From 57d604f2a0fb85d109bade7cc60bf8f317a8f9f0 Mon Sep 17 00:00:00 2001 From: Austin Henriksen Date: Mon, 11 Nov 2024 14:49:51 -0500 Subject: [PATCH] Fix Bugs in Swift Doc-Comment Generation (#3122) --- cpp/src/Slice/Parser.cpp | 4 +- cpp/src/slice2swift/Gen.cpp | 144 ++++++++--------- cpp/src/slice2swift/SwiftUtil.cpp | 248 ++++++++++++++---------------- cpp/src/slice2swift/SwiftUtil.h | 1 - slice/Ice/RemoteLogger.ice | 2 +- 5 files changed, 187 insertions(+), 212 deletions(-) diff --git a/cpp/src/Slice/Parser.cpp b/cpp/src/Slice/Parser.cpp index 87bc8cc4b9a..1c48f5f272b 100644 --- a/cpp/src/Slice/Parser.cpp +++ b/cpp/src/Slice/Parser.cpp @@ -659,7 +659,7 @@ namespace // Fix any link tags using the provided link formatter. const string link = "{@link "; - pos = comment.find(link, pos); + pos = comment.find(link); while (pos != string::npos) { string::size_type endpos = comment.find('}', pos); @@ -667,7 +667,7 @@ namespace { // Extract the linked to identifier. string::size_type identStart = comment.find_first_not_of(" \t", pos + link.size()); - string::size_type identEnd = comment.find_last_not_of(" \t", endpos) + 1; + string::size_type identEnd = comment.find_last_not_of(" \t", endpos); string ident = comment.substr(identStart, identEnd - identStart); // Then erase the entire '{@link foo}' tag from the comment. diff --git a/cpp/src/slice2swift/Gen.cpp b/cpp/src/slice2swift/Gen.cpp index e4cbddd67f8..ed6d82fde31 100644 --- a/cpp/src/slice2swift/Gen.cpp +++ b/cpp/src/slice2swift/Gen.cpp @@ -317,8 +317,7 @@ Gen::TypesVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p) ids << "]"; out << sp; - out << nl << "/// Traits for Slice interface"; - out << '`' << name << "`."; + out << nl << "/// Traits for Slice interface `" << name << "`."; out << nl << "public struct " << traits << ": " << getUnqualified("Ice.SliceTraits", swiftModule); out << sb; out << nl << "public static let staticIds = " << ids.str(); @@ -408,9 +407,7 @@ Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) // else inherit UserException's initializer. out << sp; - out << nl << "/// Returns the Slice type ID of this exception."; - out << nl << "///"; - out << nl << "/// - returns: `Swift.String` - the Slice type ID of this exception."; + out << nl << "/// - Returns: The Slice type ID of this exception."; out << nl << "open override class func ice_staticId() -> Swift.String { \"" << p->scoped() << "\" }"; out << sp; @@ -514,7 +511,7 @@ Gen::TypesVisitor::visitStructStart(const StructPtr& p) out << sp; out << nl << "/// Read a `" << name << "` structured value from the stream."; out << nl << "///"; - out << nl << "/// - returns: `" << name << "` - The structured value read from the stream."; + out << nl << "/// - Returns: The structured value read from the stream."; out << nl << "func read() throws -> " << name; out << sb; out << nl << (usesClasses ? "let" : "var") << " v = " << name << "()"; @@ -528,9 +525,9 @@ Gen::TypesVisitor::visitStructStart(const StructPtr& p) out << sp; out << nl << "/// Read an optional `" << name << "?` structured value from the stream."; out << nl << "///"; - out << nl << "/// - parameter tag: `Swift.Int32` - The numeric tag associated with the value."; + out << nl << "/// - Parameter tag: The numeric tag associated with the value."; out << nl << "///"; - out << nl << "/// - returns: `" << name << "?` - The structured value read from the stream."; + out << nl << "/// - Returns: The structured value read from the stream."; out << nl << "func read(tag: Swift.Int32) throws -> " << name << "?"; out << sb; out << nl << "guard try readOptional(tag: tag, expectedFormat: " << optionalFormat << ") else"; @@ -557,7 +554,7 @@ Gen::TypesVisitor::visitStructStart(const StructPtr& p) out << nl << "/// Write a `" << name << "` structured value to the stream."; out << nl << "///"; - out << nl << "/// - parameter _: `" << name << "` - The value to write to the stream."; + out << nl << "/// - Parameter v: The value to write to the stream."; out << nl << "func write(_ v: " << name << ")" << sb; for (const auto& member : members) { @@ -568,9 +565,8 @@ Gen::TypesVisitor::visitStructStart(const StructPtr& p) out << sp; out << nl << "/// Write an optional `" << name << "?` structured value to the stream."; out << nl << "///"; - out << nl << "/// - parameter tag: `Swift.Int32` - The numeric tag associated with the value."; - out << nl << "///"; - out << nl << "/// - parameter value: `" << name << "?` - The value to write to the stream."; + out << nl << "/// - Parameter tag: The numeric tag associated with the value."; + out << nl << "/// - Parameter value: The value to write to the stream."; out << nl << "func write(tag: Swift.Int32, value: " << name << "?)" << sb; out << nl << "if let v = value" << sb; out << nl << "if writeOptional(tag: tag, format: " << optionalFormat << ")" << sb; @@ -635,9 +631,9 @@ Gen::TypesVisitor::visitSequence(const SequencePtr& p) out << nl << "/// Read a `" << fixIdent(name) << "` sequence from the stream."; out << nl << "///"; - out << nl << "/// - parameter istr: `Ice.InputStream` - The stream to read from."; + out << nl << "/// - Parameter istr: The stream to read from."; out << nl << "///"; - out << nl << "/// - returns: `" << fixIdent(name) << "` - The sequence read from the stream."; + out << nl << "/// - Returns: The sequence read from the stream."; out << nl << "public static func read(from istr: " << istr << ") throws -> " << fixIdent(name); out << sb; out << nl << "let sz = try istr.readAndCheckSeqSize(minSize: " << p->type()->minWireSize() << ")"; @@ -668,13 +664,13 @@ Gen::TypesVisitor::visitSequence(const SequencePtr& p) out << nl << "return v"; out << eb; + out << sp; out << nl << "/// Read an optional `" << fixIdent(name) << "?` sequence from the stream."; out << nl << "///"; - out << nl << "/// - parameter istr: `Ice.InputStream` - The stream to read from."; - out << nl << "///"; - out << nl << "/// - parameter tag: `Swift.Int32` - The numeric tag associated with the value."; + out << nl << "/// - Parameter istr: The stream to read from."; + out << nl << "/// - Parameter tag: The numeric tag associated with the value."; out << nl << "///"; - out << nl << "/// - returns: `" << fixIdent(name) << "` - The sequence read from the stream."; + out << nl << "/// - Returns: The sequence read from the stream."; out << nl << "public static func read(from istr: " << istr << ", tag: Swift.Int32) throws -> " << fixIdent(name) << "?"; out << sb; @@ -694,11 +690,10 @@ Gen::TypesVisitor::visitSequence(const SequencePtr& p) out << eb; out << sp; - out << nl << "/// Wite a `" << fixIdent(name) << "` sequence to the stream."; + out << nl << "/// Write a `" << fixIdent(name) << "` sequence to the stream."; out << nl << "///"; - out << nl << "/// - parameter ostr: `Ice.OuputStream` - The stream to write to."; - out << nl << "///"; - out << nl << "/// - parameter value: `" << fixIdent(name) << "` - The sequence value to write to the stream."; + out << nl << "/// - Parameter ostr: The stream to write to."; + out << nl << "/// - Parameter value: The sequence value to write to the stream."; out << nl << "public static func write(to ostr: " << ostr << ", value v: " << fixIdent(name) << ")"; out << sb; out << nl << "ostr.write(size: v.count)"; @@ -709,13 +704,12 @@ Gen::TypesVisitor::visitSequence(const SequencePtr& p) out << eb; out << sp; - out << nl << "/// Wite an optional `" << fixIdent(name) << "?` sequence to the stream."; - out << nl << "///"; - out << nl << "/// - parameter ostr: `Ice.OuputStream` - The stream to write to."; - out << nl << "///"; - out << nl << "/// - parameter tag: `Int32` - The numeric tag associated with the value."; + out << nl << "/// Write an optional `" << fixIdent(name) << "?` sequence to the stream."; out << nl << "///"; - out << nl << "/// - parameter value: `" << fixIdent(name) << "` The sequence value to write to the stream."; + out << nl << "/// - Parameters:"; + out << nl << "/// - ostr: The stream to write to."; + out << nl << "/// - tag: The numeric tag associated with the value."; + out << nl << "/// - value: The sequence value to write to the stream."; out << nl << "public static func write(to ostr: " << ostr << ", tag: Swift.Int32, value v: " << fixIdent(name) << "?)"; out << sb; @@ -779,9 +773,9 @@ Gen::TypesVisitor::visitDictionary(const DictionaryPtr& p) out << nl << "/// Read a `" << fixIdent(name) << "` dictionary from the stream."; out << nl << "///"; - out << nl << "/// - parameter istr: `Ice.InputStream` - The stream to read from."; + out << nl << "/// - Parameter istr: The stream to read from."; out << nl << "///"; - out << nl << "/// - returns: `" << fixIdent(name) << "` - The dictionary read from the stream."; + out << nl << "/// - Returns: The dictionary read from the stream."; out << nl << "public static func read(from istr: " << istr << ") throws -> " << fixIdent(name); out << sb; out << nl << "let sz = try Swift.Int(istr.readSize())"; @@ -826,13 +820,13 @@ Gen::TypesVisitor::visitDictionary(const DictionaryPtr& p) out << nl << "return v"; out << eb; + out << sp; out << nl << "/// Read an optional `" << fixIdent(name) << "?` dictionary from the stream."; out << nl << "///"; - out << nl << "/// - parameter istr: `Ice.InputStream` - The stream to read from."; - out << nl << "///"; - out << nl << "/// - parameter tag: `Int32` - The numeric tag associated with the value."; + out << nl << "/// - Parameter istr: The stream to read from."; + out << nl << "/// - Parameter tag: The numeric tag associated with the value."; out << nl << "///"; - out << nl << "/// - returns: `" << fixIdent(name) << "` - The dictionary read from the stream."; + out << nl << "/// - Returns: The dictionary read from the stream."; out << nl << "public static func read(from istr: " << istr << ", tag: Swift.Int32) throws -> " << fixIdent(name) << "?"; out << sb; @@ -852,11 +846,10 @@ Gen::TypesVisitor::visitDictionary(const DictionaryPtr& p) out << eb; out << sp; - out << nl << "/// Wite a `" << fixIdent(name) << "` dictionary to the stream."; + out << nl << "/// Write a `" << fixIdent(name) << "` dictionary to the stream."; out << nl << "///"; - out << nl << "/// - parameter ostr: `Ice.OuputStream` - The stream to write to."; - out << nl << "///"; - out << nl << "/// - parameter value: `" << fixIdent(name) << "` - The dictionary value to write to the stream."; + out << nl << "/// - Parameter ostr: The stream to write to."; + out << nl << "/// - Parameter value: The dictionary value to write to the stream."; out << nl << "public static func write(to ostr: " << ostr << ", value v: " << fixIdent(name) << ")"; out << sb; out << nl << "ostr.write(size: v.count)"; @@ -868,13 +861,12 @@ Gen::TypesVisitor::visitDictionary(const DictionaryPtr& p) out << eb; out << sp; - out << nl << "/// Wite an optional `" << fixIdent(name) << "?` dictionary to the stream."; - out << nl << "///"; - out << nl << "/// - parameter ostr: `Ice.OuputStream` - The stream to write to."; - out << nl << "///"; - out << nl << "/// - parameter tag: `Int32` - The numeric tag associated with the value."; + out << nl << "/// Write an optional `" << fixIdent(name) << "?` dictionary to the stream."; out << nl << "///"; - out << nl << "/// - parameter value: `" << fixIdent(name) << "` - The dictionary value to write to the stream."; + out << nl << "/// - Parameters:"; + out << nl << "/// - ostr: The stream to write to."; + out << nl << "/// - tag: The numeric tag associated with the value."; + out << nl << "/// - value: The dictionary value to write to the stream."; out << nl << "public static func write(to ostr: " << ostr << ", tag: Swift.Int32, value v: " << fixIdent(name) << "?)"; out << sb; @@ -939,7 +931,7 @@ Gen::TypesVisitor::visitEnum(const EnumPtr& p) out << sp; out << nl << "/// Read an enumerated value."; out << nl << "///"; - out << nl << "/// - returns: `" << name << "` - The enumarated value."; + out << nl << "/// - Returns: The enumerated value."; out << nl << "func read() throws -> " << name; out << sb; out << nl << "let rawValue: " << enumType << " = try read(enumMaxValue: " << p->maxValue() << ")"; @@ -953,9 +945,9 @@ Gen::TypesVisitor::visitEnum(const EnumPtr& p) out << sp; out << nl << "/// Read an optional enumerated value from the stream."; out << nl << "///"; - out << nl << "/// - parameter tag: `Int32` - The numeric tag associated with the value."; + out << nl << "/// - Parameter tag: The numeric tag associated with the value."; out << nl << "///"; - out << nl << "/// - returns: `" << name << "` - The enumerated value."; + out << nl << "/// - Returns: The enumerated value."; out << nl << "func read(tag: Swift.Int32) throws -> " << name << "?"; out << sb; out << nl << "guard try readOptional(tag: tag, expectedFormat: " << optionalFormat << ") else"; @@ -975,7 +967,7 @@ Gen::TypesVisitor::visitEnum(const EnumPtr& p) out << sp; out << nl << "/// Writes an enumerated value to the stream."; out << nl << "///"; - out << nl << "/// parameter _: `" << name << "` - The enumerator to write."; + out << nl << "/// - Parameter v: The enumerator to write."; out << nl << "func write(_ v: " << name << ")"; out << sb; out << nl << "write(enum: v.rawValue, maxValue: " << p->maxValue() << ")"; @@ -984,9 +976,8 @@ Gen::TypesVisitor::visitEnum(const EnumPtr& p) out << sp; out << nl << "/// Writes an optional enumerated value to the stream."; out << nl << "///"; - out << nl << "/// parameter tag: `Int32` - The numeric tag associated with the value."; - out << nl << "///"; - out << nl << "/// parameter _: `" << name << "` - The enumerator to write."; + out << nl << "/// - Parameter tag: The numeric tag associated with the value."; + out << nl << "/// - Parameter value: The enumerator to write."; out << nl << "func write(tag: Swift.Int32, value: " << name << "?)"; out << sb; out << nl << "guard let v = value else"; @@ -1082,7 +1073,9 @@ Gen::ProxyVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p) out << nl << "/// - communicator: The communicator of the new proxy."; out << nl << "/// - proxyString: The proxy string to parse."; out << nl << "/// - type: The type of the new proxy."; + out << nl << "///"; out << nl << "/// - Throws: `Ice.ParseException` if the proxy string is invalid."; + out << nl << "///"; out << nl << "/// - Returns: A new proxy with the requested type."; out << nl << "public func makeProxy(communicator: Ice.Communicator, proxyString: String, type: " << prx << ".Protocol) throws -> " << prx; @@ -1100,18 +1093,15 @@ Gen::ProxyVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p) out << nl << "/// It will throw a local exception if a communication error occurs. You can optionally supply a"; out << nl << "/// facet name and a context map."; out << nl << "///"; - out << nl << "/// - parameter prx: `Ice.ObjectPrx` - The proxy to be cast."; - out << nl << "///"; - out << nl << "/// - parameter type: `" << prx << ".Protocol` - The proxy type to cast to."; - out << nl << "///"; - out << nl << "/// - parameter facet: `String` - The optional name of the desired facet."; - out << nl << "///"; - out << nl << "/// - parameter context: `Ice.Context` The optional context dictionary for the remote invocation."; + out << nl << "/// - Parameters:"; + out << nl << "/// - prx: The proxy to be cast."; + out << nl << "/// - type: The proxy type to cast to."; + out << nl << "/// - facet: The optional name of the desired facet."; + out << nl << "/// - context: The optional context dictionary for the remote invocation."; out << nl << "///"; - out << nl << "/// - returns: `" << prx << "` - A proxy with the requested type or nil if the objet does not"; - out << nl << "/// support this type."; + out << nl << "/// - Returns: A proxy with the requested type or nil if the objet does not support this type."; out << nl << "///"; - out << nl << "/// - throws: `Ice.LocalException` if a communication error occurs."; + out << nl << "/// - Throws: `Ice.LocalException` if a communication error occurs."; out << nl << "public func checkedCast" << spar << ("prx: " + getUnqualified("Ice.ObjectPrx", swiftModule)) << ("type: " + prx + ".Protocol") << ("facet: Swift.String? = nil") << ("context: " + getUnqualified("Ice.Context", swiftModule) + "? = nil") << epar << " async throws -> " << prx @@ -1127,13 +1117,12 @@ Gen::ProxyVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p) out << sp; out << nl << "/// Downcasts the given proxy to this type without contacting the remote server."; out << nl << "///"; - out << nl << "/// - parameter prx: `Ice.ObjectPrx` The proxy to be cast."; - out << nl << "///"; - out << nl << "/// - parameter type: `" << prx << ".Protocol` - The proxy type to cast to."; - out << nl << "///"; - out << nl << "/// - parameter facet: `String` - The optional name of the desired facet"; + out << nl << "/// - Parameters:"; + out << nl << "/// - prx: The proxy to be cast."; + out << nl << "/// - type: The proxy type to cast to."; + out << nl << "/// - facet: The optional name of the desired facet."; out << nl << "///"; - out << nl << "/// - returns: `" << prx << "` - A proxy with the requested type"; + out << nl << "/// - Returns: A proxy with the requested type."; out << nl << "public func uncheckedCast" << spar << ("prx: " + getUnqualified("Ice.ObjectPrx", swiftModule)) << ("type: " + prx + ".Protocol") << ("facet: Swift.String? = nil") << epar << " -> " << prx; out << sb; @@ -1146,9 +1135,9 @@ Gen::ProxyVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p) out << sp; out << nl << "/// Returns the Slice type id of the interface associated with this proxy type."; out << nl << "///"; - out << nl << "/// parameter type: `" << prx << ".Protocol` - The proxy type to retrieve the type id."; + out << nl << "/// - Parameter type: The proxy type to retrieve the type id."; out << nl << "///"; - out << nl << "/// returns: `String` - The type id of the interface associated with this proxy type."; + out << nl << "/// - Returns: The type id of the interface associated with this proxy type."; out << nl << "public func ice_staticId" << spar << ("_ type: " + prx + ".Protocol") << epar << " -> Swift.String"; out << sb; out << nl << "return " << traits << ".staticId"; @@ -1158,16 +1147,16 @@ Gen::ProxyVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p) // InputStream extension // out << sp; - out << nl << "/// Extension to `Ice.InputStream` class to support reading proxy of type"; + out << nl << "/// Extension to `Ice.InputStream` class to support reading proxies of type"; out << nl << "/// `" << prx << "`."; out << nl << "public extension " << getUnqualified("Ice.InputStream", swiftModule); out << sb; out << nl << "/// Extracts a proxy from the stream. The stream must have been initialized with a communicator."; out << nl << "///"; - out << nl << "/// - parameter type: `" << prx << ".Protocol` - The type of the proxy to be extracted."; + out << nl << "/// - Parameter type: The type of the proxy to be extracted."; out << nl << "///"; - out << nl << "/// - returns: `" << prx << "?` - The extracted proxy"; + out << nl << "/// - Returns: The extracted proxy."; out << nl << "func read(_ type: " << prx << ".Protocol) throws -> " << prx << "?"; out << sb; out << nl << "return try read() as " << prxI << "?"; @@ -1175,11 +1164,10 @@ Gen::ProxyVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p) out << nl << "/// Extracts a proxy from the stream. The stream must have been initialized with a communicator."; out << nl << "///"; - out << nl << "/// - parameter tag: `Int32` - The numeric tag associated with the value."; - out << nl << "///"; - out << nl << "/// - parameter type: `" << prx << ".Protocol` - The type of the proxy to be extracted."; + out << nl << "/// - Parameter tag: The numeric tag associated with the value."; + out << nl << "/// - Parameter type: The type of the proxy to be extracted."; out << nl << "///"; - out << nl << "/// - returns: `" << prx << "` - The extracted proxy."; + out << nl << "/// - Returns: The extracted proxy."; out << nl << "func read(tag: Swift.Int32, type: " << prx << ".Protocol) throws -> " << prx << "?"; out << sb; out << nl << "return try read(tag: tag) as " << prxI << "?"; @@ -1302,9 +1290,7 @@ Gen::ValueVisitor::visitClassDefStart(const ClassDefPtr& p) // else inherit Value's initializer. out << sp; - out << nl << "/// Returns the Slice type ID of the interface supported by this object."; - out << nl << "///"; - out << nl << "/// - returns: `String` - The Slice type ID of the interface supported by this object."; + out << nl << "/// - Returns: The Slice type ID of the interface supported by this object."; out << nl << "open override class func ice_staticId() -> Swift.String { \"" << p->scoped() << "\" }"; out << sp; diff --git a/cpp/src/slice2swift/SwiftUtil.cpp b/cpp/src/slice2swift/SwiftUtil.cpp index 7a61496f506..8c29ada16b5 100644 --- a/cpp/src/slice2swift/SwiftUtil.cpp +++ b/cpp/src/slice2swift/SwiftUtil.cpp @@ -154,20 +154,23 @@ namespace } } + // TODO: fix this to emit double-ticks instead of single-ticks once we've fixed all the links. string swiftLinkFormatter(string identifier, string memberComponent) { + string result = "`"; if (memberComponent.empty()) { - return fixIdent(identifier); + result += fixIdent(identifier); } else if (identifier.empty()) { - return fixIdent(memberComponent); + result += fixIdent(memberComponent); } else { - return fixIdent(identifier) + "." + fixIdent(memberComponent); + result += fixIdent(identifier) + "/" + fixIdent(memberComponent); } + return result + "`"; } } @@ -276,12 +279,12 @@ SwiftGenerator::writeDocLines(IceInternal::Output& out, const StringList& lines, l.pop_front(); } - for (StringList::const_iterator i = l.begin(); i != l.end(); ++i) + for (const auto& line : l) { out << nl << "///"; - if (!i->empty()) + if (!line.empty()) { - out << space << *i; + out << space << line; } } } @@ -349,22 +352,33 @@ SwiftGenerator::writeDocSummary(IceInternal::Output& out, const ContainedPtr& p) return; } + bool hasStarted = false; + StringList docOverview = doc->overview(); if (!docOverview.empty()) { writeDocLines(out, docOverview); + hasStarted = true; } StringList docMisc = doc->misc(); if (!docMisc.empty()) { - out << nl << "///"; + if (hasStarted) + { + out << nl << "///"; + } + hasStarted = true; writeDocLines(out, docMisc); } if (doc->isDeprecated()) { - out << nl << "///"; + if (hasStarted) + { + out << nl << "///"; + } + hasStarted = true; out << nl << "/// ## Deprecated"; StringList docDeprecated = doc->deprecated(); if (!docDeprecated.empty()) @@ -372,6 +386,8 @@ SwiftGenerator::writeDocSummary(IceInternal::Output& out, const ContainedPtr& p) writeDocLines(out, docDeprecated); } } + + // TODO we should add a section for '@see' tags. } void @@ -383,15 +399,25 @@ SwiftGenerator::writeOpDocSummary(IceInternal::Output& out, const OperationPtr& return; } + bool hasStarted = false; + + // Write the overview. StringList docOverview = doc->overview(); if (!docOverview.empty()) { writeDocLines(out, docOverview); + hasStarted = true; } + // If the comment contained an `@deprecated` include it as a section in the overview. if (doc->isDeprecated()) { - out << nl << "///"; + if (hasStarted) + { + out << nl << "///"; + } + hasStarted = true; + out << nl << "/// ## Deprecated"; StringList docDeprecated = doc->deprecated(); if (!docDeprecated.empty()) @@ -400,101 +426,108 @@ SwiftGenerator::writeOpDocSummary(IceInternal::Output& out, const OperationPtr& } } - const ParamInfoList allInParams = getAllInParams(p); auto docParameters = doc->parameters(); - for (ParamInfoList::const_iterator q = allInParams.begin(); q != allInParams.end(); ++q) + + // Document all the in parameters. + const ParamInfoList allInParams = getAllInParams(p); + bool useListStyle = allInParams.size() >= 1; // '>=' instead of '>' to account for the current/context parameter. + if (hasStarted) { out << nl << "///"; - out << nl << "/// - parameter " << (!dispatch && allInParams.size() == 1 ? "_" : q->name) << ": `" << q->typeStr - << "`"; - map::const_iterator r = docParameters.find(q->name); - if (r != docParameters.end() && !r->second.empty()) + // Don't bother setting `hasStarted`. We always emit a comment for parameters. So no need to check anymore. + } + if (useListStyle) + { + out << nl << "/// - Parameters:"; + } + for (const auto& inParam : allInParams) + { + out << nl << "/// " << (useListStyle ? " - " : "- Parameter ") << (dispatch ? "" : "iceP_") << inParam.name; + auto docParameter = docParameters.find(inParam.name); + if (docParameter != docParameters.end() && !docParameter->second.empty()) { - out << " "; - writeDocLines(out, r->second, false); + out << ": "; + writeDocLines(out, docParameter->second, false); } } - - out << nl << "///"; + out << nl << "/// " << (useListStyle ? " - " : "- Parameter "); if (dispatch) { - out << nl << "/// - parameter current: `Ice.Current` - The Current object for the dispatch."; + out << "current: The Current object for the dispatch."; } else { - out << nl << "/// - parameter context: `Ice.Context` - Optional request context."; + out << "context: Optional request context."; } - const ParamInfoList allOutParams = getAllOutParams(p); - if (allOutParams.size() == 1) + // Document the return type & any out parameters. + ParamInfoList allOutParams = getAllOutParams(p); + useListStyle = allOutParams.size() > 1; + if (useListStyle) { - ParamInfo ret = allOutParams.front(); out << nl << "///"; - out << nl << "/// - returns: `" << ret.typeStr << "`"; - if (p->returnType()) - { - StringList docReturns = doc->returns(); - if (!docReturns.empty()) - { - out << " - "; - writeDocLines(out, docReturns, false); - } - } - else - { - map::const_iterator r = docParameters.find(ret.name); - if (r != docParameters.end() && !r->second.empty()) - { - out << " - "; - writeDocLines(out, r->second, false); - } - } + out << nl << "/// - Returns:"; } - else if (allOutParams.size() > 1) + + if (!allOutParams.empty()) { - out << nl << "///"; - out << nl << "/// - returns: `" << operationReturnType(p) << "`:"; - if (p->returnType()) + // `getAllOutParams` puts the return-type parameter at the end, we want to move it to the front. + allOutParams.push_front(allOutParams.back()); + allOutParams.pop_back(); + + // Document each of the out parameters. + for (const auto& outParam : allOutParams) { - ParamInfo ret = allOutParams.back(); - out << nl << "///"; - out << nl << "/// - " << ret.name << ": `" << ret.typeStr << "`"; - StringList docReturns = doc->returns(); - if (!docReturns.empty()) + // First, check if the user supplied a message in the doc comment for this parameter / return type. + StringList docMessage; + if (outParam.param == nullptr) // This means it was a return type, not an out parameter. { - out << " - "; - writeDocLines(out, docReturns, false); + docMessage = doc->returns(); + } + else + { + const auto result = docParameters.find(outParam.name); + if (result != docParameters.end()) + { + docMessage = result->second; + } } - } - for (ParamInfoList::const_iterator q = allOutParams.begin(); q != allOutParams.end(); ++q) - { - if (q->param != 0) + if (useListStyle) { - out << nl << "///"; - out << nl << "/// - " << q->name << ": `" << q->typeStr << "`"; - map::const_iterator r = docParameters.find(q->name); - if (r != docParameters.end() && !r->second.empty()) + out << nl << "/// - " << outParam.name; + if (!docMessage.empty()) { - out << " - "; - writeDocLines(out, r->second, false); + out << ": "; + writeDocLines(out, docMessage, false); } } + else if (!docMessage.empty()) + { + out << nl << "///"; + out << nl << "/// - Returns: "; + writeDocLines(out, docMessage, false); + } } } + // Document what exceptions it can throw. auto docExceptions = doc->exceptions(); if (!docExceptions.empty()) { + useListStyle = docExceptions.size() < 2; out << nl << "///"; - out << nl << "/// - throws:"; + out << nl << "/// - Throws:"; for (const auto& docException : docExceptions) { - out << nl << "///"; - out << nl << "/// - " << docException.first; + if (useListStyle) + { + out << nl << "/// -"; + } + out << " " << docException.first; if (!docException.second.empty()) { - out << " - "; + out << " "; writeDocLines(out, docException.second, false, " "); } } @@ -535,32 +568,31 @@ SwiftGenerator::writeProxyDocSummary(IceInternal::Output& out, const InterfaceDe { out << nl << "///"; out << nl << "/// " << prx << " Methods:"; - for (OperationList::const_iterator q = ops.begin(); q != ops.end(); ++q) + for (const auto& op : ops) { - OperationPtr op = *q; CommentPtr opdoc = op->parseComment(swiftLinkFormatter, true); - out << nl << "///"; - out << nl << "/// - " << fixIdent(op->name()); + optional opDocOverview; if (opdoc) { - out << ": "; - StringList opdocOverview = opdoc->overview(); - if (!opdocOverview.empty()) + StringList overview = opdoc->overview(); + if (!overview.empty()) { - writeDocSentence(out, opdocOverview); + opDocOverview = overview; } } - out << nl << "///"; + out << nl << "/// - " << fixIdent(op->name()); + if (auto overview = opDocOverview) + { + out << ": "; + writeDocSentence(out, *overview); + } + out << nl << "/// - " << op->name() << "Async"; - if (opdoc) + if (auto overview = opDocOverview) { out << ": "; - StringList opdocOverview = opdoc->overview(); - if (!opdocOverview.empty()) - { - writeDocSentence(out, opdocOverview); - } + writeDocSentence(out, *overview); } } } @@ -598,18 +630,16 @@ SwiftGenerator::writeServantDocSummary(IceInternal::Output& out, const Interface { out << nl << "///"; out << nl << "/// " << name << " Methods:"; - for (OperationList::const_iterator q = ops.begin(); q != ops.end(); ++q) + for (const auto& op : ops) { - OperationPtr op = *q; - CommentPtr opdoc = op->parseComment(swiftLinkFormatter, true); - out << nl << "///"; out << nl << "/// - " << fixIdent(op->name()); + CommentPtr opdoc = op->parseComment(swiftLinkFormatter, true); if (opdoc) { - out << ": "; StringList opdocOverview = opdoc->overview(); if (!opdocOverview.empty()) { + out << ": "; writeDocSentence(out, opdocOverview); } } @@ -623,46 +653,6 @@ SwiftGenerator::writeServantDocSummary(IceInternal::Output& out, const Interface } } -void -SwiftGenerator::writeMemberDoc(IceInternal::Output& out, const DataMemberPtr& p) -{ - CommentPtr doc = p->parseComment(swiftLinkFormatter, true); - if (!doc) - { - return; - } - - // Skip if there are no doc comments. - StringList docOverview = doc->overview(); - StringList docMisc = doc->misc(); - StringList docSeeAlso = doc->seeAlso(); // TODO we check seeAlso, but don't write any of in the generated comment? - StringList docDeprecated = doc->deprecated(); - bool docIsDeprecated = doc->isDeprecated(); - - if (docOverview.empty()) - { - out << nl << "/// " << fixIdent(p->name()); - } - else - { - writeDocLines(out, docOverview); - } - - if (!docMisc.empty()) - { - writeDocLines(out, docMisc); - } - - if (docIsDeprecated) - { - out << nl << "/// ##Deprecated"; - if (!docDeprecated.empty()) - { - writeDocLines(out, docDeprecated); - } - } -} - void SwiftGenerator::validateMetadata(const UnitPtr& u) { @@ -1113,7 +1103,7 @@ SwiftGenerator::writeMembers( out << nl << "typealias " << alias << " = " << memberType; } - writeMemberDoc(out, member); + writeDocSummary(out, member); out << nl << access << "var " << memberName << ": " << memberType; if (protocol) { diff --git a/cpp/src/slice2swift/SwiftUtil.h b/cpp/src/slice2swift/SwiftUtil.h index 425aded7179..b58ed53e2bd 100644 --- a/cpp/src/slice2swift/SwiftUtil.h +++ b/cpp/src/slice2swift/SwiftUtil.h @@ -58,7 +58,6 @@ namespace Slice void writeProxyDocSummary(IceInternal::Output&, const InterfaceDefPtr&, const std::string&); void writeServantDocSummary(IceInternal::Output&, const InterfaceDefPtr&, const std::string&); - void writeMemberDoc(IceInternal::Output&, const DataMemberPtr&); std::string paramLabel(const std::string&, const ParamDeclList&); std::string operationReturnType(const OperationPtr&); diff --git a/slice/Ice/RemoteLogger.ice b/slice/Ice/RemoteLogger.ice index a726975e44a..1dbf9bd5075 100644 --- a/slice/Ice/RemoteLogger.ice +++ b/slice/Ice/RemoteLogger.ice @@ -35,7 +35,7 @@ module Ice ErrorMessage } - /// A sequence of {@link LogMessageType} + /// A sequence of {@link LogMessageType}. sequence LogMessageTypeSeq; /// A complete log message.