Skip to content

Commit

Permalink
Create ErrorThrowingDiagnosticCollector diagnostics before code gener…
Browse files Browse the repository at this point in the history
…ation
  • Loading branch information
PARAIPAN9 committed Aug 5, 2024
1 parent 7fba3b9 commit d71f2cf
Show file tree
Hide file tree
Showing 10 changed files with 35 additions and 43 deletions.
4 changes: 1 addition & 3 deletions Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,7 @@ func makeGeneratorPipeline(
}
let validateDoc = { (doc: OpenAPI.Document) -> OpenAPI.Document in
let validationDiagnostics = try validator(doc, config)
for diagnostic in validationDiagnostics {
try ErrorThrowingDiagnosticCollector(upstream: diagnostics).emit(diagnostic)
}
for diagnostic in validationDiagnostics { try diagnostics.emit(diagnostic) }
return doc
}
return .init(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ extension TypesFileTranslator {
objectContext: JSONSchema.ObjectContext,
isDeprecated: Bool
) throws -> Declaration {
let collector = ErrorThrowingDiagnosticCollector(upstream: diagnostics)
let documentedProperties: [PropertyBlueprint] = try objectContext.properties
.filter { key, value in

Expand All @@ -42,7 +41,7 @@ extension TypesFileTranslator {
// have a proper definition in the `properties` map are skipped, as they
// often imply a typo or a mistake in the document. So emit a diagnostic as well.
guard !value.inferred else {
try collector.emit(
try diagnostics.emit(
.warning(
message:
"A property name only appears in the required list, but not in the properties map - this is likely a typo; skipping this property.",
Expand All @@ -63,7 +62,7 @@ extension TypesFileTranslator {
// allowed in object properties, explicitly filter these out
// here.
if value.isString && value.formatString == "binary" {
try collector.emitUnsupportedSchema(
try diagnostics.emitUnsupportedSchema(
reason: "Binary properties in object schemas.",
schema: value,
foundIn: foundIn
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,7 @@ extension TypesFileTranslator {

// Attach any warnings from the parsed schema as a diagnostic.
for warning in schema.warnings {
let errorThrowing = ErrorThrowingDiagnosticCollector(upstream: diagnostics)
try errorThrowing.emit(
try diagnostics.emit(
.warning(
message: "Schema warning: \(warning.description)",
context: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,7 @@ extension FileTranslator {
-> SchemaContent?
{
guard !map.isEmpty else { return nil }
let collector = ErrorThrowingDiagnosticCollector(upstream: diagnostics)
if map.count > 1 { try collector.emitUnsupported("Multiple content types", foundIn: foundIn) }
if map.count > 1 { try diagnostics.emitUnsupported("Multiple content types", foundIn: foundIn) }
let mapWithContentTypes = try map.map { key, content in try (type: key.asGeneratorContentType, value: content) }

let chosenContent: (type: ContentType, schema: SchemaContent, content: OpenAPI.Content)?
Expand All @@ -138,15 +137,15 @@ extension FileTranslator {
contentValue
)
} else {
try collector.emitUnsupported("Unsupported content", foundIn: foundIn)
try diagnostics.emitUnsupported("Unsupported content", foundIn: foundIn)
chosenContent = nil
}
if let chosenContent {
let contentType = chosenContent.type
if contentType.lowercasedType == "multipart"
|| contentType.lowercasedTypeAndSubtype.contains("application/x-www-form-urlencoded")
{
try collector.emitUnsupportedIfNotNil(
try diagnostics.emitUnsupportedIfNotNil(
chosenContent.content.encoding,
"Custom encoding for multipart/formEncoded content",
foundIn: "\(foundIn), content \(contentType.originallyCasedTypeAndSubtype)"
Expand Down Expand Up @@ -181,9 +180,8 @@ extension FileTranslator {
foundIn: String
) throws -> SchemaContent? {
let contentType = try contentKey.asGeneratorContentType
let collector = ErrorThrowingDiagnosticCollector(upstream: diagnostics)
if contentType.lowercasedTypeAndSubtype.contains("application/x-www-form-urlencoded") {
try collector.emitUnsupportedIfNotNil(
try diagnostics.emitUnsupportedIfNotNil(
contentValue.encoding,
"Custom encoding for formEncoded content",
foundIn: "\(foundIn), content \(contentType.originallyCasedTypeAndSubtype)"
Expand All @@ -193,7 +191,7 @@ extension FileTranslator {
if contentType.isUrlEncodedForm { return .init(contentType: contentType, schema: contentValue.schema) }
if contentType.isMultipart {
guard isRequired else {
try collector.emit(
try diagnostics.emit(
.warning(
message:
"Multipart request bodies must always be required, but found an optional one - skipping. Mark as `required: true` to get this body generated.",
Expand All @@ -207,7 +205,7 @@ extension FileTranslator {
if !excludeBinary, contentType.isBinary {
return .init(contentType: contentType, schema: .b(.string(contentEncoding: .binary)))
}
try collector.emitUnsupported("Unsupported content", foundIn: foundIn)
try diagnostics.emitUnsupported("Unsupported content", foundIn: foundIn)
return nil
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -312,8 +312,7 @@ extension FileTranslator {
}
let contentType = finalContentTypeSource.contentType
if finalContentTypeSource.contentType.isMultipart {
try ErrorThrowingDiagnosticCollector(upstream: diagnostics)
.emitUnsupported("Multipart part cannot nest another multipart content.", foundIn: foundIn)
try diagnostics.emitUnsupported("Multipart part cannot nest another multipart content.", foundIn: foundIn)
return nil
}
let info = MultipartPartInfo(repetition: repetitionKind, contentTypeSource: finalContentTypeSource)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ extension FileTranslator {
}
}

let collector = ErrorThrowingDiagnosticCollector(upstream: diagnostics)
let locationTypeName = parameter.location.typeName(in: parent)
let foundIn = "\(locationTypeName.description)/\(parameter.name)"

Expand All @@ -141,22 +140,22 @@ extension FileTranslator {
switch location {
case .query:
guard case .form = style else {
try collector.emitUnsupported(
try diagnostics.emitUnsupported(
"Query params of style \(style.rawValue), explode: \(explode)",
foundIn: foundIn
)
return nil
}
case .header, .path:
guard case .simple = style else {
try collector.emitUnsupported(
try diagnostics.emitUnsupported(
"\(location.rawValue) params of style \(style.rawValue), explode: \(explode)",
foundIn: foundIn
)
return nil
}
case .cookie:
try collector.emitUnsupported("Cookie params", foundIn: foundIn)
try diagnostics.emitUnsupported("Cookie params", foundIn: foundIn)
return nil
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,10 @@ extension ClientFileTranslator {
containerExpr = .identifierPattern(requestVariableName)
supportsStyleAndExplode = true
default:
try ErrorThrowingDiagnosticCollector(upstream: diagnostics)
.emitUnsupported("Parameter of type \(parameter.location.rawValue)", foundIn: parameter.description)
try diagnostics.emitUnsupported(
"Parameter of type \(parameter.location.rawValue)",
foundIn: parameter.description
)
return nil
}
let styleAndExplodeArgs: [FunctionArgumentDescription]
Expand Down Expand Up @@ -196,8 +198,10 @@ extension ServerFileTranslator {
])
)
default:
try ErrorThrowingDiagnosticCollector(upstream: diagnostics)
.emitUnsupported("Parameter of type \(parameter.location)", foundIn: "\(typedParameter.description)")
try diagnostics.emitUnsupported(
"Parameter of type \(parameter.location)",
foundIn: "\(typedParameter.description)"
)
return nil
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@ extension FileTranslator {
switch try isSchemaSupported(schema, referenceStack: &referenceStack) {
case .supported: return true
case .unsupported(reason: let reason, schema: let schema):
try ErrorThrowingDiagnosticCollector(upstream: diagnostics)
.emitUnsupportedSchema(reason: reason.description, schema: schema, foundIn: foundIn)
try diagnostics.emitUnsupportedSchema(reason: reason.description, schema: schema, foundIn: foundIn)
return false
}
}
Expand All @@ -83,8 +82,7 @@ extension FileTranslator {
switch try isSchemaSupported(schema, referenceStack: &referenceStack) {
case .supported: return true
case .unsupported(reason: let reason, schema: let schema):
try ErrorThrowingDiagnosticCollector(upstream: diagnostics)
.emitUnsupportedSchema(reason: reason.description, schema: schema, foundIn: foundIn)
try diagnostics.emitUnsupportedSchema(reason: reason.description, schema: schema, foundIn: foundIn)
return false
}
}
Expand All @@ -102,8 +100,7 @@ extension FileTranslator {
switch try isObjectOrRefToObjectSchemaAndSupported(schema, referenceStack: &referenceStack) {
case .supported: return true
case .unsupported(reason: let reason, schema: let schema):
try ErrorThrowingDiagnosticCollector(upstream: diagnostics)
.emitUnsupportedSchema(reason: reason.description, schema: schema, foundIn: foundIn)
try diagnostics.emitUnsupportedSchema(reason: reason.description, schema: schema, foundIn: foundIn)
return false
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,12 @@ extension TypesFileTranslator {
var decls = decls
for (index, decl) in decls.enumerated() {
guard let name = decl.name, boxedNames.contains(name) else { continue }
try ErrorThrowingDiagnosticCollector(upstream: diagnostics)
.emit(
.note(
message: "Detected a recursive type; it will be boxed to break the reference cycle.",
context: ["name": name]
)
try diagnostics.emit(
.note(
message: "Detected a recursive type; it will be boxed to break the reference cycle.",
context: ["name": name]
)
)
decls[index] = boxedType(decl)
}
return decls
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,17 @@ extension _GenerateOptions {
featureFlags: resolvedFeatureFlags
)
}
let diagnostics: any DiagnosticCollector & Sendable
let innerDiagnostics: any DiagnosticCollector & Sendable
let finalizeDiagnostics: () throws -> Void
if let diagnosticsOutputPath {
let _diagnostics = _YamlFileDiagnosticsCollector(url: diagnosticsOutputPath)
finalizeDiagnostics = _diagnostics.finalize
diagnostics = _diagnostics
innerDiagnostics = _diagnostics
} else {
diagnostics = StdErrPrintingDiagnosticCollector()
innerDiagnostics = StdErrPrintingDiagnosticCollector()
finalizeDiagnostics = {}
}

let diagnostics = ErrorThrowingDiagnosticCollector(upstream: innerDiagnostics)
let doc = self.docPath
print(
"""
Expand Down Expand Up @@ -83,7 +83,7 @@ extension _GenerateOptions {
try finalizeDiagnostics()
} catch let error as Diagnostic {
// Emit our nice Diagnostics message instead of relying on ArgumentParser output.
try ErrorThrowingDiagnosticCollector(upstream: diagnostics).emit(error)
try diagnostics.emit(error)
try finalizeDiagnostics()
throw ExitCode.failure
} catch {
Expand Down

0 comments on commit d71f2cf

Please sign in to comment.