How do you attach a source location to a structured problem so an IDE can point the user at the exact file and line?
answer
- fileLocation(path)
- lineInFileLocation(path, line, col, length)
- offsetInFileLocation(path, offset, length)
- pluginLocation(pluginId)
- each call appends — multiple locations allowed
basics
~10 sOn the ProblemSpec you call location methods like spec.fileLocation(path) or spec.lineInFileLocation(path, line, column). These attach a typed location object so IDEs can render a clickable link to the offending file/line.
solid answer
~50 sA structured problem can carry one or more **locations** describing where in the user's sources it originates. On the `ProblemSpec` you add them with builder calls such as `fileLocation(String path)` for a whole-file pointer, and `lineInFileLocation(String path, int line)` or the richer `lineInFileLocation(path, line, column, length)` to pinpoint a line (and optionally a column and span). There are also offset-based variants (`offsetInFileLocation(path, offset, length)`) and a `pluginLocation(pluginId)` to blame a plugin rather than a source file. Each call appends a location, so a single problem may have several. Consumers — especially IDEs via the Tooling API — turn these typed locations into clickable navigation, which is the whole point: you're handing the IDE structured coordinates instead of embedding `"at build.gradle.kts:12"` inside a log string it would have to parse. Paths are typically the absolute or project-relative path of the file being diagnosed.
code
kotlin · 6 linesreporter.report(problemId) { spec ->
spec.severity(Severity.WARNING)
.lineInFileLocation("settings.gradle.kts", 8, 1, 24)
.pluginLocation("com.example.myplugin")
.details("Repository declared without a name")
}go deeper
Know that fileLocation / lineInFileLocation exist to point at a file/line.
List the line/column/length and offset variants and pluginLocation, and that calls append.
Explain the IDE/Tooling-API navigation payoff and when to choose offset vs line vs plugin locations.
Position typed locations as the contract that makes diagnostics machine-navigable across IDEs and CI dashboards, replacing brittle log parsing.
## Why locations exist The value of structured diagnostics is that a consumer can **navigate** to the cause. A plain `logger.warn("problem in build.gradle.kts line 12")` forces an IDE to regex the console. The Problems API instead lets you attach **typed location objects** to a problem, which the Tooling API delivers to IDEs (IntelliJ, Eclipse Buildship) and which the HTML problems report renders. ## The location builder methods on ProblemSpec Locations are added through `ProblemSpec` builder calls; each call **appends** another location (a problem can have many): - **`fileLocation(String path)`** — points at an entire file, no line. - **`lineInFileLocation(String path, int line)`** — file + 1-based line. - **`lineInFileLocation(String path, int line, int column)`** — adds a column. - **`lineInFileLocation(String path, int line, int column, int length)`** — adds a span length so the IDE can underline a range. - **`offsetInFileLocation(String path, int offset, int length)`** — character-offset based, for tools that think in offsets rather than line/column. - **`pluginLocation(String pluginId)`** — attributes the problem to a plugin instead of a user file (useful when there's no source line, e.g. a misconfiguration produced by a plugin). ```kotlin reporter.report(problemId) { spec -> spec.severity(Severity.WARNING) .lineInFileLocation("build.gradle.kts", 12, 5, 18) .details("Property 'foo' is deprecated") } ``` ## Choosing a location type - Use **`lineInFileLocation`** when you parsed a DSL/config file and know the exact line — best UX. - Use **`fileLocation`** when you can identify the file but not the line. - Use **`offsetInFileLocation`** when your tooling works in character offsets (parsers, language servers). - Use **`pluginLocation`** when the fault is conceptually "this plugin's behaviour" and there is no user source coordinate. ## Multiple locations Because each call appends, you can attach, say, both the offending `build.gradle.kts` line and a `pluginLocation` to say which plugin raised it. Consumers decide how to present several locations. ## Relationship to severity and solutions Location, severity, and solution are independent facets of the same `ProblemSpec`. A high-quality problem usually sets all three: *how serious* (severity), *where* (location), and *what to do* (solution/documentedAt). Together they make the diagnostic actionable in an IDE without the user reading the console.
- Can a single problem carry more than one location?Yes — each location call appends, so you can attach, e.g., both a lineInFileLocation and a pluginLocation to the same problem.
- When would you use pluginLocation instead of a file location?When the fault has no user-source coordinate — it's the plugin's own behaviour/misconfiguration — so you blame the plugin id rather than a line in a build script.
- What does the extra 'length' argument on lineInFileLocation enable?It gives the span length so an IDE can underline/highlight a precise range rather than just placing a caret at the line:column.
saying these in an interview costs you the question
- Embedding the location as text in details() instead of using the typed location methods — defeats IDE navigation.
- Assuming only one location is allowed; multiple appended locations are supported.