(t *Type, enclosingDeclaration *ast.Node, flags TypeFormatFlags, vc *VerbosityContext)
| 187 | } |
| 188 | |
| 189 | func (c *Checker) typeToStringEx(t *Type, enclosingDeclaration *ast.Node, flags TypeFormatFlags, vc *VerbosityContext) string { |
| 190 | // Serialization of types can lead to (lazy) resolution of members, which can cause diagnostics that again require |
| 191 | // serialization of types. This can potentially result in infinite recursion and stack overflows. To prevent that, |
| 192 | // after a certain number of recursive invocations the function simply returns "?". |
| 193 | if c.serializationLevel >= maxSerializationLevel { |
| 194 | return "?" |
| 195 | } |
| 196 | newLine := "" |
| 197 | if flags&TypeFormatFlagsMultilineObjectLiterals != 0 { |
| 198 | newLine = "\n" |
| 199 | } |
| 200 | writer := printer.NewTextWriter(newLine, 0) |
| 201 | noTruncation := ((vc == nil || vc.MaxTruncationLength == 0) && c.compilerOptions.NoErrorTruncation == core.TSTrue) || (flags&TypeFormatFlagsNoTruncation != 0) |
| 202 | combinedFlags := toNodeBuilderFlags(flags) | nodebuilder.FlagsIgnoreErrors |
| 203 | if noTruncation { |
| 204 | combinedFlags = combinedFlags | nodebuilder.FlagsNoTruncation |
| 205 | } |
| 206 | nodeBuilder, release := c.getNodeBuilder() |
| 207 | defer release() |
| 208 | oldVerbosity := nodeBuilder.verbosity |
| 209 | nodeBuilder.verbosity = vc |
| 210 | defer func() { |
| 211 | nodeBuilder.verbosity = oldVerbosity |
| 212 | }() |
| 213 | c.serializationLevel++ |
| 214 | typeNode := nodeBuilder.TypeToTypeNode(t, enclosingDeclaration, combinedFlags, nodebuilder.InternalFlagsNone, nil) |
| 215 | c.serializationLevel-- |
| 216 | if typeNode == nil { |
| 217 | panic("should always get typenode") |
| 218 | } |
| 219 | // The unresolved type gets a synthesized comment on `any` to hint to users that it's not a plain `any`. |
| 220 | // Otherwise, we always strip comments out. |
| 221 | var p *printer.Printer |
| 222 | if t == c.unresolvedType { |
| 223 | p = createPrinterWithDefaults(nodeBuilder.EmitContext()) |
| 224 | } else { |
| 225 | p = createPrinterWithRemoveComments(nodeBuilder.EmitContext()) |
| 226 | } |
| 227 | var sourceFile *ast.SourceFile |
| 228 | if enclosingDeclaration != nil { |
| 229 | sourceFile = ast.GetSourceFileOfNode(enclosingDeclaration) |
| 230 | } |
| 231 | p.Write(typeNode, sourceFile, writer, nil) |
| 232 | result := writer.String() |
| 233 | |
| 234 | maxLength := defaultMaximumTruncationLength * 2 |
| 235 | if vc != nil && vc.MaxTruncationLength > 0 { |
| 236 | maxLength = vc.MaxTruncationLength * 10 // hard cutoff matching Strada's absoluteMaximumLength |
| 237 | } |
| 238 | if noTruncation { |
| 239 | maxLength = noTruncationMaximumTruncationLength * 2 |
| 240 | } |
| 241 | if maxLength > 0 && result != "" && len(result) >= maxLength { |
| 242 | if vc != nil { |
| 243 | vc.Truncated = true |
| 244 | } |
| 245 | return result[0:maxLength-len("...")] + "..." |
| 246 | } |
no test coverage detected