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 TryGetNamespaceReference(INamespaceSymbol semanticNamespace, IAssemblyReference cciAssembly, out IUnitNamespaceReference cciNamespace) { Contract.Ensures(!Contract.Result<bool>() || (Contract.ValueAtReturn(out cciNamespace) != null)); cciNamespace = null; #region Check input if (semanticNamespace == null || cciAssembly == null) { return false; } #endregion #region If root try { if (semanticNamespace.IsGlobalNamespace) { cciNamespace = new Microsoft.Cci.MutableCodeModel.RootUnitNamespaceReference() { Unit = cciAssembly }; goto ReturnTrue; } } catch (InvalidOperationException e) { //For some reason, an InvalidOperationException may get thrown. if (e.Message.Contains(ContractsPackageAccessor.InvalidOperationExceptionMessage_TheSnapshotIsOutOfDate)) goto ReturnFalse; else throw e; } #endregion #region If nested if (semanticNamespace.ContainingNamespace != null) { IUnitNamespaceReference parentNs; if (!TryGetNamespaceReference(semanticNamespace.ContainingNamespace, cciAssembly, out parentNs)) goto ReturnFalse; if (semanticNamespace.Name == null) goto ReturnFalse; cciNamespace = new Microsoft.Cci.Immutable.NestedUnitNamespaceReference(parentNs, Host.NameTable.GetNameFor(semanticNamespace.Name)); goto ReturnTrue; } #endregion Contract.Assert(cciNamespace == null); goto ReturnFalse; #region ReturnTrue: ReturnTrue: return true; #endregion #region ReturnFalse: ReturnFalse: return false; #endregion }