public CollectOldExpressions(Module module, Method method, ContractNodes contractNodes, Dictionary<TypeNode, Local> closureLocals, int localCounterStart, Class initialClosureClass) : this(module, method, contractNodes, closureLocals, localCounterStart) { this.topLevelClosureClass = initialClosureClass; this.currentClosureClass = initialClosureClass; }
public ScrubContractClass(ExtractorVisitor parent, Class contractClass, TypeNode originalType) { Contract.Requires(TypeNode.IsCompleteTemplate(contractClass)); Contract.Requires(TypeNode.IsCompleteTemplate(originalType)); this.parent = parent; this.contractClass = contractClass; this.abstractClass = originalType; }
private ClassParameter ConvertToClassParameter(TypeNode typeParameter, InterfaceList interfaces, Class baseClass, ClassExpression cExpr){ ClassParameter cParam = typeParameter is MethodTypeParameter ? new MethodClassParameter() : new ClassParameter(); this.typeParamToClassParamMap[typeParameter.UniqueKey] = cParam; cParam.SourceContext = typeParameter.SourceContext; cParam.TypeParameterFlags = ((ITypeParameter)typeParameter).TypeParameterFlags; if (typeParameter.IsUnmanaged) { cParam.SetIsUnmanaged(); } cParam.Name = typeParameter.Name; cParam.Namespace = StandardIds.ClassParameter; cParam.BaseClass = baseClass == null ? SystemTypes.Object : baseClass; cParam.BaseClassExpression = cExpr; cParam.DeclaringMember = ((ITypeParameter)typeParameter).DeclaringMember; cParam.DeclaringModule = typeParameter.DeclaringModule; cParam.DeclaringType = typeParameter is MethodTypeParameter ? null : typeParameter.DeclaringType; cParam.Flags = typeParameter.Flags & ~TypeFlags.Interface; cParam.ParameterListIndex = ((ITypeParameter)typeParameter).ParameterListIndex; MemberList mems = cParam.DeclaringType == null ? null : cParam.DeclaringType.Members; int n = mems == null ? 0 : mems.Count; for (int i = 0; i < n; i++){ if ((mems[i] as TypeNode) == typeParameter){ mems[i] = cParam; break; } } if (cExpr != null){ n = interfaces.Count - 1; InterfaceList actualInterfaces = new InterfaceList(n); for (int i = 0; i < n; i++) actualInterfaces.Add(interfaces[i + 1]); cParam.Interfaces = actualInterfaces; }else cParam.Interfaces = interfaces; if (cExpr != null) cParam.BaseClass = this.VisitClassExpression(cExpr); return cParam; }
private static void ClearStatics() { AttributeUsageAttribute = null; ConditionalAttribute = null; DefaultMemberAttribute = null; InternalsVisibleToAttribute = null; ObsoleteAttribute = null; GenericICollection = null; GenericIEnumerable = null; GenericIList = null; ICloneable = null; ICollection = null; IEnumerable = null; IList = null; //Special attributes AllowPartiallyTrustedCallersAttribute = null; AssemblyCompanyAttribute = null; AssemblyConfigurationAttribute = null; AssemblyCopyrightAttribute = null; AssemblyCultureAttribute = null; AssemblyDelaySignAttribute = null; AssemblyDescriptionAttribute = null; AssemblyFileVersionAttribute = null; AssemblyFlagsAttribute = null; AssemblyInformationalVersionAttribute = null; AssemblyKeyFileAttribute = null; AssemblyKeyNameAttribute = null; AssemblyProductAttribute = null; AssemblyTitleAttribute = null; AssemblyTrademarkAttribute = null; AssemblyVersionAttribute = null; ClassInterfaceAttribute = null; CLSCompliantAttribute = null; ComImportAttribute = null; ComRegisterFunctionAttribute = null; ComSourceInterfacesAttribute = null; ComUnregisterFunctionAttribute = null; ComVisibleAttribute = null; DebuggableAttribute = null; DebuggerHiddenAttribute = null; DebuggerStepThroughAttribute = null; DebuggingModes = null; DllImportAttribute = null; FieldOffsetAttribute = null; FlagsAttribute = null; GuidAttribute = null; ImportedFromTypeLibAttribute = null; InAttribute = null; IndexerNameAttribute = null; InterfaceTypeAttribute = null; MethodImplAttribute = null; NonSerializedAttribute = null; OptionalAttribute = null; OutAttribute = null; ParamArrayAttribute = null; RuntimeCompatibilityAttribute = null; SatelliteContractVersionAttribute = null; SerializableAttribute = null; SecurityAttribute = null; SecurityCriticalAttribute = null; SecurityTransparentAttribute = null; SecurityTreatAsSafeAttribute = null; STAThreadAttribute = null; StructLayoutAttribute = null; SuppressMessageAttribute = null; SuppressUnmanagedCodeSecurityAttribute = null; SecurityAction = null; //Classes need for System.TypeCode DBNull = null; DateTime = null; TimeSpan = null; //Classes and interfaces used by the Framework Activator = null; AppDomain = null; ApplicationException = null; ArgumentException = null; ArgumentNullException = null; ArgumentOutOfRangeException = null; ArrayList = null; AsyncCallback = null; Assembly = null; CodeAccessPermission = null; CollectionBase = null; CultureInfo = null; DictionaryBase = null; DictionaryEntry = null; DuplicateWaitObjectException = null; Environment = null; EventArgs = null; ExecutionEngineException = null; GenericArraySegment = null; GenericArrayToIEnumerableAdapter = null; GenericDictionary = null; GenericIComparable = null; GenericIComparer = null; GenericIDictionary = null; GenericIEnumerator = null; GenericKeyValuePair = null; GenericList = null; GenericNullable = null; GenericQueue = null; GenericSortedDictionary = null; GenericStack = null; GC = null; Guid = null; __HandleProtector = null; HandleRef = null; Hashtable = null; IASyncResult = null; IComparable = null; IDictionary = null; IComparer = null; IDisposable = null; IEnumerator = null; IFormatProvider = null; IHashCodeProvider = null; IMembershipCondition = null; IndexOutOfRangeException = null; InvalidCastException = null; InvalidOperationException = null; IPermission = null; ISerializable = null; IStackWalk = null; Marshal = null; MarshalByRefObject = null; MemberInfo = null; NativeOverlapped = null; Monitor = null; NotSupportedException = null; NullReferenceException = null; OutOfMemoryException = null; ParameterInfo = null; Queue = null; ReadOnlyCollectionBase = null; ResourceManager = null; ResourceSet = null; SerializationInfo = null; Stack = null; StackOverflowException = null; Stream = null; StreamingContext = null; StringBuilder = null; StringComparer = null; StringComparison = null; SystemException = null; Thread = null; WindowsImpersonationContext = null; }
public override Class VisitClass(Class Class) { PrepareGuardedClass(Class); return base.VisitClass(Class); }
private void CheckForWrapperImplementationsForInheritedInterfaceImplementations(Class Class) { Contract.Requires(Class != null); if (Class.Interfaces == null) return; if (this.runtimeCheckingLevel == 0) return; if (!HelperMethods.ContractOption(Class, "runtime", "checking") || !HelperMethods.ContractOption(Class, "contract", "inheritance")) { return; } for (int i = 0; i < Class.Interfaces.Count; i++) { var intf = Class.Interfaces[i]; if (intf == null) continue; CheckForWrapperImplementationsForInheritedInterfaceImplementations(Class, intf); } }
public override Class VisitClass(Class Class) { Class = base.VisitClass(Class); Class.Template = null; return Class; }
void AddReadContent(Class serializer, Block block, TypeNode type, StatementList statements, Identifier reader, Expression target, Expression required, Expression result, SchemaValidator validator) { // position us in the content. statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(reader, Identifier.For("MoveToContent")), new ExpressionList()))); Local elementName = new Local(Identifier.Empty,SystemTypes.String); statements.Add(new AssignmentStatement(elementName, new QualifiedIdentifier(reader, Identifier.For("LocalName")))); // make sure the element is not empty. If isEmpty = AddEmptyElementCheck(statements, reader); // Read the contents. statements = isEmpty.FalseBlock.Statements; statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(reader, Identifier.For("Read")), new ExpressionList()))); statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(reader, Identifier.For("MoveToContent")), new ExpressionList()))); ValidationState context = new ValidationState(); context.ErrorHandler = this.errorHandler; validator.validator.InitValidation(context); ArrayList members = null; if (validator.validator is AllElementsContentValidator) { members = validator.validator.ExpectedElements(context, false, false); AddReadAllGroup(serializer, block, type, statements, reader, target, required, result, members, validator.validator.MixedMember); } else { // There should be one root level anonymous Item0 member. SequenceNode seq = (SequenceNode)validator.RootNode; // this is a wrapper node. if (seq == null) { // perhaps it is ContentType.Empty or Mixed. if (validator.validator.ContentType == XmlSchemaContentType.Mixed || validator.validator.ContentType == XmlSchemaContentType.TextOnly){ Debug.Assert(validator.validator.MixedMember != null); statements.Add(new AssignmentStatement(GetMemberBinding(target, validator.validator.MixedMember), new MethodCall(new QualifiedIdentifier(reader, Identifier.For("ReadStringElement")), new ExpressionList()))); } return; } else { ContentNode n = seq.LeftChild; AddReadContentNode(n, block, statements, reader, target, required, result, validator); } } // consume final end tag statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(reader, Identifier.For("ReadEndTag")), new ExpressionList(elementName)))); }
public override Class VisitClass(Class Class) { WriteStart("class {0}", Class.Name.Name); if (this.braceOnNewLine) { WriteFinish(string.Empty); WriteLine("{"); } else WriteFinish(" {"); In(); Class.Members = this.VisitMemberList(Class.Members); Out(); WriteLine("};"); return Class; }
private Block ProcessOldExpressionsInAsync(Method method, EnsuresList asyncpostconditions, Dictionary<TypeNode, Local> closureLocals, ref int oldLocalNameCounter, Class asyncClosure) { Contract.Requires(asyncpostconditions != null); CollectOldExpressions coe = new CollectOldExpressions( this.module, method, this.rewriterNodes, closureLocals, oldLocalNameCounter, asyncClosure ); foreach (Ensures e in asyncpostconditions) { if (!EmitEnsures(e, method.DeclaringType, this.skipQuantifiers)) continue; coe.Visit(e); } oldLocalNameCounter = coe.Counter; var oldAssignments = coe.PrestateValuesOfOldExpressions; // don't wrap in a try catch if the method is a constructor (peverify issue) if (!(method is InstanceInitializer)) { WrapOldAssignmentsInTryCatch(method, oldAssignments); } return oldAssignments; }
/// <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 Method FindAndInstantiateBaseClassInvariantMethod(Class asClass, out Field baseReentrancyFlag) { baseReentrancyFlag = null; if (asClass == null || asClass.BaseClass == null) return null; if (!this.Emit(RuntimeContractEmitFlags.InheritContracts)) return null; // don't call base class invariant if we don't inherit var baseClass = asClass.BaseClass; if (!this.InheritInvariantsAcrossAssemblies && (baseClass.DeclaringModule != asClass.DeclaringModule)) return null; var result = baseClass.GetMethod(Identifier.For("$InvariantMethod$"), null); if (result != null && !HelperMethods.IsVisibleFrom(result, asClass)) return null; if (result == null && baseClass.Template != null) { // instantiation of generated method has not happened. var generic = baseClass.Template.GetMethod(Identifier.For("$InvariantMethod$"), null); if (generic != null) { if (!HelperMethods.IsVisibleFrom(generic, asClass)) return null; // generate proper reference. result = GetMethodInstanceReference(generic, baseClass); } } // extract base reentrancy flag if (result != null) { var instantiatedParent = result.DeclaringType; baseReentrancyFlag = instantiatedParent.GetField(Identifier.For("$evaluatingInvariant$")); if (baseReentrancyFlag == null && baseClass.Template != null) { // instantiation of generated baseReentrancy flag has not happened. var generic = baseClass.Template.GetField(Identifier.For("$evaluatingInvariant$")); if (generic != null) { if (HelperMethods.IsVisibleFrom(generic, asClass)) { baseReentrancyFlag = GetFieldInstanceReference(generic, baseClass); } } } } return result; }
/// <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 VisitBaseClass(Class Class) { // F: Contract.Requires(Class != null); // make sure the possibly generic base class is rewritten before this class var baseClass = Class.BaseClass; if (baseClass == null) return; while (baseClass.Template is Class) { baseClass = (Class)baseClass.Template; } // make sure base class is in same assembly if (Class.DeclaringModule != baseClass.DeclaringModule) return; VisitClass(baseClass); }
public override void VisitClass(Class Class) { if (Class == null) return; if (visitedClasses[Class.UniqueKey] != null) return; visitedClasses[Class.UniqueKey] = Class; VisitBaseClass(Class); base.VisitClass(Class); }
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 TryAddCompilerGeneratedAttribute(Class Class) { Contract.Requires(Class != null); TryAddCompilerGeneratedAttribute(Class, System.AttributeTargets.Class); }
private Class CreateWrapperClass(Class c) { var flags = WrapperTypeFlags(c); var wrapper = new Class(this.assemblyBeingRewritten, null, null, flags, null, c.Name, SystemTypes.Object, null, null); RewriteHelper.TryAddCompilerGeneratedAttribute(wrapper); if (c.TemplateParameters != null) { Duplicator d = new Duplicator(this.assemblyBeingRewritten, wrapper); d.FindTypesToBeDuplicated(c.TemplateParameters); var templateParams = CopyTypeParameterList(wrapper, c, d); wrapper.TemplateParameters = templateParams; wrapper.IsGeneric = true; } return wrapper; }
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 virtual Class VisitClass(Class Class) { return (Class)this.VisitTypeNode(Class); }
void AddReadAllGroup(Class serializer, Block block, TypeNode type, StatementList statements, Identifier reader, Expression target, Expression required, Expression result, ArrayList members, Member mixedMember) { // todo: keep track of which members have been read and report error on duplicates MethodCall read = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("Read")), new ExpressionList()); Local sb = new Local(SystemTypes.StringBuilder); bool isMixed = mixedMember != null; if (isMixed) { statements.Add(new AssignmentStatement(sb, new Construct(new MemberBinding(null, SystemTypes.StringBuilder), new ExpressionList(), SystemTypes.StringBuilder))); } Block whileBody = new Block(new StatementList()); BinaryExpression notEndTag = new BinaryExpression( new QualifiedIdentifier(reader, Identifier.For("NodeType")) , new QualifiedIdentifier(Identifier.For("XmlNodeType"), Identifier.For("EndElement")), NodeType.Ne); BinaryExpression notEOF = new BinaryExpression( new QualifiedIdentifier(reader, Identifier.For("EOF")), Literal.True, NodeType.Ne); While w = new While(new BinaryExpression(notEndTag, notEOF, NodeType.And), whileBody); statements.Add(w); Local nameLocal = new Local(Identifier.For("name"),SystemTypes.String,block); Local nsLocal = new Local(Identifier.For("ns"),SystemTypes.String,block); Local nodeType = new Local(Identifier.For("nodeType"),Runtime.XmlNodeType,block); whileBody.Statements.Add(new AssignmentStatement(nameLocal, new QualifiedIdentifier(reader, Identifier.For("LocalName")))); whileBody.Statements.Add(new AssignmentStatement(nsLocal, new QualifiedIdentifier(reader, Identifier.For("NamespaceURI")))); whileBody.Statements.Add(new AssignmentStatement(nodeType, new QualifiedIdentifier(reader, Identifier.For("NodeType")))); Block childBlock = whileBody; if (isMixed) { // Append the text node to the current StringBuilder contents. childBlock = new Block(new StatementList()); If ifText = new If(IsTextNode(nodeType), new Block(new StatementList()), childBlock); whileBody.Statements.Add(ifText); ExpressionList args = new ExpressionList(); args.Add(new QualifiedIdentifier(reader, Identifier.For("Value"))); ifText.TrueBlock.Statements.Add(new ExpressionStatement(new MethodCall( new QualifiedIdentifier(sb, Identifier.For("Append")), args))); ifText.TrueBlock.Statements.Add(new ExpressionStatement(read)); // advance to next node } If ifElement = new If(new BinaryExpression(nodeType, new QualifiedIdentifier(Identifier.For("XmlNodeType"), Identifier.For("Element")), NodeType.Eq), new Block(new StatementList()), new Block(new StatementList())); childBlock.Statements.Add(ifElement); childBlock = ifElement.TrueBlock; //AddConsoleWrite(statements, new Literal("name=",SystemTypes.String)); //AddConsoleWriteLine(statements, nameLocal); //AddConsoleWrite(statements, new Literal("nodeType=",SystemTypes.String)); //AddConsoleWriteLine(statements, nodeType); foreach (NamedNode childNode in members) { if (!(childNode.Member is Field || childNode.Member is Property)) { AddError(statements, reader, RuntimeError.SerializationOfTypeNotSupported, new Literal(childNode.Member.GetType().FullName, SystemTypes.String)); } else { Expression mb = GetMemberBinding(target, childNode.Member); childBlock = AddReadChild(block, childBlock.Statements, childNode.Name, childNode.TypeNode, mb, reader, result, true, false).FalseBlock; // todo: throw error if child is required. (e.g. NonEmptyIEnumerable...) } } // if it isn't any of the expected elements then throw an error. AddError(childBlock.Statements, reader, RuntimeError.NoSuchMember, new Expression[2]{new Literal(tempChecker.GetTypeName(type),SystemTypes.String), nameLocal}); // If it's not an element then consume it anyway to keep the reader advancing. // Probably a comment or PI or something. ifElement.FalseBlock.Statements.Add(new ExpressionStatement(new MethodCall( new QualifiedIdentifier(reader, Identifier.For("Skip")), new ExpressionList()))); if (isMixed) { statements.Add(new AssignmentStatement(GetMemberBinding(target, mixedMember), new MethodCall(new QualifiedIdentifier(sb, Identifier.For("ToString")), new ExpressionList()))); } statements.Add(new AssignmentStatement(result, Literal.True)); }
private static void AddInterfaceImplementationWrapper(Class Class, Method intfMethod, Method baseMethod) { var d = new Duplicator(Class.DeclaringModule, Class); d.SkipBodies = true; var copy = d.VisitMethod(baseMethod); copy.Flags = MethodFlags.Private | MethodFlags.HideBySig | MethodFlags.Virtual | MethodFlags.NewSlot | MethodFlags.Final; copy.ImplementedInterfaceMethods = new MethodList(intfMethod); copy.Name = Identifier.For("InheritedInterfaceImplementationContractWrapper$" + intfMethod.Name.Name); copy.ClearBody(); copy.ThisParameter.Type = Class; var bodyBlock = new Block(new StatementList()); copy.Body = new Block(new StatementList(bodyBlock)); // add call to baseMethod var calledMethod = (baseMethod.TemplateParameters != null && baseMethod.TemplateParameters.Count > 0) ? baseMethod.GetTemplateInstance(Class, copy.TemplateParameters) : baseMethod; var argList = new ExpressionList(); for (int i = 0; i < copy.Parameters.Count; i++) { argList.Add(copy.Parameters[i]); } var callExpression = new MethodCall(new MemberBinding(copy.ThisParameter, calledMethod), argList); if (HelperMethods.IsVoidType(intfMethod.ReturnType)) { bodyBlock.Statements.Add(new ExpressionStatement(callExpression)); } else { bodyBlock.Statements.Add(new Return(callExpression)); } Class.Members.Add(copy); }
public override void VisitClass(Class Class) { if (Class == null) return; var savedState = this.currentState; this.currentState = savedState.Derive(Class); try { this.CheckClass(Class); CheckForWrapperImplementationsForInheritedInterfaceImplementations(Class); } finally { this.currentState = savedState; } base.VisitClass(Class); }
/// <summary> /// Verifies that a class marked as holding the contract for an interface implements the interface. /// </summary> private void CheckClass(Class Class) { Contract.Requires(Class != null); // Compiler generated classes are closures that should get checked when visiting // the code that generated the closure, not from this end if (HelperMethods.IsCompilerGenerated(Class)) { return; } // Contract classes need to implement the interface/abstract class that they are a contract for TypeNode originalType = HelperMethods.GetTypeFromAttribute(Class, ContractNodes.ContractClassForAttributeName); // Check that contract classes are abstract if (originalType != null && !Class.IsAbstract) { this.HandleError( new Warning(1020, "Contract class '" + Class.FullName + "' should be an abstract class.", new SourceContext())); } Interface iface = originalType as Interface; if (iface != null) { // base class should be object and interfaces should contain exactly 1, the interface if (Class.BaseClass != null && !(IsSystemObject(Class.BaseClass))) { // should be an error this.HandleError( new Warning(1066, "Class '" + Class.FullName + "' is annotated as being the contract for the interface '" + iface.FullName + "' and cannot have an explicit base class other than System.Object.", new SourceContext())); } Interface instance = null; for (int i = 0, n = Class.Interfaces == null ? 0 : Class.Interfaces.Count; i < n; i++) { Interface J = Class.Interfaces[i]; if (J == iface || J.IsStructurallyEquivalentTo(iface)) { instance = J; break; } } if (instance == null) { this.HandleError( new Error(1008, "Class '" + Class.FullName + "' is annotated as being the contract for the interface '" + iface.FullName + "' but doesn't implement the interface.", new SourceContext())); } else { // check other interfaces derive from core interface instance (.NET flattens the interface inheritance) for (int i = 0, n = Class.Interfaces == null ? 0 : Class.Interfaces.Count; i < n; i++) { Interface J = Class.Interfaces[i]; if (J != instance && !instance.IsAssignableTo(J)) { this.HandleError( new Error(1068, string.Format("Class '{0}' is annotated as being the contract for the interface '{1}' but implements unrelated interface '{2}'.", Class.FullName, iface.FullName, J.FullName), new SourceContext())); } } } } else { Class abstractClass = originalType as Class; if (abstractClass != null) { if (!(abstractClass == Class.BaseClass || abstractClass.IsStructurallyEquivalentTo(Class.BaseClass))) { this.HandleError( new Error(1009, "Class '" + Class.FullName + "' is annotated as being the contract for the abstract class '" + abstractClass.FullName + "' but doesn't extend the class.", new SourceContext())); } if (Class.Interfaces != null && Class.Interfaces.Count > 0) { this.HandleError( new Error(1067, "Class '" + Class.FullName + "' is annotated as being the contract for the abstract class '" + abstractClass.FullName + "' and cannot implement any interfaces.", new SourceContext())); } } } // Make sure that if this class *is* a contractClass, that that class points back to this one if (originalType != null) { TypeNode backPointer = HelperMethods.GetTypeFromAttribute(originalType, ContractNodes.ContractClassAttributeName); if (backPointer == null || backPointer != Class) { this.HandleError( new Error(1021, "The class '" + Class.FullName + "' is supposed to be a contract class for '" + originalType.FullName + "', but that type does not point back to this class.", new SourceContext())); } // Checks that contract class matches real class if (!GenericConstraintsMatch(originalType, Class)) { this.HandleError( new Error(1043, "The contract class '" + Class.FullName + "' and the type '" + originalType.FullName + "' must agree on all generic parameters.", new SourceContext())); } // Check that they have the same container if they are generic if (Class.IsGeneric && Class.DeclaringType != originalType.DeclaringType) { this.HandleError( new Error(1044, "The contract class '" + Class.FullName + "' and the type '" + originalType.FullName + "' must have the same declaring type if any.", new SourceContext())); } } // No class should have a contract class as a base class var baseClass = Class.BaseClass; var baseClassIsAContractClass = HelperMethods.GetTypeFromAttribute(baseClass, ContractNodes.ContractClassForAttributeName); if (baseClassIsAContractClass != null) { this.HandleError( new Error(1079, "The class '" + Class.FullName + "' cannot have a base type that is a contract class.", new SourceContext())); } }
private void CheckForWrapperImplementationsForInheritedInterfaceImplementations(Class Class, Interface intf) { Contract.Requires(Class != null); Contract.Requires(intf != null); var members = intf.Members; // if (members == null) return; for (int i = 0; i < members.Count; i++) { var intfMethod = members[i] as Method; if (intfMethod == null) continue; if (Class.ExplicitImplementation(intfMethod) != null) continue; if (Class.GetExactMatchingMethod(intfMethod) != null) continue; var contractMethod = HelperMethods.GetContractMethod(intfMethod); if (contractMethod == null) continue; var contract = contractMethod.Contract; if (contract == null) continue; if (contract.RequiresCount + contract.EnsuresCount == 0) continue; // find base implementing method var baseMethod = FindInheritedMethod(Class.BaseClass, intfMethod); if (baseMethod == null) continue; var baseMethodImplementsInterfaceMethod = false; if (baseMethod.ImplicitlyImplementedInterfaceMethods != null) { for (int j = 0; j < baseMethod.ImplicitlyImplementedInterfaceMethods.Count; j++) { if (baseMethod.ImplicitlyImplementedInterfaceMethods[j] == intfMethod) { baseMethodImplementsInterfaceMethod = true; break; } } } if (baseMethodImplementsInterfaceMethod) continue; if (this.runtimeCheckingLevel < 3 && contract.RequiresCount == 0) continue; if (this.addInterfaceWrappersWhenNeeded) { AddInterfaceImplementationWrapper(Class, intfMethod, baseMethod); } else { this.HandleError(new Warning(1080, string.Format( "Type {0} implements {1} by inheriting {2} causing the interface contract to not be checked at runtime. Consider adding a wrapper method.", Class.FullName, intfMethod.FullName, baseMethod.FullName), default(SourceContext))); } } }
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"); }
private static Method FindInheritedMethod(Class baseClass, Method interfaceMethod) { while (baseClass != null) { if (InterfaceListContains(baseClass.Interfaces, interfaceMethod.DeclaringType)) { // instrumented in base return null; } var candidate = baseClass.GetExactMatchingMethod(interfaceMethod); if (candidate != null) return candidate; baseClass = baseClass.BaseClass; } return null; }
/// <summary> /// Extracts contracts from a class into the appropriate fields in the CCI tree. /// </summary> /// <param name="Class">Class to visit.</param> /// <returns>The same class but with contracts extracted.</returns> public override Class VisitClass(Class Class) { // Special processing for classes that are holding the contract for an interface or abstract class var originalType = HelperMethods.IsContractTypeForSomeOtherTypeUnspecialized(Class, this.contractNodes); var originalScrubber = this.currentScrubber; if (originalType != null) { this.currentScrubber = new ScrubContractClass(this, Class, originalType); } try { return base.VisitClass(Class); } finally { this.currentScrubber = originalScrubber; } }
private static bool IsSystemObject(Class Class) { return Class.Name.Matches(StandardIds.CapitalObject) && Class.Namespace.Matches(StandardIds.System); }
public static bool IsContractTypeForSomeOtherType(Class Class) { if (Class == null) return false; if (Class.Attributes == null) return false; for (int i = 0; i < Class.Attributes.Count; i++) { var attr = Class.Attributes[i]; if (attr == null) continue; if (attr.Type == null) continue; if (attr.Type.Name == null) continue; if (attr.Type.Name.Name == "ContractClassForAttribute") return true; } return false; }