private void TryPortMissingTypeParamsForMember(DocsMember dMemberToUpdate, TripleSlashMember?tsMemberToPort, DocsMember?interfacedMember) { if (tsMemberToPort != null) { foreach (TripleSlashTypeParam tsTypeParam in tsMemberToPort.TypeParams) { bool isEII = false; string name = string.Empty; string value = string.Empty; DocsTypeParam dTypeParam = dMemberToUpdate.TypeParams.FirstOrDefault(x => x.Name == tsTypeParam.Name); bool created = false; if (dTypeParam == null) { ProblematicAPIs.AddIfNotExists($"TypeParam=[{tsTypeParam.Name}] in Member=[{dMemberToUpdate.DocId}]"); dTypeParam = dMemberToUpdate.AddTypeParam(tsTypeParam.Name, XmlHelper.GetNodesInPlainText(tsTypeParam.XETypeParam)); created = true; } // But it can still be empty, try to retrieve it if (IsEmpty(dTypeParam.Value)) { // try to port triple slash comments if (!IsEmpty(tsTypeParam.Value)) { name = tsTypeParam.Name; value = tsTypeParam.Value; } // or try to find if it implements a documented interface else if (interfacedMember != null) { DocsTypeParam interfacedTypeParam = interfacedMember.TypeParams.FirstOrDefault(x => x.Name == dTypeParam.Name); if (interfacedTypeParam != null) { name = interfacedTypeParam.Name; value = interfacedTypeParam.Value; isEII = true; } } } if (!IsEmpty(value)) { dTypeParam.Value = value; string message = $"MEMBER {GetIsEII(isEII)} TYPEPARAM ({GetIsCreated(created)})"; PrintModifiedMember(message, dTypeParam.ParentAPI.FilePath, dMemberToUpdate.DocId); TotalModifiedIndividualElements++; } } } }
private static bool TryPortMissingCommentsForMember(TripleSlashMember tsMember, DocsMember dMember) { bool modified = false; if (!IsEmpty(tsMember.Summary) && IsEmpty(dMember.Summary)) { // Any member can have an empty summary PrintModifiedMember("MEMBER SUMMARY", dMember.FilePath, tsMember.Name, dMember.DocId, tsMember.Summary, dMember.Summary); dMember.Summary = tsMember.Summary; TotalModifiedIndividualElements++; modified = true; } if (!IsEmpty(tsMember.Remarks) && IsEmpty(dMember.Remarks)) { // Any member can have an empty remark PrintModifiedMember("MEMBER REMARKS", dMember.FilePath, tsMember.Name, dMember.DocId, tsMember.Remarks, dMember.Remarks); dMember.Remarks = tsMember.Remarks; TotalModifiedIndividualElements++; modified = true; } // Properties and method returns save their values in different locations if (dMember.MemberType == "Property") { if (!IsEmpty(tsMember.Returns) && IsEmpty(dMember.Value)) { PrintModifiedMember("PROPERTY", dMember.FilePath, tsMember.Name, dMember.DocId, tsMember.Returns, dMember.Value); dMember.Value = tsMember.Returns; TotalModifiedIndividualElements++; modified = true; } } else if (dMember.MemberType == "Method") { if (!IsEmpty(tsMember.Returns) && IsEmpty(dMember.Returns)) { if (tsMember.Returns != null && dMember.ReturnType == "System.Void") { ProblematicAPIs.AddIfNotExists($"Returns=[{tsMember.Returns}] in Method=[{dMember.DocId}]"); } else { PrintModifiedMember("METHOD RETURN", dMember.FilePath, tsMember.Name, dMember.DocId, tsMember.Returns, dMember.Returns); dMember.Returns = tsMember.Returns; TotalModifiedIndividualElements++; modified = true; } } } // Triple slash params may cause errors if they are missing in the code side foreach (TripleSlashParam tsParam in tsMember.Params) { DocsParam dParam = dMember.Params.FirstOrDefault(x => x.Name == tsParam.Name); bool created = false; if (dParam == null) { ProblematicAPIs.AddIfNotExists($"Param=[{tsParam.Name}] in Member DocId=[{dMember.DocId}]"); created = TryPromptParam(tsParam, dMember, out dParam); } if (created || (!IsEmpty(tsParam.Value) && IsEmpty(dParam.Value))) { PrintModifiedMember(string.Format("PARAM ({0})", created ? "CREATED" : "MODIFIED"), dParam.FilePath, tsParam.Name, dParam.Name, tsParam.Value, dParam.Value); if (!created) { dParam.Value = tsParam.Value; } TotalModifiedIndividualElements++; modified = true; } } // Exceptions are a special case: If a new one is found in code, but does not exist in docs, the whole element needs to be added foreach (TripleSlashException tsException in tsMember.Exceptions) { DocsException dException = dMember.Exceptions.FirstOrDefault(x => x.Cref.EndsWith(tsException.Cref)); bool created = false; if (dException == null) { dException = dMember.SaveException(tsException.XEException); AddedExceptions.AddIfNotExists($"{dException.Cref} in {dMember.DocId}"); created = true; } if (created || (!IsEmpty(tsException.Value) && IsEmpty(dException.Value))) { PrintModifiedMember(string.Format("EXCEPTION ({0})", created ? "CREATED" : "MODIFIED"), dException.FilePath, tsException.Cref, dException.Cref, tsException.Value, dException.Value); if (!created) { dException.Value = tsException.Value; } TotalModifiedIndividualElements++; modified = true; } } foreach (TripleSlashTypeParam tsTypeParam in tsMember.TypeParams) { DocsTypeParam dTypeParam = dMember.TypeParams.FirstOrDefault(x => x.Name == tsTypeParam.Name); bool created = false; if (dTypeParam == null) { ProblematicAPIs.AddIfNotExists($"TypeParam=[{tsTypeParam.Name}] in Member=[{dMember.DocId}]"); dTypeParam = dMember.SaveTypeParam(tsTypeParam.XETypeParam); created = true; } if (created || (!IsEmpty(tsTypeParam.Value) && IsEmpty(dTypeParam.Value))) { PrintModifiedMember(string.Format("TYPE PARAM ({0})", created ? "CREATED" : "MODIFIED"), dTypeParam.FilePath, tsTypeParam.Name, dTypeParam.Name, tsTypeParam.Value, dTypeParam.Value); if (!created) { dTypeParam.Value = tsTypeParam.Value; } TotalModifiedIndividualElements++; modified = true; } } if (modified) { ModifiedAPIs.AddIfNotExists(dMember.DocId); } return(modified); }