static bool TryGetIheritedFromMember(CSharpMember semanticMember, TypeDeclarationNode syntacticParentType, out CSharpMember inheritedFromMember) { Contract.Requires(semanticMember != null); Contract.Requires(semanticMember.IsMethod); Contract.Ensures(!Contract.Result <bool>() || Contract.ValueAtReturn(out inheritedFromMember) != null && Contract.ValueAtReturn(out inheritedFromMember).IsMethod); inheritedFromMember = null; #region If member is from struct, ignore it if (semanticMember.ContainingType.IsValueType || semanticMember.ContainingType.IsStruct) { ContractsPackageAccessor.Current.Logger.WriteToLog("Member is struct or value type, skipping member..."); return(false); } #endregion #region If member is from a contract class, ignore it //TODO: Get proper attributes from semantic model! Bug in semantic model, custom attributes don't seem to work right. bool ignoreIt = false; var containingType = semanticMember.ContainingType; if (containingType.IsClass) { if (syntacticParentType != null) { foreach (var attributeSection in syntacticParentType.Attributes) { foreach (var attribute in attributeSection.AttributeList) { var attributeName = attribute.AttributeName as IdentifierNode; if (attributeName != null) { if (attributeName.Name.Text.Contains("ContractClassFor")) { ignoreIt = true; } } } } } } if (ignoreIt) { ContractsPackageAccessor.Current.Logger.WriteToLog("Member has 'ContractClassForAttribute', skipping member..."); return(false); } #endregion // If member is override, get base member if (semanticMember.IsOverride) { if (!CSharpToCCIHelper.TryGetBaseMember(semanticMember, out inheritedFromMember)) { ContractsPackageAccessor.Current.Logger.WriteToLog("Member is an override but we can't get its base member, skipping member..."); return(false); //If we can't get the base member, we don't want to keep going with this member. } } else if (semanticMember.ContainingType.IsInterface || semanticMember.IsAbstract) { inheritedFromMember = semanticMember; } #region Else member implements an interface or it doesn't have inherited contracts, get interface member else { if (!CSharpToCCIHelper.TryGetInterfaceMember(semanticMember, out inheritedFromMember)) { ContractsPackageAccessor.Current.Logger.WriteToLog("Member isn't override, abstract, in an interface or an interface member, skipping member..."); return(false); //If we can't get the interface member, we don't want to keep going with this member. } } #endregion return(inheritedFromMember != null); }
public bool TryGetPropertyAccessorReferences(CSharpMember semanticProperty, out IMethodReference getter, out IMethodReference setter) { Contract.Requires(semanticProperty == null || semanticProperty.IsProperty || semanticProperty.IsIndexer); getter = setter = null; #region Check input if (semanticProperty == null) { return(false); } #endregion #region Check cache Tuple <IMethodReference, IMethodReference> cacheOutput; if (_semanticPropertiesToCCIAccessorMethods.TryGetValue(semanticProperty, out cacheOutput)) { Contract.Assume(cacheOutput != null, "Non-null only dictionary"); getter = cacheOutput.Item1; setter = cacheOutput.Item2; return((getter != null && getter != Dummy.MethodReference) || (setter != null && setter != Dummy.MethodReference)); } #endregion #region Get calling conventions var callingConventions = CSharpToCCIHelper.GetCallingConventionFor(semanticProperty); #endregion #region get containing type ITypeReference containingType; if (!TryGetTypeReference(semanticProperty.ContainingType, out containingType)) { goto ReturnFalse; } #endregion #region Get return type ITypeReference returnType; if (!TryGetTypeReference(semanticProperty.ReturnType, out returnType)) { goto ReturnFalse; } #endregion #region Get the property's name string propertyName; if (semanticProperty.IsIndexer) { propertyName = "Item"; } else { if (semanticProperty.Name == null) { goto ReturnFalse; } propertyName = semanticProperty.Name.Text; } #endregion #region Get the parameters List <IParameterTypeInformation> getterParams; if (semanticProperty.Parameters != null) { if (!TryGetParametersList(semanticProperty.Parameters, out getterParams)) { goto ReturnFalse; } } else { getterParams = new List <IParameterTypeInformation>(); } List <IParameterTypeInformation> setterParams; if (semanticProperty.Parameters != null) { if (!TryGetParametersList(semanticProperty.Parameters, out setterParams, 1)) { goto ReturnFalse; } #region Append the "value" param var valParam = new Microsoft.Cci.MutableCodeModel.ParameterTypeInformation() { Type = returnType, Index = 0, IsByReference = false }; setterParams.Insert(0, valParam); #endregion } else { setterParams = new List <IParameterTypeInformation>(); } #endregion #region Build the getter getter = new Microsoft.Cci.MutableCodeModel.MethodReference() { InternFactory = Host.InternFactory, CallingConvention = callingConventions, ContainingType = containingType, Type = returnType, Name = Host.NameTable.GetNameFor("get_" + propertyName), GenericParameterCount = 0, Parameters = getterParams }; #endregion #region Build the setter setter = new Microsoft.Cci.MutableCodeModel.MethodReference() { InternFactory = Host.InternFactory, CallingConvention = callingConventions, ContainingType = containingType, Type = Host.PlatformType.SystemVoid, Name = Host.NameTable.GetNameFor("set_" + propertyName), GenericParameterCount = 0, Parameters = setterParams }; #endregion #region Get the assembly reference (this also ensures the assembly gets loaded properly) IAssemblyReference assemblyReference; TryGetAssemblyReference(semanticProperty.Assembly, out assemblyReference); #endregion #region ReturnTrue: //ReturnTrue: _semanticPropertiesToCCIAccessorMethods[semanticProperty] = new Tuple <IMethodReference, IMethodReference>(getter, setter); return(true); #endregion #region ReturnFalse: ReturnFalse: if (semanticProperty.Name != null) { ContractsPackageAccessor.Current.Logger.WriteToLog("Failed to build accessor references for: " + semanticProperty.Name.Text); } _semanticPropertiesToCCIAccessorMethods[semanticProperty] = new Tuple <IMethodReference, IMethodReference>(Dummy.MethodReference, Dummy.MethodReference); return(false); #endregion }
public bool TryGetTypeReference(CSharpType semanticType, IAssemblyReference cciAssembly, out ITypeReference cciType) { Contract.Ensures(!Contract.Result <bool>() || (Contract.ValueAtReturn(out cciType) != null)); cciType = null; #region Check input if (semanticType == null || cciAssembly == null) { return(false); } #endregion #region Check cache if (ContractsPackageAccessor.Current.VSOptionsPage.Caching) { if (_semanticTypesToCCITypes.TryGetValue(semanticType, out cciType)) { return(cciType != null && cciType != Dummy.TypeReference); } } #endregion #region If generic if (semanticType.TypeArguments != null && semanticType.TypeArguments.Count > 0) { var genericArguments = new List <ITypeReference>(); foreach (var semanticTypeArg in semanticType.TypeArguments) { if (semanticTypeArg == null) { goto ReturnFalse; } ITypeReference cciTypeArg = null; if (TryGetTypeReference(semanticTypeArg, out cciTypeArg)) { genericArguments.Add(cciTypeArg); } else { goto ReturnFalse; } } ITypeReference genericType = null; if (!TryGetTypeReference(semanticType.DefiningType, out genericType)) { goto ReturnFalse; } cciType = new Microsoft.Cci.MutableCodeModel.GenericTypeInstanceReference() { InternFactory = this.Host.InternFactory, GenericArguments = genericArguments, GenericType = (INamedTypeReference)genericType, }; goto ReturnTrue; } #endregion #region If array if (semanticType.IsArray) { ITypeReference eleType; if (!TryGetTypeReference(semanticType.ElementType, out eleType)) { goto ReturnFalse; } if (semanticType.ElementType.IsArray) { Contract.Assume(semanticType.Rank > 0); cciType = new Microsoft.Cci.MutableCodeModel.MatrixTypeReference() { ElementType = eleType, InternFactory = this.Host.InternFactory, Rank = (uint)semanticType.Rank }; goto ReturnTrue; } else { cciType = new Microsoft.Cci.MutableCodeModel.VectorTypeReference() { ElementType = eleType, InternFactory = this.Host.InternFactory, }; goto ReturnTrue; } } #endregion #region If type parameter if (semanticType.IsTypeParameter) { if (semanticType.DefiningMember != null) { cciType = new Microsoft.Cci.MutableCodeModel.GenericMethodParameterReference() { Index = (ushort)(semanticType.DefiningMember.TypeParameters != null? semanticType.DefiningMember.TypeParameters.IndexOf(semanticType) : 0), InternFactory = this.Host.InternFactory, Name = Host.NameTable.GetNameFor(semanticType.Name != null ? semanticType.Name.Text : "T"), }; goto ReturnTrue; } else if (semanticType.DefiningType != null) { ITypeReference cciDefiningType; if (!TryGetTypeReference(semanticType.DefiningType, out cciDefiningType)) { goto ReturnFalse; } cciType = new Microsoft.Cci.MutableCodeModel.GenericTypeParameterReference() { DefiningType = cciDefiningType, Index = (ushort)(semanticType.DefiningType.TypeParameters != null ? semanticType.DefiningType.TypeParameters.IndexOf(semanticType) : 0), InternFactory = this.Host.InternFactory, Name = Host.NameTable.GetNameFor(semanticType.Name != null ? semanticType.Name.Text : "T"), }; goto ReturnTrue; } } #endregion #region If namespace type if (semanticType.ContainingType == null) { IUnitNamespaceReference cciNamespace; var namespaceName = semanticType.ContainingNamespace; if (namespaceName == null || !TryGetNamespaceReference(namespaceName, cciAssembly, out cciNamespace)) { cciNamespace = new Microsoft.Cci.MutableCodeModel.RootUnitNamespaceReference() { Unit = cciAssembly }; } if (semanticType.ContainingType == null) { if (semanticType.Name == null || semanticType.Name.Text == null) { goto ReturnFalse; } cciType = new Microsoft.Cci.MutableCodeModel.NamespaceTypeReference() { ContainingUnitNamespace = cciNamespace, GenericParameterCount = (ushort)(semanticType.TypeParameters == null ? 0 : semanticType.TypeParameters.Count), InternFactory = Host.InternFactory, IsValueType = semanticType.IsValueType, IsEnum = semanticType.IsEnum, Name = Host.NameTable.GetNameFor(semanticType.Name.Text), TypeCode = CSharpToCCIHelper.GetPrimitiveTypeCode(semanticType), }; goto ReturnTrue; } } #endregion #region If nested type if (semanticType.ContainingType != null) { ITypeReference containingType; if (!TryGetTypeReference(semanticType.ContainingType, cciAssembly, out containingType)) { goto ReturnFalse; } if (semanticType.Name == null || semanticType.Name.Text == null) { goto ReturnFalse; } cciType = new Microsoft.Cci.MutableCodeModel.NestedTypeReference() { ContainingType = containingType, GenericParameterCount = (ushort)(semanticType.TypeParameters == null ? 0 : semanticType.TypeParameters.Count), InternFactory = this.Host.InternFactory, MangleName = true, Name = Host.NameTable.GetNameFor(semanticType.Name.Text) }; goto ReturnTrue; } #endregion #region ReturnTrue: ReturnTrue: if (ContractsPackageAccessor.Current.VSOptionsPage.Caching) { _semanticTypesToCCITypes[semanticType] = cciType; } return(true); #endregion #region ReturnFalse: ReturnFalse: ContractsPackageAccessor.Current.Logger.WriteToLog("Failed to build type reference for: " + (semanticType.Name != null ? semanticType.Name.Text : semanticType.ToString())); if (ContractsPackageAccessor.Current.VSOptionsPage.Caching) { _semanticTypesToCCITypes[semanticType] = Dummy.TypeReference; } return(false); #endregion }
public bool TryGetMethodReference(CSharpMember semanticMethod, out IMethodReference cciMethod) { Contract.Requires(semanticMethod == null || semanticMethod.IsConstructor || semanticMethod.IsMethod); Contract.Ensures(!Contract.Result <bool>() || Contract.ValueAtReturn(out cciMethod) != null); cciMethod = null; #region Check input if (semanticMethod == null) { return(false); } #endregion #region Check cache if (ContractsPackageAccessor.Current.VSOptionsPage.Caching) { if (_semanticMembersToCCIMethods.TryGetValue(semanticMethod, out cciMethod)) { return((!(cciMethod is Dummy)) && cciMethod != null); } } #endregion #region Set up our working cci method var workingCciMethod = new Microsoft.Cci.MutableCodeModel.MethodReference(); #endregion #region Set the intern factory workingCciMethod.InternFactory = Host.InternFactory; #endregion #region Get calling conventions workingCciMethod.CallingConvention = CSharpToCCIHelper.GetCallingConventionFor(semanticMethod); #endregion #region Get containing type reference ITypeReference containingType; if (!TryGetTypeReference(semanticMethod.ContainingType, out containingType)) { goto ReturnFalse; } workingCciMethod.ContainingType = containingType; #endregion #region Get return type reference if (semanticMethod.IsConstructor) { workingCciMethod.Type = this.Host.PlatformType.SystemVoid; } else { ITypeReference returnType; if (!TryGetTypeReference(semanticMethod.ReturnType, out returnType)) { goto ReturnFalse; } workingCciMethod.Type = returnType; } #endregion #region Get name if (!semanticMethod.IsConstructor && semanticMethod.Name == null) { goto ReturnFalse; } workingCciMethod.Name = Host.NameTable.GetNameFor(semanticMethod.IsConstructor?".ctor":semanticMethod.Name.Text); #endregion #region Get generic param count if (semanticMethod.TypeParameters == null) { workingCciMethod.GenericParameterCount = 0; } else { workingCciMethod.GenericParameterCount = (ushort)semanticMethod.TypeParameters.Count; } #endregion #region Get parameter references List <IParameterTypeInformation> cciParameters; if (semanticMethod.Parameters == null) { goto ReturnFalse; } Contract.Assume(semanticMethod.Parameters.Count <= ushort.MaxValue, "Should be a postcondition?"); if (!TryGetParametersList(semanticMethod.Parameters, out cciParameters)) { goto ReturnFalse; } workingCciMethod.Parameters = cciParameters; #endregion #region Get the assembly reference (this also ensures the assembly gets loaded properly) IAssemblyReference assemblyReference; TryGetAssemblyReference(semanticMethod.Assembly, out assemblyReference); #endregion cciMethod = workingCciMethod; return(true); #region ReturnFalse: ReturnFalse: cciMethod = Dummy.MethodReference; if (ContractsPackageAccessor.Current.VSOptionsPage.Caching) { _semanticMembersToCCIMethods[semanticMethod] = cciMethod; } return(false); #endregion }