public DuplicatorForContractsAndClosures(Module module, Method sourceMethod, Method targetMethod, ContractNodes contractNodes, bool mapParameters) : base(module, targetMethod.DeclaringType) { this.sourceMethod = sourceMethod; this.targetMethod = targetMethod; this.RemoveNameForLocals = true; Duplicator dup = this; if (mapParameters) { if (sourceMethod.ThisParameter != null) { if (targetMethod.ThisParameter != null) { dup.DuplicateFor[sourceMethod.ThisParameter.UniqueKey] = targetMethod.ThisParameter; } else { // target is a static wrapper. But duplicator cannot handle This -> Parameter conversion // so we handle it explicitly here in this visitor. replaceThisWithParameter = targetMethod.Parameters[0]; } } if (sourceMethod.Parameters != null && targetMethod.Parameters != null && sourceMethod.Parameters.Count == targetMethod.Parameters.Count) { for (int i = 0, n = sourceMethod.Parameters.Count; i < n; i++) { dup.DuplicateFor[sourceMethod.Parameters[i].UniqueKey] = targetMethod.Parameters[i]; } } } var originalType = HelperMethods.IsContractTypeForSomeOtherType(sourceMethod.DeclaringType, contractNodes); if (originalType != null) { var contractType = this.contractClass = sourceMethod.DeclaringType; while (contractType.Template != null) { contractType = contractType.Template; } while (originalType.Template != null) { originalType = originalType.Template; } // forward ContractType<A,B> -> originalType<A',B'> this.contractClassToForward = contractType; this.targetTypeToForwardTo = originalType; //dup.DuplicateFor[contractType.UniqueKey] = originalType; } }
public override Expression VisitParameter(Parameter parameter) { if (parameter == null) return null; var oe = new OldExpression(parameter); oe.Type = parameter.Type; return oe; }
public override void VisitParameter(Parameter parameter) { if (parameter == null) return; if (this.BoundVars.Contains(parameter) && !this.FoundVariables.Contains(parameter)) { this.FoundVariables.Add(parameter); this.FoundReferences.Add(parameter); } }
public override Expression VisitParameter(Parameter parameter) { Expression re = base.VisitParameter(parameter); TypeNode typeNode = (TypeNode)parameter.TypeExpression; parameterType.Add(typeNode); return re; }
public override Expression VisitParameter(Parameter parameter) { if (parameter == null) return null; object result = map[parameter.UniqueKey]; if (result != null) return (Expression) result; return base.VisitParameter(parameter); }
public override Expression VisitParameter(Parameter parameter) { if (parameter == null) return null; if (parameter.DeclaringMethod == abbreviation) { var argIndex = parameter.ParameterListIndex; if (argIndex >= actuals.Count) throw new InvalidOperationException("bad parameter/actual list"); return (Expression) this.Visit(actuals[argIndex]); } if (parameter.DeclaringMethod == this.targetMethod) { // important lower case. Upper case is Duplicator's target method return parameter; } return base.VisitParameter(parameter); }
private Method MakeRaiseFailureEventMethod() { Parameter kindParameter = new Parameter(Identifier.For("kind"), contractNodes.ContractFailureKind); Parameter messageParameter = new Parameter(Identifier.For("msg"), SystemTypes.String); Parameter conditionTextParameter = new Parameter(Identifier.For("conditionTxt"), SystemTypes.String); Parameter exceptionParameter = new Parameter(Identifier.For("inner"), SystemTypes.Exception); ParameterList pl = new ParameterList(kindParameter, messageParameter, conditionTextParameter, exceptionParameter); Block body = new Block(new StatementList()); Method m = new Method(this.RuntimeContractType, null, ContractNodes.RaiseContractFailedEventName, pl, SystemTypes.String, body); m.Flags = MethodFlags.Assembly | MethodFlags.Static; m.Attributes = new AttributeList(); this.RuntimeContractType.Members.Add(m); // // Generate the following // // return String.Format("{0} failed: {1}: {2}", box(kind), conditionText, message); var stringFormat3 = SystemTypes.String.GetMethod(Identifier.For("Format"), SystemTypes.String, SystemTypes.Object, SystemTypes.Object, SystemTypes.Object); body.Statements.Add(new Return(new MethodCall(new MemberBinding(null, stringFormat3), new ExpressionList(new Literal("{0} failed: {1}: {2}"), new BinaryExpression(kindParameter, new Literal(contractNodes.ContractFailureKind), NodeType.Box), conditionTextParameter, messageParameter)))); return m; }
private Method MakeRequiresWithExceptionMethod(string name) { Parameter conditionParameter = new Parameter(Identifier.For("condition"), SystemTypes.Boolean); Parameter messageParameter = new Parameter(Identifier.For("msg"), SystemTypes.String); Parameter conditionTextParameter = new Parameter(Identifier.For("conditionTxt"), SystemTypes.String); MethodClassParameter typeArg = new MethodClassParameter(); ParameterList pl = new ParameterList(conditionParameter, messageParameter, conditionTextParameter); Block body = new Block(new StatementList()); Method m = new Method(this.RuntimeContractType, null, Identifier.For(name), pl, SystemTypes.Void, body); m.Flags = MethodFlags.Assembly | MethodFlags.Static; m.Attributes = new AttributeList(); m.TemplateParameters = new TypeNodeList(typeArg); m.IsGeneric = true; this.RuntimeContractType.Members.Add(m); typeArg.Name = Identifier.For("TException"); typeArg.DeclaringMember = m; typeArg.BaseClass = SystemTypes.Exception; typeArg.ParameterListIndex = 0; typeArg.DeclaringModule = this.RuntimeContractType.DeclaringModule; Block returnBlock = new Block(new StatementList(new Return())); Block b = new Block(new StatementList()); b.Statements.Add(new Branch(conditionParameter, returnBlock)); // // Generate the following // // // message == null means: yes we handled it. Otherwise it is the localized failure message // var message = RaiseFailureEvent(ContractFailureKind.Precondition, userMessage, conditionString, null); // #if assertOnFailure // if (message != null) { // Assert(false, message); // } // #endif var messageLocal = new Local(Identifier.For("msg"), SystemTypes.String); ExpressionList elist = new ExpressionList(); elist.Add(this.PreconditionKind); elist.Add(messageParameter); elist.Add(conditionTextParameter); elist.Add(Literal.Null); b.Statements.Add(new AssignmentStatement(messageLocal, new MethodCall(new MemberBinding(null, this.RaiseFailureEventMethod), elist))); if (this.AssertOnFailure) { var assertMethod = GetSystemDiagnosticsAssertMethod(); if (assertMethod != null) { var skipAssert = new Block(); b.Statements.Add(new Branch(new UnaryExpression(messageLocal, NodeType.LogicalNot), skipAssert)); // emit assert call ExpressionList assertelist = new ExpressionList(); assertelist.Add(Literal.False); assertelist.Add(messageLocal); b.Statements.Add(new ExpressionStatement(new MethodCall(new MemberBinding(null, assertMethod), assertelist))); b.Statements.Add(skipAssert); } } // // construct exception // Exception obj = null; // ConstructorInfo ci = typeof(TException).GetConstructor(new[] { typeof(string), typeof(string) }); // if (ci != null) // { // if (reflection.firstArgName == "paramName") { // exceptionObject = ci.Invoke(new[] { userMessage, message }) as Exception; // } // else { // exceptionObject = ci.Invoke(new[] { message, userMessage }) as Exception; // } // } // else { // ci = typeof(TException).GetConstructor(new[] { typeof(string) }); // if (ci != null) // { // exceptionObject = ci.Invoke(new[] { message }) as Exception; // } // } var exceptionLocal = new Local(Identifier.For("obj"), SystemTypes.Exception); b.Statements.Add(new AssignmentStatement(exceptionLocal, Literal.Null)); var constructorInfoType = TypeNode.GetTypeNode(typeof(System.Reflection.ConstructorInfo)); Contract.Assume(constructorInfoType != null); var methodBaseType = TypeNode.GetTypeNode(typeof(System.Reflection.MethodBase)); Contract.Assume(methodBaseType != null); var constructorLocal = new Local(Identifier.For("ci"), constructorInfoType); Contract.Assume(SystemTypes.Type != null); var getConstructorMethod = SystemTypes.Type.GetMethod(Identifier.For("GetConstructor"), SystemTypes.Type.GetArrayType(1)); var typeofExceptionArg = GetTypeFromHandleExpression(typeArg); var typeofString = GetTypeFromHandleExpression(SystemTypes.String); var typeArrayLocal = new Local(Identifier.For("typeArray"), SystemTypes.Type.GetArrayType(1)); var typeArray2 = new ConstructArray(); typeArray2.ElementType = SystemTypes.Type; typeArray2.Rank = 1; typeArray2.Operands = new ExpressionList(Literal.Int32Two); var typeArrayInit2 = new Block(new StatementList()); typeArrayInit2.Statements.Add(new AssignmentStatement(typeArrayLocal, typeArray2)); typeArrayInit2.Statements.Add(new AssignmentStatement(new Indexer(typeArrayLocal, new ExpressionList(Literal.Int32Zero), SystemTypes.Type), typeofString)); typeArrayInit2.Statements.Add(new AssignmentStatement(new Indexer(typeArrayLocal, new ExpressionList(Literal.Int32One), SystemTypes.Type), typeofString)); typeArrayInit2.Statements.Add(new ExpressionStatement(typeArrayLocal)); var typeArrayExpression2 = new BlockExpression(typeArrayInit2); b.Statements.Add(new AssignmentStatement(constructorLocal, new MethodCall(new MemberBinding(typeofExceptionArg, getConstructorMethod), new ExpressionList(typeArrayExpression2)))); var elseBlock = new Block(); b.Statements.Add(new Branch(new UnaryExpression(constructorLocal, NodeType.LogicalNot), elseBlock)); var endifBlock2 = new Block(); var invokeMethod = constructorInfoType.GetMethod(Identifier.For("Invoke"), SystemTypes.Object.GetArrayType(1)); var argArray2 = new ConstructArray(); argArray2.ElementType = SystemTypes.Object; argArray2.Rank = 1; argArray2.Operands = new ExpressionList(Literal.Int32Two); var argArrayLocal = new Local(Identifier.For("argArray"), SystemTypes.Object.GetArrayType(1)); var parameterInfoType = TypeNode.GetTypeNode(typeof(System.Reflection.ParameterInfo)); Contract.Assume(parameterInfoType != null); var parametersMethod = methodBaseType.GetMethod(Identifier.For("GetParameters")); var get_NameMethod = parameterInfoType.GetMethod(Identifier.For("get_Name")); var string_op_EqualityMethod = SystemTypes.String.GetMethod(Identifier.For("op_Equality"), SystemTypes.String, SystemTypes.String); var elseArgMsgBlock = new Block(); var endIfArgMsgBlock = new Block(); b.Statements.Add(new Branch(new UnaryExpression(new MethodCall(new MemberBinding(null, string_op_EqualityMethod), new ExpressionList(new MethodCall(new MemberBinding(new Indexer(new MethodCall(new MemberBinding(constructorLocal, parametersMethod), new ExpressionList(), NodeType.Callvirt), new ExpressionList(Literal.Int32Zero), parameterInfoType), get_NameMethod), new ExpressionList(), NodeType.Callvirt), new Literal("paramName", SystemTypes.String))), NodeType.LogicalNot), elseArgMsgBlock)); var argArrayInit2 = new Block(new StatementList()); argArrayInit2.Statements.Add(new AssignmentStatement(argArrayLocal, argArray2)); argArrayInit2.Statements.Add(new AssignmentStatement(new Indexer(argArrayLocal, new ExpressionList(Literal.Int32Zero), SystemTypes.Object), messageParameter)); argArrayInit2.Statements.Add(new AssignmentStatement(new Indexer(argArrayLocal, new ExpressionList(Literal.Int32One), SystemTypes.Object), messageLocal)); argArrayInit2.Statements.Add(new ExpressionStatement(argArrayLocal)); var argArrayExpression2 = new BlockExpression(argArrayInit2); b.Statements.Add(new AssignmentStatement(exceptionLocal, new BinaryExpression(new MethodCall(new MemberBinding(constructorLocal, invokeMethod), new ExpressionList(argArrayExpression2)), new Literal(SystemTypes.Exception), NodeType.Isinst))); b.Statements.Add(new Branch(null, endIfArgMsgBlock)); b.Statements.Add(elseArgMsgBlock); var argArrayInit2_1 = new Block(new StatementList()); argArrayInit2_1.Statements.Add(new AssignmentStatement(argArrayLocal, argArray2)); argArrayInit2_1.Statements.Add(new AssignmentStatement(new Indexer(argArrayLocal, new ExpressionList(Literal.Int32Zero), SystemTypes.Object), messageLocal)); argArrayInit2_1.Statements.Add(new AssignmentStatement(new Indexer(argArrayLocal, new ExpressionList(Literal.Int32One), SystemTypes.Object), messageParameter)); argArrayInit2_1.Statements.Add(new ExpressionStatement(argArrayLocal)); var argArrayExpression2_1 = new BlockExpression(argArrayInit2_1); b.Statements.Add(new AssignmentStatement(exceptionLocal, new BinaryExpression(new MethodCall(new MemberBinding(constructorLocal, invokeMethod), new ExpressionList(argArrayExpression2_1)), new Literal(SystemTypes.Exception), NodeType.Isinst))); b.Statements.Add(endIfArgMsgBlock); b.Statements.Add(new Branch(null, endifBlock2)); b.Statements.Add(elseBlock); var typeArray1 = new ConstructArray(); typeArray1.ElementType = SystemTypes.Type; typeArray1.Rank = 1; typeArray1.Operands = new ExpressionList(Literal.Int32One); var typeArrayInit1 = new Block(new StatementList()); typeArrayInit1.Statements.Add(new AssignmentStatement(typeArrayLocal, typeArray1)); typeArrayInit1.Statements.Add(new AssignmentStatement(new Indexer(typeArrayLocal, new ExpressionList(Literal.Int32Zero), SystemTypes.Type), typeofString)); typeArrayInit1.Statements.Add(new ExpressionStatement(typeArrayLocal)); var typeArrayExpression1 = new BlockExpression(typeArrayInit1); b.Statements.Add(new AssignmentStatement(constructorLocal, new MethodCall(new MemberBinding(typeofExceptionArg, getConstructorMethod), new ExpressionList(typeArrayExpression1)))); b.Statements.Add(new Branch(new UnaryExpression(constructorLocal, NodeType.LogicalNot), endifBlock2)); var argArray1 = new ConstructArray(); argArray1.ElementType = SystemTypes.Object; argArray1.Rank = 1; argArray1.Operands = new ExpressionList(Literal.Int32One); var argArrayInit1 = new Block(new StatementList()); argArrayInit1.Statements.Add(new AssignmentStatement(argArrayLocal, argArray1)); argArrayInit1.Statements.Add(new AssignmentStatement(new Indexer(argArrayLocal, new ExpressionList(Literal.Int32Zero), SystemTypes.Object), messageLocal)); argArrayInit1.Statements.Add(new ExpressionStatement(argArrayLocal)); var argArrayExpression1 = new BlockExpression(argArrayInit1); b.Statements.Add(new AssignmentStatement(exceptionLocal, new BinaryExpression(new MethodCall(new MemberBinding(constructorLocal, invokeMethod), new ExpressionList(argArrayExpression1)), new Literal(SystemTypes.Exception), NodeType.Isinst))); b.Statements.Add(endifBlock2); // // throw it // if (exceptionObject == null) // { // throw new ArgumentException(displayMessage, message); // } // else // { // throw exceptionObject; // } var thenBlock3 = new Block(); b.Statements.Add(new Branch(exceptionLocal, thenBlock3)); b.Statements.Add(new Throw(new Construct(new MemberBinding(null, SystemTypes.ArgumentException.GetConstructor(SystemTypes.String, SystemTypes.String)), new ExpressionList(messageLocal, messageParameter)))); b.Statements.Add(thenBlock3); b.Statements.Add(new Throw(exceptionLocal)); b.Statements.Add(returnBlock); Contract.Assume(body.Statements != null); body.Statements.Add(b); Member constructor = null; AttributeNode attribute = null; #region Add [DebuggerNonUserCodeAttribute] if (this.HideFromDebugger) { TypeNode debuggerNonUserCode = SystemTypes.SystemAssembly.GetType(Identifier.For("System.Diagnostics"), Identifier.For("DebuggerNonUserCodeAttribute")); if (debuggerNonUserCode != null) { constructor = debuggerNonUserCode.GetConstructor(); attribute = new AttributeNode(new MemberBinding(null, constructor), null, AttributeTargets.Method); m.Attributes.Add(attribute); } } #endregion Add [DebuggerNonUserCodeAttribute] TypeNode reliabilityContract = SystemTypes.SystemAssembly.GetType(Identifier.For("System.Runtime.ConstrainedExecution"), Identifier.For("ReliabilityContractAttribute")); TypeNode consistency = SystemTypes.SystemAssembly.GetType(Identifier.For("System.Runtime.ConstrainedExecution"), Identifier.For("Consistency")); TypeNode cer = SystemTypes.SystemAssembly.GetType(Identifier.For("System.Runtime.ConstrainedExecution"), Identifier.For("Cer")); if (reliabilityContract != null && consistency != null && cer != null) { constructor = reliabilityContract.GetConstructor(consistency, cer); if (constructor != null) { attribute = new AttributeNode( new MemberBinding(null, constructor), new ExpressionList( new Literal(System.Runtime.ConstrainedExecution.Consistency.WillNotCorruptState, consistency), new Literal(System.Runtime.ConstrainedExecution.Cer.MayFail, cer)), AttributeTargets.Method ); m.Attributes.Add(attribute); } } return m; }
private Method MakeFailureMethod() { Parameter kindParameter = new Parameter(Identifier.For("kind"), contractNodes.ContractFailureKind); Parameter messageParameter = new Parameter(Identifier.For("msg"), SystemTypes.String); Parameter conditionTextParameter = new Parameter(Identifier.For("conditionTxt"), SystemTypes.String); Parameter exceptionParameter = new Parameter(Identifier.For("inner"), SystemTypes.Exception); ParameterList pl = new ParameterList(kindParameter, messageParameter, conditionTextParameter, exceptionParameter); Block body = new Block(new StatementList()); Method m = new Method(this.RuntimeContractType, null, ContractNodes.ReportFailureName, pl, SystemTypes.Void, body); m.Flags = MethodFlags.Assembly | MethodFlags.Static; m.Attributes = new AttributeList(); this.RuntimeContractType.Members.Add(m); Block returnBlock = new Block(new StatementList(new Return())); // // Generate the following // // // message == null means: yes we handled it. Otherwise it is the localized failure message // var message = RaiseFailureEvent(kind, userMessage, conditionString, inner); // if (message == null) return; var messageLocal = new Local(Identifier.For("msg"), SystemTypes.String); ExpressionList elist = new ExpressionList(); elist.Add(kindParameter); elist.Add(messageParameter); elist.Add(conditionTextParameter); elist.Add(exceptionParameter); body.Statements.Add(new AssignmentStatement(messageLocal, new MethodCall(new MemberBinding(null, this.RaiseFailureEventMethod), elist))); body.Statements.Add(new Branch(new UnaryExpression(messageLocal, NodeType.LogicalNot), returnBlock)); body.Statements.Add(new ExpressionStatement(new MethodCall(new MemberBinding(null, this.TriggerFailureMethod), new ExpressionList(kindParameter, messageLocal, messageParameter, conditionTextParameter, exceptionParameter)))); body.Statements.Add(returnBlock); return m; }
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; }
/// <summary> /// Constructs (and returns) a method that looks like this: /// /// [System.Diagnostics.DebuggerNonUserCodeAttribute] /// [System.Runtime.ConstrainedExecution.ReliabilityContractReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] /// static void name(bool condition, string message, string conditionText){ /// if (!condition) { /// System.Diagnostics.Contracts.Contract.Failure(kind, message, conditionText, null); /// } /// } /// /// Or, if the ContractFailureKind is PostconditionOnException, then the generated method /// gets an extra parameter which is an Exception and that parameter is passed to Contract.Failure instead of null /// </summary> private Method MakeMethod(string name, ContractFailureKind kind) { Parameter conditionParameter = new Parameter(Identifier.For("condition"), SystemTypes.Boolean); Parameter messageParameter = new Parameter(Identifier.For("msg"), SystemTypes.String); Parameter conditionTextParameter = new Parameter(Identifier.For("conditionTxt"), SystemTypes.String); Parameter exceptionParameter = new Parameter(Identifier.For("originalException"), SystemTypes.Exception); Block returnBlock = new Block(new StatementList(new Return())); Block body = new Block(new StatementList()); Block b = new Block(new StatementList()); b.Statements.Add(new Branch(conditionParameter, returnBlock)); ExpressionList elist = new ExpressionList(); elist.Add(TranslateKindForBackwardCompatibility(kind)); elist.Add(messageParameter); elist.Add(conditionTextParameter); if (kind == ContractFailureKind.PostconditionOnException) { elist.Add(exceptionParameter); } else { elist.Add(Literal.Null); } b.Statements.Add(new ExpressionStatement(new MethodCall(new MemberBinding(null, this.FailureMethod), elist))); b.Statements.Add(returnBlock); body.Statements.Add(b); ParameterList pl = new ParameterList(conditionParameter, messageParameter, conditionTextParameter); if (kind == ContractFailureKind.PostconditionOnException) { pl.Add(exceptionParameter); } Method m = new Method(this.RuntimeContractType, null, Identifier.For(name), pl, SystemTypes.Void, body); m.Flags = MethodFlags.Assembly | MethodFlags.Static; m.Attributes = new AttributeList(); this.RuntimeContractType.Members.Add(m); Member constructor = null; AttributeNode attribute = null; #region Add [DebuggerNonUserCodeAttribute] if (this.HideFromDebugger) { TypeNode debuggerNonUserCode = SystemTypes.SystemAssembly.GetType(Identifier.For("System.Diagnostics"), Identifier.For("DebuggerNonUserCodeAttribute")); if (debuggerNonUserCode != null) { constructor = debuggerNonUserCode.GetConstructor(); attribute = new AttributeNode(new MemberBinding(null, constructor), null, AttributeTargets.Method); m.Attributes.Add(attribute); } } #endregion Add [DebuggerNonUserCodeAttribute] TypeNode reliabilityContract = SystemTypes.SystemAssembly.GetType(Identifier.For("System.Runtime.ConstrainedExecution"), Identifier.For("ReliabilityContractAttribute")); TypeNode consistency = SystemTypes.SystemAssembly.GetType(Identifier.For("System.Runtime.ConstrainedExecution"), Identifier.For("Consistency")); TypeNode cer = SystemTypes.SystemAssembly.GetType(Identifier.For("System.Runtime.ConstrainedExecution"), Identifier.For("Cer")); if (reliabilityContract != null && consistency != null && cer != null) { constructor = reliabilityContract.GetConstructor(consistency, cer); if (constructor != null) { attribute = new AttributeNode( new MemberBinding(null, constructor), new ExpressionList( new Literal(System.Runtime.ConstrainedExecution.Consistency.WillNotCorruptState, consistency), new Literal(System.Runtime.ConstrainedExecution.Cer.MayFail, cer)), AttributeTargets.Method ); m.Attributes.Add(attribute); } } return m; }
private Parameter ParseParameter(TokenSet followers, bool allowRefParameters, bool namesAreOptional, bool typesAreOptional){ Parameter p = new Parameter(); p.SourceContext = this.scanner.CurrentSourceContext; Token tok = this.currentToken; p.Attributes = this.ParseAttributes(null, followers|Parser.ParameterTypeStart); p.Flags = ParameterFlags.None; bool byRef = false; switch(this.currentToken){ case Token.Out: //TODO: error if !allowRefParameters && typesAreOptional p.Flags = ParameterFlags.Out; goto case Token.Ref; case Token.Ref: //TODO: error if !allowRefParameters && typesAreOptional if (!allowRefParameters) this.HandleError(Error.IndexerWithRefParam); byRef = true; this.GetNextToken(); if (this.currentToken == Token.Params){ this.HandleError(Error.ParamsCantBeRefOut); this.GetNextToken(); } break; case Token.Params: //TODO: error if !allowRefParameters && typesAreOptional Literal lit = new Literal(TypeExpressionFor("System", "ParamArrayAttribute"), null, this.scanner.CurrentSourceContext); AttributeNode paramsAttribute = new AttributeNode(lit, null); if (p.Attributes == null) p.Attributes = new AttributeList(1); p.Attributes.Add(paramsAttribute); this.GetNextToken(); if (this.currentToken == Token.Out || this.currentToken == Token.Ref){ this.HandleError(Error.ParamsCantBeRefOut); if (this.currentToken == Token.Out) goto case Token.Out; goto case Token.Ref; } break; } bool voidParam = false; if (this.currentToken == Token.Void){ if (this.inUnsafeCode){ TypeNode voidT = this.TypeExpressionFor(Token.Void); SourceContext sctx = this.scanner.CurrentSourceContext; this.GetNextToken(); sctx.EndPos = this.scanner.endPos; this.Skip(Token.Multiply); p.Type = p.TypeExpression = new PointerTypeExpression(voidT, sctx); }else{ this.HandleError(Error.NoVoidParameter); p.Type = this.TypeExpressionFor(Token.Object); p.TypeExpression = new TypeExpression(this.scanner.GetIdentifier(), this.scanner.CurrentSourceContext); this.GetNextToken(); voidParam = true; } }else if (this.currentToken == Token.Delegate) p.Type = p.TypeExpression = this.ParseDelegateDeclaration(null, null, null, TypeFlags.None, p.SourceContext, followers); else if (p.Type == null){ p.Type = p.TypeExpression = this.ParseTypeExpression(null, followers|Parser.IdentifierOrNonReservedKeyword); } if (byRef) p.Type = p.TypeExpression = new ReferenceTypeExpression(p.Type); if ((this.currentToken == Token.Comma || this.currentToken == Token.RightParenthesis) && p.TypeExpression is TypeExpression && ((TypeExpression)p.TypeExpression).Expression is Identifier && typesAreOptional) { p.Name = (Identifier)((TypeExpression)p.TypeExpression).Expression; p.Type = p.TypeExpression = null; }else{ p.Name = this.scanner.GetIdentifier(); } p.SourceContext.EndPos = this.scanner.endPos; if (!voidParam || Parser.IdentifierOrNonReservedKeyword[this.currentToken]){ if (Parser.IdentifierOrNonReservedKeyword[this.currentToken]) this.GetNextToken(); else{ if (namesAreOptional) p.Name = Identifier.Empty; else this.SkipIdentifierOrNonReservedKeyword(); } } if (this.currentToken == Token.LeftBracket){ this.HandleError(Error.BadArraySyntax); int endPos = this.scanner.endPos; int rank = this.ParseRankSpecifier(true, followers|Token.LeftBracket); if (rank > 0) p.Type = p.TypeExpression = this.ParseArrayType(rank, p.Type, followers); else{ this.currentToken = Token.LeftBracket; this.scanner.endPos = endPos; this.GetNextToken(); while (!this.scanner.TokenIsFirstAfterLineBreak && this.currentToken != Token.RightBracket && this.currentToken != Token.Comma && this.currentToken != Token.RightParenthesis) this.GetNextToken(); if (this.currentToken == Token.RightBracket) this.GetNextToken(); } }else if (this.currentToken == Token.Assign){ this.HandleError(Error.NoDefaultArgs); this.GetNextToken(); if (Parser.UnaryStart[this.currentToken]){ this.ParseExpression(followers); return p; } } this.SkipTo(followers); return p; }
public DuplicatorForContractsAndClosures(Module module, Method sourceMethod, Method targetMethod, ContractNodes contractNodes, bool mapParameters) : base(module, targetMethod.DeclaringType) { this.sourceMethod = sourceMethod; this.targetMethod = targetMethod; this.RemoveNameForLocals = true; Duplicator dup = this; if (mapParameters) { if (sourceMethod.ThisParameter != null) { if (targetMethod.ThisParameter != null) { dup.DuplicateFor[sourceMethod.ThisParameter.UniqueKey] = targetMethod.ThisParameter; } else { // target is a static wrapper. But duplicator cannot handle This -> Parameter conversion // so we handle it explicitly here in this visitor. replaceThisWithParameter = targetMethod.Parameters[0]; } } if (sourceMethod.Parameters != null && targetMethod.Parameters != null && sourceMethod.Parameters.Count == targetMethod.Parameters.Count) { for (int i = 0, n = sourceMethod.Parameters.Count; i < n; i++) { dup.DuplicateFor[sourceMethod.Parameters[i].UniqueKey] = targetMethod.Parameters[i]; } } // This code makes sure that generic method parameters used by contracts inherited from contract class // are correctly replaced by the one defined in the target method. // Without this mapping <c>CheckPost</c> method in generated async closure class would contain an invalid // reference to a generic contract method parameter instead of generic async closure type parameter. // For more about this problem see comments for Microsoft.Contracts.Foxtrot.EmitAsyncClosure.GenericTypeMapper class // and issue #380. if (sourceMethod.TemplateParameters != null && targetMethod.TemplateParameters != null && sourceMethod.TemplateParameters.Count == targetMethod.TemplateParameters.Count) { for (int i = 0, n = sourceMethod.TemplateParameters.Count; i < n; i++) { dup.DuplicateFor[sourceMethod.TemplateParameters[i].UniqueKey] = targetMethod.TemplateParameters[i]; } } } var originalType = HelperMethods.IsContractTypeForSomeOtherType(sourceMethod.DeclaringType, contractNodes); if (originalType != null) { var contractType = this.contractClass = sourceMethod.DeclaringType; while (contractType.Template != null) { contractType = contractType.Template; } while (originalType.Template != null) { originalType = originalType.Template; } // forward ContractType<A,B> -> originalType<A',B'> this.contractClassToForward = contractType; this.targetTypeToForwardTo = originalType; //dup.DuplicateFor[contractType.UniqueKey] = originalType; } }
public void AddAsyncPost(List<Ensures> asyncPostconditions) { var origBody = new Block(this.checkBody); origBody.HasLocals = true; var newBodyBlock = new Block(new StatementList()); newBodyBlock.HasLocals = true; var methodBody = new StatementList(); var methodBodyBlock = new Block(methodBody); methodBodyBlock.HasLocals = true; checkMethod.Body = methodBodyBlock; methodBody.Add(newBodyBlock); Block newExitBlock = new Block(); methodBody.Add(newExitBlock); #region Map closure locals to fields and initialize closure fields foreach (Ensures e in asyncPostconditions) { if (e == null) continue; this.Visit(e); if (this.forwarder != null) { this.forwarder.Visit(e); } ReplaceResult repResult = new ReplaceResult(this.checkMethod, this.originalResultLocal, this.parent.assemblyBeingRewritten); repResult.Visit(e); // now need to initialize closure result fields foreach (var target in repResult.NecessaryResultInitializationAsync(this.closureLocals)) { // note: target here methodBody.Add(new AssignmentStatement(target, this.originalResultLocal)); } } #endregion #region Emit normal postconditions SourceContext lastEnsuresSourceContext = default(SourceContext); bool hasLastEnsuresContext = false; bool containsExceptionalPostconditions = false; var ensuresChecks = new StatementList(); foreach (Ensures e in asyncPostconditions) { // Exceptional postconditions are handled separately. if (e is EnsuresExceptional) { containsExceptionalPostconditions = true; continue; } if (IsVoidTask()) break; // something is wrong in the original contract lastEnsuresSourceContext = e.SourceContext; hasLastEnsuresContext = true; // call Contract.RewriterEnsures Method ensMethod = this.parent.runtimeContracts.EnsuresMethod; ExpressionList args = new ExpressionList(); args.Add(e.PostCondition); if (e.UserMessage != null) args.Add(e.UserMessage); else args.Add(Literal.Null); if (e.SourceConditionText != null) { args.Add(e.SourceConditionText); } else { args.Add(Literal.Null); } ensuresChecks.Add(new ExpressionStatement( new MethodCall(new MemberBinding(null, ensMethod), args, NodeType.Call, SystemTypes.Void), e.SourceContext)); } this.parent.cleanUpCodeCoverage.VisitStatementList(ensuresChecks); this.parent.EmitRecursionGuardAroundChecks(this.checkMethod, methodBodyBlock, ensuresChecks); #endregion Normal postconditions #region Exceptional postconditions if (containsExceptionalPostconditions) { // Because async tasks wrap exceptions into Aggregate exceptions, we have to catch AggregateException // and iterate over the internal exceptions of the Aggregate. // We thus emit the following handler: // // catch(AggregateException ae) { // ae.Handle(this.CheckException); // rethrow; // } // // alternatively, if the Task has no Result, we emit // // var ae = t.Exception as AggregateException; // if (ae != null) { // ae.Handle(this.CheckException); // throw ae; // } var aggregateType = AggregateExceptionType.Value; var exnParameter = new Parameter(Identifier.For("e"), SystemTypes.Exception); this.checkExceptionMethod = new Method(this.closureClass, null, this.checkExceptionMethodId, new ParameterList(exnParameter), SystemTypes.Boolean, new Block(new StatementList())); this.checkExceptionMethod.Body.HasLocals = true; checkExceptionMethod.CallingConvention = CallingConventionFlags.HasThis; checkExceptionMethod.Flags |= MethodFlags.Public; this.closureClass.Members.Add(checkExceptionMethod); if (this.IsVoidTask()) { var blockAfterTest = new Block(); methodBody.Add(origBody); methodBody.Add(new Branch(new UnaryExpression(this.newResultLocal, NodeType.LogicalNot), blockAfterTest)); var funcType = Func2Type.Value; funcType = funcType.GetTemplateInstance(this.parent.assemblyBeingRewritten, SystemTypes.Exception, SystemTypes.Boolean); var handleMethod = aggregateType.GetMethod(Identifier.For("Handle"), funcType); var funcLocal = new Local(funcType); var ldftn = new UnaryExpression(new MemberBinding(null, this.checkExceptionMethod), NodeType.Ldftn, CoreSystemTypes.IntPtr); methodBody.Add(new AssignmentStatement(funcLocal, new Construct(new MemberBinding(null, funcType.GetConstructor(SystemTypes.Object, SystemTypes.IntPtr)), new ExpressionList(this.checkMethod.ThisParameter, ldftn)))); methodBody.Add(new ExpressionStatement(new MethodCall(new MemberBinding(this.newResultLocal, handleMethod), new ExpressionList(funcLocal)))); methodBody.Add(new Throw(this.newResultLocal)); methodBody.Add(blockAfterTest); } else { // The tryCatch holds the try block, the catch blocks, and an empty block that is the // target of an unconditional branch for normal execution to go from the try block // around the catch blocks. if (this.checkMethod.ExceptionHandlers == null) this.checkMethod.ExceptionHandlers = new ExceptionHandlerList(); Block afterCatches = new Block(new StatementList()); Block tryCatch = newBodyBlock; Block tryBlock = new Block(new StatementList()); tryBlock.Statements.Add(origBody); tryBlock.Statements.Add(new Branch(null, afterCatches, false, true, true)); // the EH needs to have a pointer to this block so the writer can // calculate the length of the try block. So it should be the *last* // thing in the try body. Block blockAfterTryBody = new Block(null); tryBlock.Statements.Add(blockAfterTryBody); tryCatch.Statements.Add(tryBlock); // The catchBlock contains the catchBody, and then // an empty block that is used in the EH. Block catchBlock = new Block(new StatementList()); Local l = new Local(aggregateType); Throw rethrow = new Throw(); rethrow.NodeType = NodeType.Rethrow; catchBlock.Statements.Add(new AssignmentStatement(l, new Expression(NodeType.Pop))); var funcType = Func2Type.Value; funcType = funcType.GetTemplateInstance(this.parent.assemblyBeingRewritten, SystemTypes.Exception, SystemTypes.Boolean); var handleMethod = aggregateType.GetMethod(Identifier.For("Handle"), funcType); var funcLocal = new Local(funcType); var ldftn = new UnaryExpression(new MemberBinding(null, this.checkExceptionMethod), NodeType.Ldftn, CoreSystemTypes.IntPtr); catchBlock.Statements.Add(new AssignmentStatement(funcLocal, new Construct(new MemberBinding(null, funcType.GetConstructor(SystemTypes.Object, SystemTypes.IntPtr)), new ExpressionList(this.checkMethod.ThisParameter, ldftn)))); catchBlock.Statements.Add(new ExpressionStatement(new MethodCall(new MemberBinding(l, handleMethod), new ExpressionList(funcLocal)))); // Handle method should return if all passes catchBlock.Statements.Add(rethrow); // The last thing in each catch block is an empty block that is the target of // BlockAfterHandlerEnd in each exception handler. // It is used in the writer to determine the length of each catch block // so it should be the last thing added to each catch block. Block blockAfterHandlerEnd = new Block(new StatementList()); catchBlock.Statements.Add(blockAfterHandlerEnd); tryCatch.Statements.Add(catchBlock); // add information to the ExceptionHandlers of this method ExceptionHandler exHandler = new ExceptionHandler(); exHandler.TryStartBlock = origBody; exHandler.BlockAfterTryEnd = blockAfterTryBody; exHandler.HandlerStartBlock = catchBlock; exHandler.BlockAfterHandlerEnd = blockAfterHandlerEnd; exHandler.FilterType = l.Type; exHandler.HandlerType = NodeType.Catch; this.checkMethod.ExceptionHandlers.Add(exHandler); tryCatch.Statements.Add(afterCatches); } EmitCheckExceptionBody(asyncPostconditions); } else // no exceptional post conditions { newBodyBlock.Statements.Add(origBody); } #endregion Exceptional and finally postconditions #region Create a block for the return statement and insert it // this is the block that contains the return statements // it is (supposed to be) the single exit from the method // that way, anything that must always be done can be done // in this block Statement returnStatement; if (this.IsVoidTask()) { returnStatement = new Return(); } else { returnStatement = new Return(this.newResultLocal); } if (hasLastEnsuresContext) { returnStatement.SourceContext = lastEnsuresSourceContext; } Block returnBlock = new Block(new StatementList(1)); returnBlock.Statements.Add(returnStatement); methodBody.Add(returnBlock); #endregion }
/// <summary> /// Checks whether a specific parameter is an "out" parameter. /// </summary> /// <param name="parameter">Parameter to test.</param> /// <returns>True if "out" parameter.</returns> public static bool IsOut(Parameter parameter) { return (parameter.Flags & ParameterFlags.Out) > 0 && (parameter.Flags & ParameterFlags.In) == 0; }
public static string GetParameterTypeName(Parameter parameter, MemberNameOptions givenOptions, Scope scope) { if (parameter == null) return ""; Reference r = parameter.Type as Reference; TypeNode typeNode = null; StringBuilder sb = new StringBuilder(); string backUpName = null; if (r != null) { if ((parameter.Flags & ParameterFlags.Out) != 0) { if ( IsOptionActive(givenOptions, MemberNameOptions.PutParameterModifiers) ) sb.Append("out "); typeNode = r.ElementType; } else { if (IsOptionActive(givenOptions, MemberNameOptions.PutParameterModifiers)) sb.Append("ref "); typeNode = r.ElementType; } } else if (parameter.GetParamArrayElementType() != null) { if (IsOptionActive(givenOptions, MemberNameOptions.PutParameterModifiers)) sb.Append("params "); typeNode = parameter.Type; } else { typeNode = parameter.Type; if (typeNode == null && parameter.TypeExpression != null) backUpName = parameter.TypeExpression.SourceContext.SourceText; } sb.Append(backUpName != null ? MemberNameBuilder.GetAtPrefixedIfRequired(backUpName, givenOptions) : GetMemberNameRaw(typeNode, givenOptions, scope)); if (IsOptionActive(givenOptions, MemberNameOptions.PutParameterName) && parameter.Name!= null) { sb.Append(' '); sb.Append(MemberNameBuilder.GetAtPrefixedIfRequired(parameter.Name.ToString(), givenOptions)); } return sb.ToString(); }
public override Expression VisitParameter(Parameter parameter) { if (parameter == null) return null; Parameter dup = (Parameter)this.DuplicateFor[parameter.UniqueKey]; if (dup != null) { if (dup.DeclaringMethod == null) dup.DeclaringMethod = this.TargetMethod; return dup; } this.DuplicateFor[parameter.UniqueKey] = dup = (Parameter)parameter.Clone(); if (dup.MarshallingInformation != null) dup.MarshallingInformation = dup.MarshallingInformation.Clone(); dup.DeclaringMethod = this.TargetMethod; return base.VisitParameter(dup); }
public override string GetParameterSignature(ParameterField f){ if (f == null) return ""; StringBuilder result = new StringBuilder("(parameter) "); //REVIEW: localize the (parameter) part? this.currentParameter = f.Parameter; result.Append(this.GetTypeName(f.Type)+" "+f.Name.ToString()); return result.ToString(); }
public override Expression VisitParameter(Parameter parameter) { Parameter result = (Parameter)base.VisitParameter(parameter); Reference pRefType = result.Type as Reference; return result; }
private Expression ParsePrimaryExpression(TokenSet followers){ Expression expression = null; SourceContext sctx = this.scanner.CurrentSourceContext; switch(this.currentToken){ case Token.ArgList: this.GetNextToken(); expression = new ArglistExpression(sctx); break; case Token.Delegate:{ this.GetNextToken(); ParameterList parameters = null; if (this.currentToken == Token.LeftParenthesis) parameters = this.ParseParameters(Token.RightParenthesis, followers|Token.LeftBrace); Block block = null; if (this.currentToken == Token.LeftBrace) block = this.ParseBlock(this.scanner.CurrentSourceContext, followers); else this.SkipTo(followers, Error.ExpectedLeftBrace); sctx.EndPos = this.scanner.endPos; return new AnonymousNestedDelegate(parameters, block, sctx);} case Token.New: expression = this.ParseNew(followers|Token.Dot|Token.LeftBracket|Token.Arrow); break; case Token.Identifier: expression = this.scanner.GetIdentifier(); if (this.sink != null) { this.sink.StartName((Identifier)expression); } this.GetNextToken(); if (this.currentToken == Token.DoubleColon){ this.GetNextToken(); Identifier id = this.scanner.GetIdentifier(); id.Prefix = (Identifier)expression; id.SourceContext.StartPos = expression.SourceContext.StartPos; expression = id; if (this.currentToken != Token.EndOfFile) this.GetNextToken(); }else if (this.currentToken == Token.Lambda){ Parameter par = new Parameter((Identifier)expression, null); par.SourceContext = expression.SourceContext; return this.ParseLambdaExpression(par.SourceContext, new ParameterList(par), followers); } break; case Token.Null: expression = new Literal(null, null, sctx); this.GetNextToken(); break; case Token.True: expression = new Literal(true, null, sctx); this.GetNextToken(); break; case Token.False: expression = new Literal(false, null, sctx); this.GetNextToken(); break; case Token.CharLiteral: expression = new Literal(this.scanner.charLiteralValue, null, sctx); this.GetNextToken(); break; case Token.HexLiteral: expression = this.ParseHexLiteral(); break; case Token.IntegerLiteral: expression = this.ParseIntegerLiteral(); break; case Token.RealLiteral: expression = this.ParseRealLiteral(); break; case Token.StringLiteral: expression = this.scanner.GetStringLiteral(); this.GetNextToken(); break; case Token.This: expression = new This(sctx, false); if (this.sink != null) { this.sink.StartName(expression); } this.GetNextToken(); if (this.currentToken == Token.LeftParenthesis && (this.inInstanceConstructor==BaseOrThisCallKind.None || this.inInstanceConstructor==BaseOrThisCallKind.InCtorBodyThisSeen)){ QualifiedIdentifier thisCons = new QualifiedIdentifier(expression, StandardIds.Ctor, this.scanner.CurrentSourceContext); MethodCall thisConstructorCall = new MethodCall(thisCons, null, NodeType.Call); thisConstructorCall.SourceContext = sctx; SourceContext lpCtx = this.scanner.CurrentSourceContext; this.Skip(Token.LeftParenthesis); thisConstructorCall.Operands = this.ParseArgumentList(followers|Token.LeftBrace|Token.Semicolon, lpCtx, out thisConstructorCall.SourceContext.EndPos); expression = thisConstructorCall; this.inInstanceConstructor=BaseOrThisCallKind.InCtorBodyThisSeen; goto done; } break; case Token.Base: Base ba = new Base(sctx, false); expression = ba; if (this.sink != null) { this.sink.StartName(expression); } this.GetNextToken(); if (this.currentToken == Token.Semicolon && (this.inInstanceConstructor == BaseOrThisCallKind.ColonThisOrBaseSeen || this.inInstanceConstructor == BaseOrThisCallKind.None)) { // When there are non-null fields, then the base ctor call can happen only after they are // initialized. // In Spec#, we allow a base ctor call in the body of the ctor. But if someone is using // the C# comment convention, then they cannot do that. // So allow "base;" as a marker to indicate where the base ctor call should happen. // There may be an explicit "colon base call" or it may be implicit. // // Just leave expression as a bare "Base" node; later pipeline stages will all have // to ignore it. Mark the current ctor as having (at least) one of these bad boys // in it. ba.UsedAsMarker = true; this.currentCtor.ContainsBaseMarkerBecauseOfNonNullFields = true; goto done; } if (this.currentToken == Token.LeftParenthesis && (this.inInstanceConstructor==BaseOrThisCallKind.None || this.inInstanceConstructor==BaseOrThisCallKind.InCtorBodyBaseSeen)){ QualifiedIdentifier supCons = new QualifiedIdentifier(expression, StandardIds.Ctor, this.scanner.CurrentSourceContext); MethodCall superConstructorCall = new MethodCall(supCons, null, NodeType.Call); superConstructorCall.SourceContext = sctx; SourceContext lpCtx = this.scanner.CurrentSourceContext; this.Skip(Token.LeftParenthesis); superConstructorCall.Operands = this.ParseArgumentList(followers|Token.LeftBrace|Token.Semicolon, lpCtx, out superConstructorCall.SourceContext.EndPos); expression = superConstructorCall; this.inInstanceConstructor=BaseOrThisCallKind.InCtorBodyBaseSeen; goto done; } break; case Token.Typeof: case Token.Sizeof: case Token.Default:{ //if (this.currentToken == Token.Sizeof && !this.inUnsafeCode) //this.HandleError(Error.SizeofUnsafe); UnaryExpression uex = new UnaryExpression(null, this.currentToken == Token.Typeof ? NodeType.Typeof : this.currentToken == Token.Sizeof ? NodeType.Sizeof : NodeType.DefaultValue); uex.SourceContext = sctx; this.GetNextToken(); this.Skip(Token.LeftParenthesis); TypeNode t = null; if (this.currentToken == Token.Void && uex.NodeType == NodeType.Typeof){ t = this.TypeExpressionFor(Token.Void); this.GetNextToken(); }else t = this.ParseTypeExpression(null, followers|Token.RightParenthesis, false, false, uex.NodeType == NodeType.Typeof); if (t == null){this.SkipTo(followers); return null;} uex.Operand = new MemberBinding(null, t, t.SourceContext, null); uex.Operand.SourceContext = t.SourceContext; uex.SourceContext.EndPos = this.scanner.endPos; this.Skip(Token.RightParenthesis); expression = uex; break;} case Token.Stackalloc:{ this.GetNextToken(); TypeNode elementType = this.ParseBaseTypeExpression(null, followers|Token.LeftBracket, false, false); if (elementType == null){this.SkipTo(followers); return null;} Token openingDelimiter = this.currentToken; if (this.currentToken != Token.LeftBracket){ this.HandleError(Error.BadStackAllocExpr); if (this.currentToken == Token.LeftParenthesis) this.GetNextToken(); }else this.GetNextToken(); Expression numElements = this.ParseExpression(followers|Token.RightBracket|Token.RightParenthesis); sctx.EndPos = this.scanner.endPos; if (this.currentToken == Token.RightParenthesis && openingDelimiter == Token.LeftParenthesis) this.GetNextToken(); else this.Skip(Token.RightBracket); this.SkipTo(followers); return new StackAlloc(elementType, numElements, sctx);} case Token.Checked: case Token.Unchecked: //TODO: use NodeType.SkipCheck and NodeType.EnforceCheck Block b = new Block(new StatementList(1), this.currentToken == Token.Checked, this.currentToken == Token.Unchecked, this.inUnsafeCode); b.SourceContext = sctx; this.GetNextToken(); this.Skip(Token.LeftParenthesis); b.Statements.Add(new ExpressionStatement(this.ParseExpression(followers|Token.RightParenthesis))); this.Skip(Token.RightParenthesis); expression = new BlockExpression(b); expression.SourceContext = b.SourceContext; break; case Token.RefType:{ this.GetNextToken(); this.Skip(Token.LeftParenthesis); Expression e = this.ParseExpression(followers|Token.RightParenthesis); this.Skip(Token.RightParenthesis); expression = new RefTypeExpression(e, sctx); break; } case Token.RefValue:{ this.GetNextToken(); this.Skip(Token.LeftParenthesis); Expression e = this.ParseExpression(followers|Token.Comma); this.Skip(Token.Comma); TypeNode te = this.ParseTypeOrFunctionTypeExpression(followers|Token.RightParenthesis, false, true); Expression operand2 = new MemberBinding(null, te); if (te is TypeExpression) operand2.SourceContext = te.SourceContext; else operand2.SourceContext = sctx; this.Skip(Token.RightParenthesis); expression = new RefValueExpression(e, operand2, sctx); break; } case Token.Bool: case Token.Decimal: case Token.Sbyte: case Token.Byte: case Token.Short: case Token.Ushort: case Token.Int: case Token.Uint: case Token.Long: case Token.Ulong: case Token.Char: case Token.Float: case Token.Double: case Token.Object: case Token.String: MemberBinding mb = new MemberBinding(null, this.TypeExpressionFor(this.currentToken), sctx); this.GetNextToken(); expression = this.ParseIndexerCallOrSelector(mb, followers); goto done; case Token.LeftParenthesis: expression = this.ParseParenthesizedExpression(followers|Token.Dot|Token.LeftBracket|Token.Arrow, true); break; default: if (Parser.IdentifierOrNonReservedKeyword[this.currentToken]) goto case Token.Identifier; if (Parser.InfixOperators[this.currentToken]){ this.HandleError(Error.InvalidExprTerm, this.scanner.GetTokenSource()); this.GetNextToken(); }else this.SkipTo(followers|Parser.PrimaryStart, Error.InvalidExprTerm, this.scanner.GetTokenSource()); if (Parser.PrimaryStart[this.currentToken]) return this.ParsePrimaryExpression(followers); goto done; } if (expression is Base && this.currentToken != Token.Dot && this.currentToken != Token.LeftBracket){ this.HandleError(expression.SourceContext, Error.BaseIllegal); expression = null; } expression = this.ParseIndexerCallOrSelector(expression, followers|Token.AddOne|Token.SubtractOne); for(;;){ switch(this.currentToken){ case Token.AddOne: case Token.SubtractOne: SourceContext ctx = expression.SourceContext; ctx.EndPos = this.scanner.endPos; PostfixExpression pex = new PostfixExpression(expression, Parser.ConvertToBinaryNodeType(this.currentToken), ctx); this.GetNextToken(); expression = pex; break; case Token.Dot: expression = this.ParseIndexerCallOrSelector(expression, followers|Token.AddOne|Token.SubtractOne); break; default: goto done; } } done: this.SkipTo(followers); return expression; }
private Method MakeTriggerFailureMethod(bool throwOnFailure) { Parameter kindParameter = new Parameter(Identifier.For("kind"), contractNodes.ContractFailureKind); Parameter messageParameter = new Parameter(Identifier.For("msg"), SystemTypes.String); Parameter userMessageParameter = new Parameter(Identifier.For("userMessage"), SystemTypes.String); Parameter conditionTextParameter = new Parameter(Identifier.For("conditionTxt"), SystemTypes.String); Parameter exceptionParameter = new Parameter(Identifier.For("inner"), SystemTypes.Exception); ParameterList pl = new ParameterList(kindParameter, messageParameter, userMessageParameter, conditionTextParameter, exceptionParameter); Block body = new Block(new StatementList()); Method m = new Method(this.RuntimeContractType, null, ContractNodes.TriggerFailureName, pl, SystemTypes.Void, body); m.Flags = MethodFlags.Assembly | MethodFlags.Static; m.Attributes = new AttributeList(); this.RuntimeContractType.Members.Add(m); // // Generate the following // // #if throwOnFailure // throw new ContractException(kind, message, userMessage, conditionText, inner); // #else // Debug.Assert(false, messageParameter); // #endif if (throwOnFailure) { ExpressionList elist = new ExpressionList(); elist.Add(kindParameter); elist.Add(messageParameter); elist.Add(userMessageParameter); elist.Add(conditionTextParameter); elist.Add(exceptionParameter); body.Statements.Add(new Throw(new Construct(new MemberBinding(null, this.ContractExceptionCtor), elist))); } else { var sysassem = SystemTypes.SystemDllAssembly; if (sysassem == null) { throw new ApplicationException("Cannot find System.dll"); } var debugType = sysassem.GetType(Identifier.For("System.Diagnostics"), Identifier.For("Debug")); if (debugType == null) { throw new ApplicationException("Cannot find System.Diagnostics.Debug"); } var assertMethod = debugType.GetMethod(Identifier.For("Assert"), SystemTypes.Boolean, SystemTypes.String); if (assertMethod == null) { throw new ApplicationException("Cannot find System.Diagnostics.Debug.Assert(bool,string)"); } ExpressionList elist = new ExpressionList(); elist.Add(Literal.False); elist.Add(messageParameter); body.Statements.Add(new ExpressionStatement(new MethodCall(new MemberBinding(null, assertMethod), elist))); body.Statements.Add(new Return()); } return m; }
public override AttributeNode VisitParameterAttribute(AttributeNode attr, Parameter parameter) { attr = base.VisitParameterAttribute(attr, parameter); if (attr == null) return null; if (attr.Type == SystemTypes.ParamArrayAttribute && attr.SourceContext.Document != null) this.HandleError(attr, Error.ExplicitParamArray, this.GetTypeName(SystemTypes.ParamArrayAttribute)); if ((IsAdditive(attr) || IsInside(attr) || attr.Type == SystemTypes.CapturedAttribute || attr.Type == SystemTypes.NoDefaultContractAttribute) && parameter.Type != null && parameter.Type.IsValueType) { this.HandleError(attr, Error.AttributeAllowedOnlyOnReferenceTypeParameters, this.GetTypeName(attr.Type)); } if (attr.Type == SystemTypes.CapturedAttribute && parameter.IsOut) { this.HandleError(attr, Error.AttributeNotAllowedOnlyOnInParameters, this.GetTypeName(attr.Type)); } return attr; }
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); }
private ParameterList ParseParameters(Token closingToken, TokenSet followers, bool namesAreOptional, bool typesAreOptional){ bool arglist = false; Debug.Assert(closingToken == Token.RightParenthesis || closingToken == Token.RightBracket); SourceContext sctx = this.scanner.CurrentSourceContext; if (closingToken == Token.RightParenthesis){ if (this.currentToken != Token.LeftParenthesis){ this.SkipTo(followers|Parser.UnaryStart, Error.SyntaxError, "("); } if (this.currentToken == Token.LeftParenthesis) this.GetNextToken(); }else{ if (this.currentToken != Token.LeftBracket) this.SkipTo(followers|Parser.UnaryStart, Error.SyntaxError, "["); if (this.currentToken == Token.LeftBracket) this.GetNextToken(); } ParameterList result = new ParameterList(); if (this.currentToken != closingToken && this.currentToken != Token.EndOfFile){ bool allowRefParameters = closingToken == Token.RightParenthesis; TokenSet followersOrCommaOrRightParenthesis = followers|Token.Comma|closingToken|Token.ArgList; int counter = 0; for (;;){ if (this.currentToken == Token.ArgList) { Parameter ap = new Parameter(StandardIds.__Arglist, this.TypeExpressionFor(Token.Void)); ap.SourceContext = this.scanner.CurrentSourceContext; this.GetNextToken(); arglist = true; result.Add(ap); break; } Parameter p = this.ParseParameter(followersOrCommaOrRightParenthesis, allowRefParameters, namesAreOptional, typesAreOptional); if (namesAreOptional && p != null && p.Name == Identifier.Empty){ p.Name = new Identifier("p"+counter++); if (p.Type != null) p.Name.SourceContext = p.Type.SourceContext; } if (typesAreOptional && p != null && p.Type == null) allowRefParameters = false; result.Add(p); if (this.currentToken == Token.Comma) this.GetNextToken(); else break; } } if (closingToken == Token.RightBracket) { if (result.Count == 0) this.HandleError(Error.IndexerNeedsParam); else if (arglist) { this.HandleError(result[result.Count-1].SourceContext, Error.NoArglistInIndexers); result.Count = result.Count-1; } } if (this.currentToken == closingToken){ if (this.sink != null) this.sink.MatchPair(sctx, this.scanner.CurrentSourceContext); this.GetNextToken(); this.SkipTo(followers); }else{ this.SkipTo(followers, closingToken==Token.RightBracket ? Error.ExpectedRightBracket : Error.ExpectedRightParenthesis); } return result; }
/// <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; }
private static bool FieldAssociatedWithParameter(Field field, Method originalMethod, out Parameter p) { string fname = field.Name.Name; if (fname.EndsWith("__this")) { // check that it is not a nested one if (fname.Length > 8 && !fname.Substring(2, fname.Length - 8).Contains("__")) { p = originalMethod.ThisParameter; return true; } } foreach (Parameter par in originalMethod.Parameters) { string pname = par.Name.Name; if (fname == pname) { p = par; return true; } } p = null; return false; }
public virtual Expression VisitParameter(Parameter parameter) { if (parameter == null) return null; parameter.Attributes = this.VisitAttributeList(parameter.Attributes); parameter.Type = this.VisitTypeReference(parameter.Type); parameter.DefaultValue = this.VisitExpression(parameter.DefaultValue); ParameterBinding pb = parameter as ParameterBinding; if (pb != null) { Parameter par = this.VisitParameter(pb.BoundParameter) as Parameter; if (par != null) pb.BoundParameter = par; } return parameter; }
public override Expression CoerceArgument(Expression argument, Parameter parameter) { Expression result = base.CoerceArgument(argument, parameter); if (result != null) { Reference r = parameter.Type as Reference; if (r != null) { UnaryExpression unexp = argument as UnaryExpression; if (parameter.IsOut) { if (unexp == null) { if (argument.SourceContext.Document != null) this.HandleError(argument, Error.NoImplicitConversion, this.typeSystem.GetTypeName(r.ElementType), this.typeSystem.GetTypeName(r)); } else { if (unexp.NodeType == NodeType.RefAddress) this.HandleError(argument, Error.NoImplicitConversion, "ref " + this.typeSystem.GetTypeName(r.ElementType), this.typeSystem.GetTypeName(r)); else if (unexp.NodeType != NodeType.OutAddress) this.HandleError(argument, Error.NoImplicitConversion, this.typeSystem.GetTypeName(r.ElementType), this.typeSystem.GetTypeName(r)); } } else { if (unexp == null) { if (argument.SourceContext.Document != null) this.HandleError(argument, Error.NoImplicitConversion, this.typeSystem.GetTypeName(r.ElementType), this.typeSystem.GetTypeName(r)); } else { if (unexp.NodeType == NodeType.OutAddress) this.HandleError(argument, Error.NoImplicitConversion, "out " + this.typeSystem.GetTypeName(r.ElementType), this.typeSystem.GetTypeName(r)); else if (unexp.NodeType != NodeType.RefAddress) this.HandleError(argument, Error.NoImplicitConversion, this.typeSystem.GetTypeName(r.ElementType), this.typeSystem.GetTypeName(r)); } } } else if (!(parameter.Type is Reference)) { if (argument.NodeType == NodeType.OutAddress) this.HandleError(((UnaryExpression)argument).Operand, Error.BadArgExtraRef, (parameter.ParameterListIndex + 1).ToString(), "out"); else if (argument.NodeType == NodeType.RefAddress) this.HandleError(((UnaryExpression)argument).Operand, Error.BadArgExtraRef, (parameter.ParameterListIndex + 1).ToString(), "ref"); } } // Special case to handle arglist when the parameter is a params object[] // and the argument constains __arglist(). We will flatten that __arglist. // This is an effort to simulate CSC. // Note, if passing an __arglist and an object for params object[], CSC generates // invalid code while we are ok. See SingSharpConformance.Suite. TypeNode maybeObjectType = parameter.GetParamArrayElementType(); if (maybeObjectType == SystemTypes.Object) { result = FlattenArglist(result); } return result; }
public override Expression VisitParameter(Parameter parameter) { if (parameter == null) return null; Write("{0}", GetParameterDirection(parameter.Flags)); this.VisitTypeReference(parameter.Type); Write(" "); if (parameter.DefaultValue != null) throw new ArgumentException("Unexpected parameter default value"); Write("{0}", parameter.Name.Name); return parameter; }
private static TypeNode IsConstrainedTypeVariable(Parameter target) { if (target == null) return null; Reference r = target.Type as Reference; if (r == null) return null; if (!(r.ElementType is ITypeParameter)) return null; return r.ElementType; }