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 static bool TypesAreEquivalent(ITypeSymbol type1, ITypeSymbol type2) { if (type1 == null && type2 == null) { return(true); } if (type1 == null) { return(false); } if (type2 == null) { return(false); } #region Check if type parameter if ((type1.TypeKind == TypeKind.TypeParameter) != (type2.TypeKind == TypeKind.TypeParameter)) { return(false); } if (type1.TypeKind == TypeKind.TypeParameter) { ITypeParameterSymbol typeParameter1 = (ITypeParameterSymbol)type1; ITypeParameterSymbol typeParameter2 = (ITypeParameterSymbol)type2; if (typeParameter1.HasReferenceTypeConstraint ^ typeParameter2.HasReferenceTypeConstraint) { return(false); } if (typeParameter1.HasValueTypeConstraint ^ typeParameter2.HasValueTypeConstraint) { return(false); } return(true); } #endregion //return type1.Equals(type2); //TODO: Can we use this? Doesn't seem to work for generic types like 'List<J>' #region Check name //if (type1.Name == null) throw new IllFormedSemanticModelException("A CSharpType was founded with a null 'Name' field.", type1); //if (type2.Name == null) throw new IllFormedSemanticModelException("A CSharpType was founded with a null 'Name' field.", type2); //It seems array types always have null names if (type1.Name != null ^ type2.Name != null) { return(false); } if (type1.Name != null && type2.Name != null && !type1.Name.Equals(type2.Name)) { return(false); } #endregion #region Check containing type and namespace if (type1.ContainingType != null ^ type2.ContainingType != null) { return(false); } if (type1.ContainingType != null && type2.ContainingType != null) { if (!TypesAreEquivalent(type1.ContainingType, type2.ContainingType)) { return(false); } } else { if (type1.ContainingNamespace != null ^ type2.ContainingNamespace != null) { return(false); } if (type1.ContainingNamespace != null && type2.ContainingNamespace != null && !type1.ContainingNamespace.Equals(type2.ContainingNamespace)) { return(false); } } #endregion #region Check type parameters if (!type1.TypeParameters().IsDefault ^ !type2.TypeParameters().IsDefault) { return(false); } if (!type1.TypeParameters().IsDefault&& !type2.TypeParameters().IsDefault&& type1.TypeParameters().Length != type2.TypeParameters().Length) { return(false); } #endregion #region Check type arguments if (!type1.TypeArguments().IsDefault ^ !type2.TypeArguments().IsDefault) { return(false); } if (!type1.TypeArguments().IsDefault&& !type2.TypeArguments().IsDefault&& !TypeListsAreEquivalent(type1.TypeArguments(), type2.TypeArguments())) { return(false); } #endregion #region Check array if ((type1.TypeKind == TypeKind.Array) ^ (type2.TypeKind == TypeKind.Array)) { return(false); } if ((type1.TypeKind == TypeKind.Array) && (type2.TypeKind == TypeKind.Array)) { return(TypesAreEquivalent(type1.ElementType(), type2.ElementType())); } #endregion #region Check pointer if ((type1.TypeKind == TypeKind.Pointer) ^ (type2.TypeKind == TypeKind.Pointer)) { return(false); } if ((type1.TypeKind == TypeKind.Pointer) && (type2.TypeKind == TypeKind.Pointer)) { return(TypesAreEquivalent(type1.ElementType(), type2.ElementType())); } #endregion if ((type1.TypeKind == TypeKind.Class) != (type2.TypeKind == TypeKind.Class) || (type1.TypeKind == TypeKind.Struct) != (type2.TypeKind == TypeKind.Struct) || type1.IsStatic != type2.IsStatic || type1.IsValueType != type2.IsValueType) { return(false); } return(true); }
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 }