Skip to content

Commit 01a097b

Browse files
martinbonninBoD
andauthored
Apollo AST: add start/end instead of endColumn/endLine (#5103)
* replace endLine/endColumn by start/end * update API dump * Update libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/SourceLocation.kt Co-authored-by: Benoit Lubek <[email protected]> --------- Co-authored-by: Benoit Lubek <[email protected]>
1 parent 4babca1 commit 01a097b

File tree

13 files changed

+231
-130
lines changed

13 files changed

+231
-130
lines changed

libraries/apollo-ast/api/apollo-ast.api

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -910,11 +910,11 @@ public final class com/apollographql/apollo3/ast/SourceLocation {
910910
public static final field Companion Lcom/apollographql/apollo3/ast/SourceLocation$Companion;
911911
public fun <init> (IIIILjava/lang/String;)V
912912
public final fun getColumn ()I
913-
public final fun getEndColumn ()I
914-
public final fun getEndLine ()I
913+
public final fun getEnd ()I
915914
public final fun getFilePath ()Ljava/lang/String;
916915
public final fun getLine ()I
917916
public final fun getPosition ()I
917+
public final fun getStart ()I
918918
public final fun pretty ()Ljava/lang/String;
919919
public fun toString ()Ljava/lang/String;
920920
}

libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/SourceLocation.kt

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,26 @@ package com.apollographql.apollo3.ast
33
import com.apollographql.apollo3.annotations.ApolloDeprecatedSince
44

55
/**
6+
* @param start the offset where the symbol starts, inclusive, starting at 0
7+
* Note that because the parser works on UTF16 Strings, the offset is in terms of UTF16 chars and not unicode Chars
8+
*
9+
* @param end the offset where the symbol ends, exclusive
10+
* Because [end] is exclusive, you can use str.substring(start, end) to get the symbol text
11+
* Note that because the parser works on UTF16 Strings, the offset is in terms of UTF16 chars and not unicode Chars
12+
*
613
* @param line the line where the symbol starts, starting at 1
714
*
815
* @param column the column where the symbol starts, starting at 1
16+
* Note that because the parser works on UTF16 Strings, the column is in terms of UTF16 chars and not unicode Chars
917
*
10-
* @param endLine the line where the symbol ends, inclusive, starting at 1
11-
*
12-
* @param endColumn the column where the symbol ends, inclusive, starting at 1
13-
* *
1418
* @param filePath The path to the document containing the node
15-
* Might be null if the document origin is not known
19+
* Might be null if the document origin is not known (parsing from a String for an example)
1620
*/
1721
class SourceLocation(
22+
val start: Int,
23+
val end: Int,
1824
val line: Int,
1925
val column: Int,
20-
val endLine: Int,
21-
val endColumn: Int,
2226
val filePath: String?
2327
) {
2428
@ApolloDeprecatedSince(ApolloDeprecatedSince.Version.v4_0_0)
@@ -35,7 +39,22 @@ class SourceLocation(
3539
companion object {
3640
@ApolloDeprecatedSince(ApolloDeprecatedSince.Version.v4_0_0)
3741
@Deprecated("SourceLocation is now nullable and this is replaced by null", ReplaceWith("null"), level = DeprecationLevel.ERROR)
38-
val UNKNOWN = SourceLocation(-1, -1, -1, -1, null)
42+
val UNKNOWN = SourceLocation.forPath(null)
43+
44+
/**
45+
* Constructs a [SourceLocation] that only contains a filePath for the moments when we're constructing nodes programmatically
46+
* but still want to carry around the path of the original nodes for debugging purposes.
47+
* TODO: I'm not sure how much this is helping vs confusing. We might want to remove that and just set a null sourceLocation in those cases
48+
*/
49+
internal fun forPath(filePath: String?): SourceLocation {
50+
return SourceLocation(
51+
start = 0,
52+
end = 1,
53+
line = -1,
54+
column = -1,
55+
filePath = filePath
56+
)
57+
}
3958
}
4059
}
4160

libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/api.kt

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,25 +27,57 @@ fun BufferedSource.toSchema(filePath: String? = null): Schema = parseAsGQLDocume
2727
* See [parseAsGQLDocument] and [validateAsExecutable] for more granular error reporting
2828
*/
2929
@ApolloExperimental
30-
fun BufferedSource.toExecutableDefinitions(schema: Schema, filePath: String? = null, fieldsOnDisjointTypesMustMerge: Boolean = true): List<GQLDefinition> = parseAsGQLDocument(filePath)
30+
fun BufferedSource.toExecutableDefinitions(
31+
schema: Schema,
32+
filePath: String? = null,
33+
fieldsOnDisjointTypesMustMerge: Boolean = true,
34+
): List<GQLDefinition> = parseAsGQLDocument(filePath)
3135
.getOrThrow()
3236
.validateAsExecutable(schema, fieldsOnDisjointTypesMustMerge)
3337
.getOrThrow()
3438

35-
private fun <T: Any> BufferedSource.parseInternal(filePath: String?, withSourceLocation: Boolean, block: Parser.() -> T): GQLResult<T> {
39+
private fun <T : Any> BufferedSource.parseInternal(filePath: String?, withSourceLocation: Boolean, block: Parser.() -> T): GQLResult<T> {
3640
return try {
3741
GQLResult(Parser(this.use { it.readUtf8() }, withSourceLocation, filePath).block(), emptyList())
3842
} catch (e: ParserException) {
39-
GQLResult(null, listOf(Issue.ParsingError(e.message, SourceLocation(e.token.line, e.token.column, -1, -1, filePath))))
43+
GQLResult(
44+
null,
45+
listOf(
46+
Issue.ParsingError(
47+
e.message,
48+
SourceLocation(
49+
start = e.token.start,
50+
end = e.token.end,
51+
line = e.token.line,
52+
column = e.token.column,
53+
filePath = filePath
54+
)
55+
)
56+
)
57+
)
4058
} catch (e: LexerException) {
41-
GQLResult(null, listOf(Issue.ParsingError(e.message, SourceLocation(e.line, e.column, -1, -1, filePath))))
59+
GQLResult(
60+
null,
61+
listOf(
62+
Issue.ParsingError(
63+
e.message,
64+
SourceLocation(
65+
start = e.pos,
66+
end = e.pos + 1,
67+
line = e.line,
68+
column = e.column,
69+
filePath = filePath
70+
)
71+
)
72+
)
73+
)
4274
}
4375
}
4476

4577
class ParserOptions(
4678
val useAntlr: Boolean = false,
4779
val allowEmptyDocuments: Boolean = true,
48-
val withSourceLocation: Boolean = true
80+
val withSourceLocation: Boolean = true,
4981
) {
5082
companion object {
5183
val Default = ParserOptions()
@@ -96,7 +128,7 @@ fun BufferedSource.parseAsGQLValue(filePath: String? = null, options: ParserOpti
96128
* Closes [BufferedSource]
97129
*/
98130
@ApolloExperimental
99-
fun BufferedSource.parseAsGQLType(filePath: String? = null, options: ParserOptions = ParserOptions.Default): GQLResult<GQLType> {
131+
fun BufferedSource.parseAsGQLType(filePath: String? = null, options: ParserOptions = ParserOptions.Default): GQLResult<GQLType> {
100132
return if (options.useAntlr) {
101133
parseTypeWithAntlr(this, filePath)
102134
} else {
@@ -110,7 +142,10 @@ fun BufferedSource.parseAsGQLType(filePath: String? = null, options: ParserOptio
110142
* Closes [BufferedSource]
111143
*/
112144
@ApolloExperimental
113-
fun BufferedSource.parseAsGQLSelections(filePath: String? = null, options: ParserOptions = ParserOptions.Default): GQLResult<List<GQLSelection>> {
145+
fun BufferedSource.parseAsGQLSelections(
146+
filePath: String? = null,
147+
options: ParserOptions = ParserOptions.Default,
148+
): GQLResult<List<GQLSelection>> {
114149
return if (options.useAntlr) {
115150
parseSelectionsWithAntlr(this, filePath)
116151
} else {
@@ -164,7 +199,7 @@ fun GQLDocument.validateAsExecutable(schema: Schema, fieldsOnDisjointTypesMustMe
164199
fun GQLFragmentDefinition.inferVariables(
165200
schema: Schema,
166201
fragments: Map<String, GQLFragmentDefinition>,
167-
fieldsOnDisjointTypesMustMerge: Boolean
202+
fieldsOnDisjointTypesMustMerge: Boolean,
168203
) = ExecutableValidationScope(schema, fragments, fieldsOnDisjointTypesMustMerge).inferFragmentVariables(this)
169204

170205

libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/gql.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ class GQLDocument(
131131
val definitions: List<GQLDefinition>,
132132
override val sourceLocation: SourceLocation?,
133133
) : GQLNode {
134-
constructor(definitions: List<GQLDefinition>, filePath: String?): this(definitions, SourceLocation(0, 0, -1, -1, filePath))
134+
constructor(definitions: List<GQLDefinition>, filePath: String?): this(definitions, SourceLocation.forPath(filePath))
135135

136136
override val children = definitions
137137

0 commit comments

Comments
 (0)