public override InstanceInitializer InjectDefaultConstructor(TypeNode typeNode) { if (this.DontInjectDefaultConstructors || typeNode.IsNormalized) return null; Class Class = typeNode as Class; if (Class != null && Class.Name != null && !(Class is ClassParameter) && ClassHasNoExplicitConstructors(typeNode)) { if (Class.IsAbstractSealedContainerForStatics) return null; if (Class.PartiallyDefines != null){ this.InjectDefaultConstructor(Class.PartiallyDefines); InstanceInitializer defCons = Class.PartiallyDefines.GetConstructor(); if (defCons != null && !defCons.HasCompilerGeneratedSignature) defCons = null; //Not an orphan if (defCons != null){ //This is an injected default constructor that is an orphan, adopt it defCons.HasCompilerGeneratedSignature = false; //abuse this flag to stop other partial types from adopting it Class.Members.Add(defCons); Class.BaseClass = ((Class)Class.PartiallyDefines).BaseClass; } return defCons; //Ok if defCons null, this type should not show up in inheritance chains }else{ //Inject a default constructor This thisParameter = new This(Class); Class baseClass = Class.BaseClass; StatementList statements = new StatementList(2); statements.Add(new FieldInitializerBlock(typeNode, false)); if (baseClass != null) { MethodCall mcall = new MethodCall(new QualifiedIdentifier(new Base(), StandardIds.Ctor, typeNode.Name.SourceContext), null); mcall.SourceContext = typeNode.Name.SourceContext; ExpressionStatement callSupCons = new ExpressionStatement(mcall); callSupCons.SourceContext = typeNode.Name.SourceContext; statements.Add(callSupCons); } InstanceInitializer defCons = new InstanceInitializer(typeNode, null, null, new Block(statements)); defCons.Name = new Identifier(".ctor", typeNode.Name.SourceContext); defCons.SourceContext = typeNode.Name.SourceContext; defCons.ThisParameter = thisParameter; if (typeNode.IsAbstract) defCons.Flags |= MethodFlags.Family|MethodFlags.HideBySig; else defCons.Flags |= MethodFlags.Public|MethodFlags.HideBySig; defCons.CallingConvention = CallingConventionFlags.HasThis; defCons.IsCompilerGenerated = true; typeNode.Members.Add(defCons); return defCons; } } return null; }
/// <summary> /// Tries to reuse or create the attribute /// </summary> private static InstanceInitializer GetRuntimeContractsAttributeCtor(AssemblyNode assembly) { EnumNode runtimeContractsFlags = assembly.GetType(ContractNodes.ContractNamespace, Identifier.For("RuntimeContractsFlags")) as EnumNode; Class RuntimeContractsAttributeClass = assembly.GetType(ContractNodes.ContractNamespace, Identifier.For("RuntimeContractsAttribute")) as Class; if (runtimeContractsFlags == null) { #region Add [Flags] Member flagsConstructor = RewriteHelper.flagsAttributeNode.GetConstructor(); AttributeNode flagsAttribute = new AttributeNode(new MemberBinding(null, flagsConstructor), null, AttributeTargets.Class); #endregion Add [Flags] runtimeContractsFlags = new EnumNode(assembly, null, /* declaringType */ new AttributeList(2), TypeFlags.Sealed, ContractNodes.ContractNamespace, Identifier.For("RuntimeContractsFlags"), new InterfaceList(), new MemberList()); runtimeContractsFlags.Attributes.Add(flagsAttribute); RewriteHelper.TryAddCompilerGeneratedAttribute(runtimeContractsFlags); runtimeContractsFlags.UnderlyingType = SystemTypes.Int32; Type copyFrom = typeof(RuntimeContractEmitFlags); foreach (System.Reflection.FieldInfo fi in copyFrom.GetFields()) { if (fi.IsLiteral) { AddEnumValue(runtimeContractsFlags, fi.Name, fi.GetRawConstantValue()); } } assembly.Types.Add(runtimeContractsFlags); } InstanceInitializer ctor = (RuntimeContractsAttributeClass == null) ? null : RuntimeContractsAttributeClass.GetConstructor(runtimeContractsFlags); if (RuntimeContractsAttributeClass == null) { RuntimeContractsAttributeClass = new Class(assembly, null, /* declaringType */ new AttributeList(), TypeFlags.Sealed, ContractNodes.ContractNamespace, Identifier.For("RuntimeContractsAttribute"), SystemTypes.Attribute, new InterfaceList(), new MemberList(0)); RewriteHelper.TryAddCompilerGeneratedAttribute(RuntimeContractsAttributeClass); assembly.Types.Add(RuntimeContractsAttributeClass); } if (ctor == null) { Block returnBlock = new Block(new StatementList(new Return())); Block body = new Block(new StatementList()); Block b = new Block(new StatementList()); ParameterList pl = new ParameterList(); Parameter levelParameter = new Parameter(Identifier.For("contractFlags"), runtimeContractsFlags); pl.Add(levelParameter); ctor = new InstanceInitializer(RuntimeContractsAttributeClass, null, pl, body); ctor.Flags = MethodFlags.Assembly | MethodFlags.HideBySig | MethodFlags.SpecialName | MethodFlags.RTSpecialName; Method baseCtor = SystemTypes.Attribute.GetConstructor(); b.Statements.Add(new ExpressionStatement(new MethodCall(new MemberBinding(null, baseCtor), new ExpressionList(ctor.ThisParameter)))); b.Statements.Add(returnBlock); body.Statements.Add(b); RuntimeContractsAttributeClass.Members.Add(ctor); } return ctor; }
public virtual InstanceInitializer VisitInstanceInitializer(InstanceInitializer cons) { return (InstanceInitializer)this.VisitMethod(cons); }
/// <summary> /// There are 2 cases: /// 1) Task has no return value. In this case, we emit /// void CheckMethod(Task t) { /// var ae = t.Exception as AggregateException; /// if (ae != null) { ae.Handle(this.CheckException); throw ae; } /// } /// bool CheckException(Exception e) { /// .. check exceptional post /// } /// 2) Task(T) returns a T value /// T CheckMethod(Task t) { /// try { /// var r = t.Result; /// .. check ensures on r .. /// return r; /// } /// catch (AggregateException ae) { /// ae.Handle(this.CheckException); /// throw; /// } /// } /// bool CheckException(Exception e) { /// .. check exceptional post /// } /// </summary> public EmitAsyncClosure(Method from, Rewriter parent) { this.fromMethod = from; this.parent = parent; this.checkMethodId = Identifier.For("CheckPost"); this.checkExceptionMethodId = Identifier.For("CheckException"); this.declaringType = from.DeclaringType; var closureName = HelperMethods.NextUnusedMemberName(declaringType, "<" + from.Name.Name + ">AsyncContractClosure"); this.closureClass = new Class(declaringType.DeclaringModule, declaringType, null, TypeFlags.NestedPrivate, null, Identifier.For(closureName), SystemTypes.Object, null, null); declaringType.Members.Add(this.closureClass); RewriteHelper.TryAddCompilerGeneratedAttribute(this.closureClass); this.dup = new Duplicator(this.declaringType.DeclaringModule, this.declaringType); var taskType = from.ReturnType; var taskArgs = taskType.TemplateArguments == null ? 0 : taskType.TemplateArguments.Count; this.AggregateExceptionType = new Cache<TypeNode>(() => HelperMethods.FindType(parent.assemblyBeingRewritten, StandardIds.System, Identifier.For("AggregateException"))); this.Func2Type = new Cache<TypeNode>(() => HelperMethods.FindType(SystemTypes.SystemAssembly, StandardIds.System, Identifier.For("Func`2"))); if (from.IsGeneric) { this.closureClass.TemplateParameters = new TypeNodeList(); var parentCount = this.declaringType.ConsolidatedTemplateParameters == null ? 0 : this.declaringType.ConsolidatedTemplateParameters.Count; for (int i = 0; i < from.TemplateParameters.Count; i++) { var tp = HelperMethods.NewEqualTypeParameter(dup, (ITypeParameter)from.TemplateParameters[i], this.closureClass, parentCount + i); this.closureClass.TemplateParameters.Add(tp); } this.closureClass.IsGeneric = true; this.closureClass.EnsureMangledName(); this.forwarder = new Specializer(this.declaringType.DeclaringModule, from.TemplateParameters, this.closureClass.TemplateParameters); this.forwarder.VisitTypeParameterList(this.closureClass.TemplateParameters); taskType = this.forwarder.VisitTypeReference(taskType); } else { this.closureClassInstance = this.closureClass; } var taskTemplate = HelperMethods.Unspecialize(taskType); var continueWithCandidates = taskTemplate.GetMembersNamed(Identifier.For("ContinueWith")); Method continueWithMethod = null; for (int i = 0; i < continueWithCandidates.Count; i++) { var cand = continueWithCandidates[i] as Method; if (cand == null) continue; if (taskArgs == 0) { if (cand.IsGeneric) continue; if (cand.ParameterCount != 1) continue; var p = cand.Parameters[0]; var ptype = p.Type; var ptypeTemplate = ptype; while (ptypeTemplate.Template != null) { ptypeTemplate = ptypeTemplate.Template; } if (ptypeTemplate.Name.Name != "Action`1") continue; continueWithMethod = cand; break; } else { if (!cand.IsGeneric) continue; if (cand.TemplateParameters.Count != 1) continue; if (cand.ParameterCount != 1) continue; var p = cand.Parameters[0]; var ptype = p.Type; var ptypeTemplate = ptype; while (ptypeTemplate.Template != null) { ptypeTemplate = ptypeTemplate.Template; } if (ptypeTemplate.Name.Name != "Func`2") continue; // now create instance, first of task var taskInstance = taskTemplate.GetTemplateInstance(this.closureClass.DeclaringModule, taskType.TemplateArguments[0]); var candMethod = taskInstance.GetMembersNamed(Identifier.For("ContinueWith"))[i] as Method; continueWithMethod = candMethod.GetTemplateInstance(null, taskType.TemplateArguments[0]); break; } } if (continueWithMethod != null) { this.continuewithMethod = continueWithMethod; EmitCheckMethod(taskType, taskArgs == 1); var ctor = new InstanceInitializer(this.closureClass, null, null, null); this.constructor = ctor; ctor.CallingConvention = CallingConventionFlags.HasThis; ctor.Flags |= MethodFlags.Public | MethodFlags.HideBySig; ctor.Body = new Block(new StatementList( new ExpressionStatement(new MethodCall(new MemberBinding(ctor.ThisParameter, SystemTypes.Object.GetConstructor()), new ExpressionList())), new Return() )); this.closureClass.Members.Add(ctor); } // now that we added the ctor and the check method, let's instantiate the closure class if necessary if (this.closureClassInstance == null) { var consArgs = new TypeNodeList(); var args = new TypeNodeList(); var parentCount = this.closureClass.DeclaringType.ConsolidatedTemplateParameters == null ? 0 : this.closureClass.DeclaringType.ConsolidatedTemplateParameters.Count; for (int i = 0; i < parentCount; i++) { consArgs.Add(this.closureClass.DeclaringType.ConsolidatedTemplateParameters[i]); } var methodCount = from.TemplateParameters == null ? 0: from.TemplateParameters.Count; for (int i = 0; i < methodCount; i++) { consArgs.Add(from.TemplateParameters[i]); args.Add(from.TemplateParameters[i]); } this.closureClassInstance = (Class)this.closureClass.GetConsolidatedTemplateInstance(this.parent.assemblyBeingRewritten, closureClass.DeclaringType, closureClass.DeclaringType, args, consArgs); } // create closure initializer for context method this.ClosureLocal = new Local(this.ClosureClass); this.ClosureInitializer = new Block(new StatementList()); this.ClosureInitializer.Statements.Add(new AssignmentStatement(this.ClosureLocal, new Construct(new MemberBinding(null, this.Ctor), new ExpressionList()))); }
private void EmitCheckMethod(TypeNode taskType, bool hasResult) { var funcType = this.continuewithMethod.Parameters[0].Type; this.funcCtor = funcType.GetConstructor(SystemTypes.Object, SystemTypes.IntPtr); var taskParameter = new Parameter(Identifier.For("task"), taskType); this.originalResultLocal = new Local(taskParameter.Type); if (hasResult) { this.checkMethod = new Method(this.closureClass, null, this.checkMethodId, new ParameterList(taskParameter), taskType.TemplateArguments[0], null); checkMethod.CallingConvention = CallingConventionFlags.HasThis; checkMethod.Flags |= MethodFlags.Public; this.checkBody = new StatementList(); var tmpresult = new Local(checkMethod.ReturnType); this.newResultLocal = tmpresult; checkBody.Add(new AssignmentStatement(this.originalResultLocal, taskParameter)); checkBody.Add(new AssignmentStatement(tmpresult, new MethodCall(new MemberBinding(checkMethod.Parameters[0], checkMethod.Parameters[0].Type.GetMethod(Identifier.For("get_Result"))), new ExpressionList()))); } else { this.checkMethod = new Method(this.closureClass, null, this.checkMethodId, new ParameterList(taskParameter), SystemTypes.Void, null); checkMethod.CallingConvention = CallingConventionFlags.HasThis; checkMethod.Flags |= MethodFlags.Public; this.checkBody = new StatementList(); var aggregateType = AggregateExceptionType.Value; this.newResultLocal = new Local(aggregateType); checkBody.Add(new AssignmentStatement(this.originalResultLocal, taskParameter)); checkBody.Add(new AssignmentStatement(this.newResultLocal, new BinaryExpression(new MethodCall(new MemberBinding(checkMethod.Parameters[0], checkMethod.Parameters[0].Type.GetMethod(Identifier.For("get_Exception"))), new ExpressionList()), new MemberBinding(null, aggregateType), NodeType.Isinst))); } this.closureClass.Members.Add(this.checkMethod); }
public override InstanceInitializer VisitInstanceInitializer(InstanceInitializer cons) { WriteStart("{0}", GetMethodQualifiers(cons)); this.VisitIdentifier(cons.DeclaringType.Name); Write("("); In(); cons.Parameters = this.VisitParameterList(cons.Parameters); Out(); Write(")"); // ISSUE: Is the constructor initializer always statement 1, following the field initializer? // Handle the constructor initializer if (cons.Body.Statements.Count >= 2) { for (int n = 0; n < 2; n++) { if (cons.Body.Statements[n] is ExpressionStatement) { ExpressionStatement es = (ExpressionStatement)cons.Body.Statements[n]; if (es.Expression is MethodCall) { MethodCall mc = (MethodCall)es.Expression; if (mc.Callee is QualifiedIdentifier) { QualifiedIdentifier qi = (QualifiedIdentifier)mc.Callee; if (qi.Identifier.Name == ".ctor") { // Bingo - this is the constructor initializer if (mc.Operands != null || !(qi.Qualifier is Base)) { // We have a non-default initializer, so we must emit it Write(" : "); this.VisitExpression(qi.Qualifier); Write("("); this.VisitExpressionList(mc.Operands); Write(")"); } break; } } } } } } WriteFinish(string.Empty); this.VisitBlock(cons.Body); //this.VisitTypeReferenceList(method.ImplementedTypes); //this.VisitExpressionList(method.Requires); //this.VisitExpressionList(method.Ensures); return cons; }
private Class MakeContractException() { Class contractExceptionType; #region If we're rewriting an assembly for v4 or above and it *isn't* Silverlight (so serialization support is needed), then use new embedded dll as the type if (4 <= TargetPlatform.MajorVersion) { var iSafeSerializationData = SystemTypes.SystemAssembly.GetType(Identifier.For("System.Runtime.Serialization"), Identifier.For("ISafeSerializationData")) as Interface; if (iSafeSerializationData != null) { // Just much easier to write the C# and have the compiler generate everything than to try and create it all manually System.Reflection.Assembly embeddedAssembly; Stream embeddedAssemblyStream; embeddedAssembly = System.Reflection.Assembly.GetExecutingAssembly(); embeddedAssemblyStream = embeddedAssembly.GetManifestResourceStream("Microsoft.Contracts.Foxtrot.InternalException.dll"); byte[] data = new byte[0]; using (var br = new BinaryReader(embeddedAssemblyStream)) { var len = embeddedAssemblyStream.Length; if (len < Int32.MaxValue) data = br.ReadBytes((int)len); AssemblyNode assemblyNode = AssemblyNode.GetAssembly(data, TargetPlatform.StaticAssemblyCache, true, false, true); contractExceptionType = assemblyNode.GetType(Identifier.For(""), Identifier.For("ContractException")) as Class; } if (contractExceptionType == null) throw new RewriteException("Tried to create the ContractException type from the embedded dll, but failed"); var d = new Duplicator(this.targetAssembly, this.RuntimeContractType); d.FindTypesToBeDuplicated(new TypeNodeList(contractExceptionType)); var ct = d.Visit(contractExceptionType); contractExceptionType = (Class)ct; contractExceptionType.Flags |= TypeFlags.NestedPrivate; this.RuntimeContractType.Members.Add(contractExceptionType); return contractExceptionType; } } #endregion contractExceptionType = new Class(this.targetAssembly, this.RuntimeContractType, new AttributeList(), TypeFlags.Class | TypeFlags.NestedPrivate | TypeFlags.Serializable, null, Identifier.For("ContractException"), SystemTypes.Exception, null, null); RewriteHelper.TryAddCompilerGeneratedAttribute(contractExceptionType); var kindField = new Field(contractExceptionType, null, FieldFlags.Private, Identifier.For("_Kind"), contractNodes.ContractFailureKind, null); var userField = new Field(contractExceptionType, null, FieldFlags.Private, Identifier.For("_UserMessage"), SystemTypes.String, null); var condField = new Field(contractExceptionType, null, FieldFlags.Private, Identifier.For("_Condition"), SystemTypes.String, null); contractExceptionType.Members.Add(kindField); contractExceptionType.Members.Add(userField); contractExceptionType.Members.Add(condField); #region Constructor for setting the fields var parameters = new ParameterList(); var kindParam = new Parameter(Identifier.For("kind"), this.contractNodes.ContractFailureKind); var failureParam = new Parameter(Identifier.For("failure"), SystemTypes.String); var usermsgParam = new Parameter(Identifier.For("usermsg"), SystemTypes.String); var conditionParam = new Parameter(Identifier.For("condition"), SystemTypes.String); var innerParam = new Parameter(Identifier.For("inner"), SystemTypes.Exception); parameters.Add(kindParam); parameters.Add(failureParam); parameters.Add(usermsgParam); parameters.Add(conditionParam); parameters.Add(innerParam); var body = new Block(new StatementList()); var ctor = new InstanceInitializer(contractExceptionType, null, parameters, body); ctor.Flags |= MethodFlags.Public | MethodFlags.HideBySig; ctor.CallingConvention = CallingConventionFlags.HasThis; body.Statements.Add(new ExpressionStatement(new MethodCall(new MemberBinding(ctor.ThisParameter, contractExceptionType.BaseClass.GetConstructor(SystemTypes.String, SystemTypes.Exception)), new ExpressionList(failureParam, innerParam)))); body.Statements.Add(new AssignmentStatement(new MemberBinding(ctor.ThisParameter, kindField), kindParam)); body.Statements.Add(new AssignmentStatement(new MemberBinding(ctor.ThisParameter, userField), usermsgParam)); body.Statements.Add(new AssignmentStatement(new MemberBinding(ctor.ThisParameter, condField), conditionParam)); body.Statements.Add(new Return()); contractExceptionType.Members.Add(ctor); #endregion if (SystemTypes.SerializationInfo != null && SystemTypes.SerializationInfo.BaseClass != null) { // Silverlight (e.g.) is a platform that doesn't support serialization. So check to make sure the type really exists. // var baseCtor = SystemTypes.Exception.GetConstructor(SystemTypes.SerializationInfo, SystemTypes.StreamingContext); if (baseCtor != null) { #region Deserialization Constructor parameters = new ParameterList(); var info = new Parameter(Identifier.For("info"), SystemTypes.SerializationInfo); var context = new Parameter(Identifier.For("context"), SystemTypes.StreamingContext); parameters.Add(info); parameters.Add(context); body = new Block(new StatementList()); ctor = new InstanceInitializer(contractExceptionType, null, parameters, body); ctor.Flags |= MethodFlags.Private | MethodFlags.HideBySig; ctor.CallingConvention = CallingConventionFlags.HasThis; // : base(info, context) body.Statements.Add(new ExpressionStatement(new MethodCall(new MemberBinding(ctor.ThisParameter, baseCtor), new ExpressionList(info, context)))); // _Kind = (ContractFailureKind)info.GetInt32("Kind"); var getInt32 = SystemTypes.SerializationInfo.GetMethod(Identifier.For("GetInt32"), SystemTypes.String); body.Statements.Add(new AssignmentStatement( new MemberBinding(new This(), kindField), new MethodCall(new MemberBinding(info, getInt32), new ExpressionList(new Literal("Kind", SystemTypes.String))) )); // _UserMessage = info.GetString("UserMessage"); var getString = SystemTypes.SerializationInfo.GetMethod(Identifier.For("GetString"), SystemTypes.String); body.Statements.Add(new AssignmentStatement( new MemberBinding(new This(), userField), new MethodCall(new MemberBinding(info, getString), new ExpressionList(new Literal("UserMessage", SystemTypes.String))) )); // _Condition = info.GetString("Condition"); body.Statements.Add(new AssignmentStatement( new MemberBinding(new This(), condField), new MethodCall(new MemberBinding(info, getString), new ExpressionList(new Literal("Condition", SystemTypes.String))) )); body.Statements.Add(new Return()); contractExceptionType.Members.Add(ctor); #endregion #region GetObjectData var securityCriticalCtor = SystemTypes.SecurityCriticalAttribute.GetConstructor(); var securityCriticalAttribute = new AttributeNode(new MemberBinding(null, securityCriticalCtor), null, System.AttributeTargets.Method); var attrs = new AttributeList(securityCriticalAttribute); parameters = new ParameterList(); info = new Parameter(Identifier.For("info"), SystemTypes.SerializationInfo); context = new Parameter(Identifier.For("context"), SystemTypes.StreamingContext); parameters.Add(info); parameters.Add(context); body = new Block(new StatementList()); var getObjectDataName = Identifier.For("GetObjectData"); var getObjectData = new Method(contractExceptionType, attrs, getObjectDataName, parameters, SystemTypes.Void, body); getObjectData.CallingConvention = CallingConventionFlags.HasThis; // public override getObjectData.Flags = MethodFlags.Public | MethodFlags.Virtual; // base.GetObjectData(info, context); var baseGetObjectData = SystemTypes.Exception.GetMethod(getObjectDataName, SystemTypes.SerializationInfo, SystemTypes.StreamingContext); body.Statements.Add(new ExpressionStatement( new MethodCall(new MemberBinding(new This(), baseGetObjectData), new ExpressionList(info, context), NodeType.Call, SystemTypes.Void) )); // info.AddValue("Kind", _Kind); var addValueObject = SystemTypes.SerializationInfo.GetMethod(Identifier.For("AddValue"), SystemTypes.String, SystemTypes.Object); body.Statements.Add(new ExpressionStatement( new MethodCall(new MemberBinding(info, addValueObject), new ExpressionList(new Literal("Kind", SystemTypes.String), new BinaryExpression(new MemberBinding(new This(), kindField), new Literal(contractNodes.ContractFailureKind), NodeType.Box)), NodeType.Call, SystemTypes.Void) )); // info.AddValue("UserMessage", _UserMessage); body.Statements.Add(new ExpressionStatement( new MethodCall(new MemberBinding(info, addValueObject), new ExpressionList(new Literal("UserMessage", SystemTypes.String), new MemberBinding(new This(), userField)), NodeType.Call, SystemTypes.Void) )); // info.AddValue("Condition", _Condition); body.Statements.Add(new ExpressionStatement( new MethodCall(new MemberBinding(info, addValueObject), new ExpressionList(new Literal("Condition", SystemTypes.String), new MemberBinding(new This(), condField)), NodeType.Call, SystemTypes.Void) )); body.Statements.Add(new Return()); contractExceptionType.Members.Add(getObjectData); #endregion } } this.RuntimeContractType.Members.Add(contractExceptionType); return contractExceptionType; }
internal static void Initialize(){ RuntimeAssembly = Runtime.GetRuntimeAssembly(); PostCompilationPluginAttributeType = RuntimeAssembly.GetType(Identifier.For("Microsoft.SpecSharp"), Identifier.For("PostCompilationPluginAttribute")); ObjectConstructor = SystemTypes.Object.GetConstructor(); IListAdd = SystemTypes.IList.GetMethod(StandardIds.Add, SystemTypes.Object); #if CCINamespace const string ContractsNs = "Microsoft.Contracts"; #else const string ContractsNs = "Microsoft.Contracts"; #endif MustOverrideAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "MustOverrideAttribute"); }
public override InstanceInitializer VisitInstanceInitializer(InstanceInitializer cons) { hasCall = true; return cons; }
private static void WriteConstructor(InstanceInitializer constructor, TextWriter writer) { WriteType(constructor.DeclaringType, writer); writer.Write(".#ctor"); WriteParameters(constructor.Parameters, writer); }
private void ParseConstructor(TypeNode parentType, AttributeList attributes, TokenList modifierTokens, SourceContextList modifierContexts, object sctx, SourceContext idCtx, TokenSet followers){ InstanceInitializer c = new InstanceInitializer(parentType, attributes, null, null, this.TypeExpressionFor(Token.Void)); this.currentCtor = c; c.Name = new Identifier(".ctor", idCtx); MethodFlags flags = this.GetMethodFlags(modifierTokens, modifierContexts, parentType, c); if ((flags & MethodFlags.Static) != 0){ this.currentCtor = null; // Can you call "base" in a static ctor? this.ParseStaticConstructor(parentType, attributes, modifierTokens, modifierContexts, flags, sctx, idCtx, followers); return; } parentType.Members.Add(c); c.Flags |= flags|MethodFlags.HideBySig; c.Parameters = this.ParseParameters(Token.RightParenthesis, followers|Token.LeftBrace|Token.Semicolon|Token.Colon|Parser.ContractStart|Token.Where); c.HasCompilerGeneratedSignature = false; c.Documentation = this.LastDocComment; QualifiedIdentifier supCons = new QualifiedIdentifier(new Base(), StandardIds.Ctor, this.scanner.CurrentSourceContext); MethodCall superConstructorCall = new MethodCall(supCons, null, NodeType.Call); superConstructorCall.SourceContext = this.scanner.CurrentSourceContext; StatementList slist = new StatementList(); Block body = new Block(slist, this.insideCheckedBlock, this.insideUncheckedBlock, this.inUnsafeCode); body.SourceContext = this.scanner.CurrentSourceContext; Block iblock = new Block(new StatementList(), this.insideCheckedBlock, this.insideUncheckedBlock, this.inUnsafeCode); if (this.currentToken == Token.Colon){ this.GetNextToken(); bool savedParsingStatement = this.parsingStatement; this.parsingStatement = true; superConstructorCall.SourceContext = this.scanner.CurrentSourceContext; supCons.SourceContext = this.scanner.CurrentSourceContext; bool init = false; this.inInstanceConstructor = BaseOrThisCallKind.ColonThisOrBaseSeen; if (this.currentToken == Token.This){ if (this.sink != null) this.sink.StartName(new Identifier(".ctor", this.scanner.CurrentSourceContext)); supCons.Qualifier = new This(this.scanner.CurrentSourceContext, true); this.GetNextToken(); }else if (this.currentToken == Token.Base){ if (parentType.IsValueType) this.HandleError(Error.StructWithBaseConstructorCall, new ErrorHandler(this.errors).GetMemberSignature(c)); else if (this.sink != null) this.sink.StartName(new Identifier(".ctor", this.scanner.CurrentSourceContext)); supCons.Qualifier = new Base(this.scanner.CurrentSourceContext, true); this.GetNextToken(); }else{ if (!init) this.SkipTo(followers|Token.LeftBrace|Token.Semicolon|Parser.ContractStart|Token.Where, Error.ThisOrBaseExpected); if (this.currentToken != Token.EndOfFile) this.parsingStatement = savedParsingStatement; goto parseBody; } SourceContext lpCtx = this.scanner.CurrentSourceContext; this.Skip(Token.LeftParenthesis); superConstructorCall.Operands = this.ParseArgumentList(followers|Token.LeftBrace|Token.Semicolon|Parser.ContractStart|Token.Where, lpCtx, out superConstructorCall.SourceContext.EndPos); if (this.currentToken != Token.EndOfFile) this.parsingStatement = savedParsingStatement; } else { // no colon ==> no "base" or "this" before body of ctor if (! parentType.IsValueType) this.inInstanceConstructor = BaseOrThisCallKind.None; } parseBody: superConstructorCall.SourceContext.EndPos = this.scanner.endPos; supCons.SourceContext.EndPos = this.scanner.endPos; bool swallowedSemicolonAlready = false; this.ParseMethodContract(c, followers|Token.LeftBrace|Token.Semicolon, ref swallowedSemicolonAlready); Block b; if (this.parsingContractAssembly) b = this.ParseBody(c, sctx, followers, swallowedSemicolonAlready); // only allow semicolon body in contract assemblies else b = this.ParseBody(c, sctx, followers); slist.Add(iblock); c.IsDeferringConstructor = supCons.Qualifier is This || this.inInstanceConstructor == BaseOrThisCallKind.InCtorBodyThisSeen; if (!c.IsDeferringConstructor){ slist.Add(new FieldInitializerBlock(parentType,false)); } Block baseOrDeferringCallBlock = new Block(new StatementList(1)); c.BaseOrDefferingCallBlock = baseOrDeferringCallBlock; slist.Add(baseOrDeferringCallBlock); if (this.inInstanceConstructor == BaseOrThisCallKind.None || this.inInstanceConstructor == BaseOrThisCallKind.ColonThisOrBaseSeen){ if (!(parentType.IsValueType || this.TypeIsSystemObject(parentType)) || supCons.Qualifier is This) baseOrDeferringCallBlock.Statements.Add(new ExpressionStatement(superConstructorCall, superConstructorCall.SourceContext)); } if (b != null){ slist.Add(b); body.SourceContext.EndPos = b.SourceContext.EndPos; if ((c.Flags & MethodFlags.PInvokeImpl) != 0 && b.Statements != null && b.Statements.Count > 0) body = null; else if (this.omitBodies) b.Statements = null; }else if ((c.Flags & MethodFlags.PInvokeImpl) != 0) body = null; c.Body = body; this.inInstanceConstructor = BaseOrThisCallKind.Disallowed; this.currentCtor = null; }
private System.Attribute ConstructAttribute(InstanceInitializer/*!*/ constr, object[] argumentValues) { //This could execute partially trusted code, so set up a very restrictive execution environment //TODO: skip this if the attribute is from a trusted assembly System.Reflection.ConstructorInfo consInfo = constr.GetConstructorInfo(); if(consInfo == null) return null; //Because we invoke the constructor through reflection, a stack walk is performed. The following two commented-out statements //would cause the stack walk to fail. //For VS2003 and earlier, we will run the constructor in full trust. //For VS2005 and later, we will construct a DynamicMethod, wrap it in a delegate, and invoke that. //System.Security.PermissionSet perm = new System.Security.PermissionSet(System.Security.Permissions.PermissionState.None); //perm.PermitOnly(); try { return consInfo.Invoke(argumentValues) as System.Attribute; } catch { } return null; }
public virtual void ProvideMembers() { if(this.membersAlreadyProvided) return; this.membersAlreadyProvided = true; this.memberCount = 0; MemberList members = this.members = new MemberList(); //ctor ParameterList parameters = new ParameterList(); parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.Object, CoreSystemTypes.Object, null, null)); parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.Method, CoreSystemTypes.IntPtr, null, null)); InstanceInitializer ctor = new InstanceInitializer(this, null, parameters, null); ctor.Flags |= MethodFlags.Public | MethodFlags.HideBySig; ctor.CallingConvention = CallingConventionFlags.HasThis; ctor.ImplFlags = MethodImplFlags.Runtime; members.Add(ctor); //Invoke Method invoke = new Method(this, null, StandardIds.Invoke, this.Parameters, this.ReturnType, null); invoke.Flags = MethodFlags.Public | MethodFlags.HideBySig | MethodFlags.Virtual; invoke.CallingConvention = CallingConventionFlags.HasThis; invoke.ImplFlags = MethodImplFlags.Runtime; members.Add(invoke); //BeginInvoke ParameterList dparams = this.parameters; int n = dparams == null ? 0 : dparams.Count; parameters = new ParameterList(); for(int i = 0; i < n; i++) { //^ assert dparams != null; Parameter p = dparams[i]; if(p == null) continue; parameters.Add((Parameter)p.Clone()); } parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.callback, SystemTypes.AsyncCallback, null, null)); parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.Object, CoreSystemTypes.Object, null, null)); Method beginInvoke = new Method(this, null, StandardIds.BeginInvoke, parameters, SystemTypes.IASyncResult, null); beginInvoke.Flags = MethodFlags.Public | MethodFlags.HideBySig | MethodFlags.NewSlot | MethodFlags.Virtual; beginInvoke.CallingConvention = CallingConventionFlags.HasThis; beginInvoke.ImplFlags = MethodImplFlags.Runtime; members.Add(beginInvoke); //EndInvoke parameters = new ParameterList(); for(int i = 0; i < n; i++) { Parameter p = dparams[i]; if(p == null || p.Type == null || !(p.Type is Reference)) continue; parameters.Add((Parameter)p.Clone()); } parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.result, SystemTypes.IASyncResult, null, null)); Method endInvoke = new Method(this, null, StandardIds.EndInvoke, parameters, this.ReturnType, null); endInvoke.Flags = MethodFlags.Public | MethodFlags.HideBySig | MethodFlags.NewSlot | MethodFlags.Virtual; endInvoke.CallingConvention = CallingConventionFlags.HasThis; endInvoke.ImplFlags = MethodImplFlags.Runtime; members.Add(endInvoke); if(!this.IsGeneric) { TypeNodeList templPars = this.TemplateParameters; for(int i = 0, m = templPars == null ? 0 : templPars.Count; i < m; i++) { //^ assert templPars != null; TypeNode tpar = templPars[i]; if(tpar == null) continue; members.Add(tpar); } } }
private static InstanceInitializer CreateConstructor(Class closureClass) { var ctor = new InstanceInitializer(closureClass, null, null, null); ctor.CallingConvention = CallingConventionFlags.HasThis; ctor.Flags |= MethodFlags.Public | MethodFlags.HideBySig; // Regular block that calls base class constructor ctor.Body = new Block( new StatementList( new ExpressionStatement( new MethodCall(new MemberBinding(ctor.ThisParameter, SystemTypes.Object.GetConstructor()), new ExpressionList())), new Return())); return ctor; }
internal Class CreateSerializerFor(TypeNode type) { // todo: look in the genCache for other serializer assemblies that may have already // created the serializer for this type and make an assembly reference to that // serializer instead of creating a complete duplicate. TypeNode saved = tempChecker.currentType; Class c = (Class)serializers[type]; if (c != null) return c; c = new Class(); c.Flags = TypeFlags.Class | TypeFlags.BeforeFieldInit; // copy the accessibility of the type we are serializing. c.Flags |= (type.Flags & (TypeFlags.Public | TypeFlags.NestedAssembly)); c.Name = Identifier.For(GetSerializerName(type)); c.Namespace = Identifier.For(GetSerializerNamespace(type)); c.DeclaringModule = this.module; c.Members = new MemberList(); c.Attributes = new AttributeList(); c.BaseClass = Runtime.XmlSerializer; tempChecker.currentType = c; InstanceInitializer ii = Runtime.XmlSerializerAttribute.GetConstructor(); MemberBinding mb = new MemberBinding(null, ii); mb.Type = Runtime.XmlSerializerAttribute; c.Attributes.Add(new AttributeNode(mb, null)); if (cunit != null) { cunit.Namespaces[0].Types.Add(c); } this.module.Types.Add(c); Identifier typeId = Identifier.For("type"); // what we are writing to. Identifier rootName = Identifier.For("rootName"); // what we are writing to. Identifier rootNamespace = Identifier.For("rootNamespace"); // what we are writing to. // Constructor Method constructor = new InstanceInitializer(); constructor.Name = StandardIds.Ctor; constructor.DeclaringType = c; constructor.Flags = MethodFlags.Public|MethodFlags.HideBySig|MethodFlags.SpecialName|MethodFlags.RTSpecialName; constructor.Parameters = new ParameterList(); constructor.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, typeId, SystemTypes.Type, null, null)); constructor.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, rootName, SystemTypes.String, null, null)); constructor.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, rootNamespace, SystemTypes.String, null, null)); constructor.ReturnType = SystemTypes.Void; c.Members.Add(constructor); // pass args thru to base XmlSerializer constructor. Block b = constructor.Body = new Block(new StatementList()); b.Statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(new Base(), StandardIds.Ctor), new ExpressionList(typeId, rootName, rootNamespace), NodeType.Call))); //AddConsoleWrite(b.Statements, new Literal("Hello!!",SystemTypes.String)); // Serialize(T source, XmlSerializationWriter writer) method Identifier src = Identifier.For("source"); // object being serialized. Identifier writer = Identifier.For("writer"); // what we are writing to. Method serialize = new Method(); serialize.Name = Identifier.For("Serialize"); serialize.DeclaringType = c; serialize.Flags = MethodFlags.Public|MethodFlags.Static|MethodFlags.HideBySig; serialize.Parameters = new ParameterList(); serialize.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, src, type, null, null)); serialize.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, writer, Runtime.XmlSerializationWriter, null, null)); serialize.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, rootName, SystemTypes.String, null, null)); serialize.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, rootNamespace, SystemTypes.String, null, null)); serialize.ReturnType = SystemTypes.Void; c.Members.Add(serialize); // T Deserialize(XmlReader reader, bool required, out bool result) method Identifier reader = Identifier.For("reader"); // what we are reading from. Identifier required = Identifier.For("required"); // whether an object is required or not. Identifier result = Identifier.For("result"); // whether we found anything. Method deserialize = new Method(); deserialize.Name = Identifier.For("Deserialize"); deserialize.DeclaringType = c; deserialize.Flags = MethodFlags.Public|MethodFlags.Static|MethodFlags.HideBySig; deserialize.Parameters = new ParameterList(); deserialize.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, reader, Runtime.XmlSerializationReader, null, null)); deserialize.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, required, SystemTypes.Boolean, null, null)); deserialize.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.Out, result, SystemTypes.Boolean.GetReferenceType(), null, null)); deserialize.ReturnType = type; c.Members.Add(deserialize); // It is important that we add the serializer to the cache AFTER we create the methods, but // BEFORE we create the method bodies so that we can handle recurrsive calls to AddCallSerializer which // happens in recurrsive structures like "class Foo { public Foo f; }". Otherwise we'd get stuck in an // infinite loop. serializers[type] = c; // Body of serialize method. b = serialize.Body = new Block(new StatementList()); StatementList statements = b.Statements; if (!AddWriteSimpleType(type, statements, c, writer, src, rootName, rootNamespace)) { MethodCall call = new MethodCall(); call.Callee = new QualifiedIdentifier(writer,Identifier.For("WriteStartElement")); call.Operands = new ExpressionList(); call.Operands.Add(rootName); call.Operands.Add(rootNamespace); statements.Add(new If(new BinaryExpression(rootName,Literal.Null,NodeType.Ne), new Block(new StatementList(new ExpressionStatement(call))),null)); Expression source = src; if (type.Template == SystemTypes.GenericBoxed) { statements = AddCheckForNull(statements, Duplicate(src, c), type); type = Checker.GetCollectionElementType(type); source = CastTo(src, type);//unbox it } if (type is TupleType) { AddWriteTuple(type as TupleType, statements, c, source, writer); } else if (type is TypeUnion) { AddWriteChoice(type as TypeUnion, statements, c, source, writer); } else if (IsStream(type)) { AddWriteStream(type, statements, c, source, writer); } else { SchemaElementDecl sd = SchemaElementDecl.Compile(this.module, type, Checker.GetCollectionElementType(type), this.errorHandler, schemaElementDeclCache); SchemaValidator validator = validator = sd.CreateValidator(this.errorHandler); statements = AddCheckForNull(statements, Duplicate(src, c), type); AddWriteAttributes(statements, c, writer, source, validator); AddWriteContent(type, statements, c, writer, source, validator); } call = new MethodCall(); call.Callee = new QualifiedIdentifier(writer,Identifier.For("WriteEndElement")); call.Operands = new ExpressionList(); statements.Add(new If(new BinaryExpression(rootName,Literal.Null,NodeType.Ne), new Block(new StatementList(new ExpressionStatement(call))),null)); } // body of deserialize method. b = deserialize.Body = new Block(new StatementList()); statements = b.Statements; Local target = new Local(Identifier.Empty, type); if (type.Template == SystemTypes.GenericBoxed){ type = Checker.GetCollectionElementType(type); } if (type is TupleType) { AddReadTuple(b, type as TupleType, statements, reader, target, required, result); } else if (type is TypeUnion) { AddReadChoice(b, type as TypeUnion, statements, reader, target, required, result); } else if (IsStream(type)) { AddReadStream(b, type, statements, reader, target, result); } else { if (type is TypeAlias) { type = ((TypeAlias)type).AliasedType; } // Then we are already positioned on the element to be deserialized. statements.Add(new AssignmentStatement(required, Literal.True)); if (!AddReadSimpleType(type, statements, reader, target, result, false)) { if (!type.IsValueType && !type.IsAbstract && type.GetConstructor() != null) { Construct cons = new Construct(new MemberBinding(null, type), new ExpressionList(), type); statements.Add(new AssignmentStatement(target, cons)); } SchemaElementDecl sd = SchemaElementDecl.Compile(this.module, type, Checker.GetCollectionElementType(type), this.errorHandler, schemaElementDeclCache); SchemaValidator validator = validator = sd.CreateValidator(this.errorHandler); AddReadAttributes(type, statements, reader, target, validator); AddReadContent(c, b, type, statements, reader, target, required, result, validator); } } statements.Add(new Return(target)); tempChecker.currentType = saved; return c; }
public override InstanceInitializer VisitInstanceInitializer(InstanceInitializer cons) { isMRNAO = true; return cons; }
/// <summary> /// Write out a constructor name /// </summary> /// <param name="constructor">The constructor for which to write out the name</param> /// <param name="sb">The string builder to which the name is written</param> private static void WriteConstructor(InstanceInitializer constructor, StringBuilder sb) { WriteType(constructor.DeclaringType, sb); sb.Append(".#ctor"); WriteParameters(constructor.Parameters, sb); }
public EventingVisitor(Action<InstanceInitializer> visitInstanceInitializer) { VisitedInstanceInitializer += visitInstanceInitializer; } public event Action<InstanceInitializer> VisitedInstanceInitializer; public override InstanceInitializer VisitInstanceInitializer(InstanceInitializer cons) { if (VisitedInstanceInitializer != null) VisitedInstanceInitializer(cons); return base.VisitInstanceInitializer(cons); }