public CodeTypeRef StripGenerics(CodeTypeRef member) { try { if (member.AsFullName.Contains("<") == false) { return(member); //No need to attempt to guess, this is not a generic class } //todo check if we need to cast to CodeTypeRef2 here var codeTypeRef2 = member as CodeTypeRef2; if (codeTypeRef2 == null || !codeTypeRef2.IsGeneric) { return(member); } var typeNameAsInCode = DTEHelper.RemoveTaskFromString(codeTypeRef2.AsFullName); typeNameAsInCode = DTEHelper.RemoveNullableStr(typeNameAsInCode); try { CodeModel projCodeModel = ((CodeElement)member.Parent).ProjectItem.ContainingProject.CodeModel; if (projCodeModel == null) { return(member); } var codeType = projCodeModel.CodeTypeFromFullName(typeNameAsInCode); if (codeType != null) { return(projCodeModel.CreateCodeTypeRef(codeType)); } return(member); } catch (COMException ex) { var found = CheckForTypeInOtherPlaces(typeNameAsInCode); if (found != null) { return(found); } } if (member.AsFullName.Contains("Task<")) { return(null); //we failed, might as well throw error } return(member); } catch (Exception ex) { return(member); } }
public CodeTypeRef TryToGuessGenericArgument(CodeTypeRef member) { try { if (member.AsFullName.Contains("<") == false) { return(member); //No need to attempt to guess, this is not a generic class } //todo check if we need to cast to CodeTypeRef2 here var codeTypeRef2 = member as CodeTypeRef2; if (codeTypeRef2 == null || !codeTypeRef2.IsGeneric) { return(member); } // There is no way to extract generic parameter as CodeTypeRef or something similar // (see http://social.msdn.microsoft.com/Forums/vstudio/en-US/09504bdc-2b81-405a-a2f7-158fb721ee90/envdte-envdte80-codetyperef2-and-generic-types?forum=vsx) // but we can make it work at least for some simple case with the following heuristic: // 1) get the argument's local name by parsing the type reference's full text // 2) if it's a known primitive (i.e. string, int, etc.), return that // 3) otherwise, guess that it's a type from the same namespace and same project, // and use the project CodeModel to retrieve it by full name // 4) if CodeModel returns null - well, bad luck, don't have any more guesses var typeNameAsInCode = DTEHelper.RemoveTaskFromString(codeTypeRef2.AsFullName); // var typeNameAsInCode = codeTypeRef2.AsString.Replace("?", ""); //typeNameAsInCode = typeNameAsInCode.Split('<', '>').ElementAtOrDefault(1) ?? ""; typeNameAsInCode = typeNameAsInCode.Split('<', '>').ElementAtOrDefault(1) ?? typeNameAsInCode; try { CodeModel projCodeModel = ((CodeElement)member.Parent).ProjectItem.ContainingProject.CodeModel; if (projCodeModel == null) { return(member); } var codeType = projCodeModel.CodeTypeFromFullName(typeNameAsInCode); if (codeType != null) { return(projCodeModel.CreateCodeTypeRef(codeType)); } return(member); } catch (COMException ex) { var found = CheckForTypeInOtherPlaces(typeNameAsInCode); if (found != null) { return(found); } } if (member.AsFullName.Contains("Task<")) { return(null); //we failed, might as well throw error } if (member.AsFullName.Contains("List<")) { return(null); //we failed, might as well throw error } return(member); } catch (Exception ex) { return(member); } }