public bool TryGetTypeReference(ITypeSymbol 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().IsDefault && semanticType.TypeArguments().Length > 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.TypeKind == TypeKind.Array) { ITypeReference eleType; if (!TryGetTypeReference(semanticType.ElementType(), out eleType)) goto ReturnFalse; if (semanticType.ElementType().TypeKind == TypeKind.Array) { Contract.Assume(((IArrayTypeSymbol)semanticType).Rank > 0); cciType = new Microsoft.Cci.MutableCodeModel.MatrixTypeReference() { ElementType = eleType, InternFactory = this.Host.InternFactory, Rank = (uint)((IArrayTypeSymbol)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.TypeKind == TypeKind.TypeParameter) { if (semanticType.DefiningMember() != null) { cciType = new Microsoft.Cci.MutableCodeModel.GenericMethodParameterReference() { Index = (ushort)(!semanticType.DefiningMember().TypeParameters().IsDefault ? semanticType.DefiningMember().TypeParameters().IndexOf((ITypeParameterSymbol)semanticType) : 0), InternFactory = this.Host.InternFactory, Name = Host.NameTable.GetNameFor(semanticType.Name != null ? semanticType.Name : "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().IsDefaultOrEmpty ? semanticType.DefiningType().TypeParameters().IndexOf((ITypeParameterSymbol)semanticType) : 0), InternFactory = this.Host.InternFactory, Name = Host.NameTable.GetNameFor(semanticType.Name != null ? semanticType.Name : "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 == null) goto ReturnFalse; cciType = new Microsoft.Cci.MutableCodeModel.NamespaceTypeReference() { ContainingUnitNamespace = cciNamespace, GenericParameterCount = (ushort) (semanticType.TypeParameters().IsDefault ? 0 : semanticType.TypeParameters().Length), InternFactory = Host.InternFactory, IsValueType = semanticType.IsValueType, IsEnum = semanticType.TypeKind == TypeKind.Enum, Name = Host.NameTable.GetNameFor(semanticType.Name), 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 == null) goto ReturnFalse; cciType = new Microsoft.Cci.MutableCodeModel.NestedTypeReference() { ContainingType = containingType, GenericParameterCount = (ushort)(semanticType.TypeParameters().IsDefault ? 0 : semanticType.TypeParameters().Length), InternFactory = this.Host.InternFactory, MangleName = true, Name = Host.NameTable.GetNameFor(semanticType.Name) }; 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 : semanticType.ToString())); if (ContractsPackageAccessor.Current.VSOptionsPage.Caching) _semanticTypesToCCITypes[semanticType] = Dummy.TypeReference; 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 }