Abstract Spanning::start and Spanning::end into Span (#1207, #1208)

This commit is contained in:
Audun Halland 2023-11-09 15:04:30 +01:00 committed by GitHub
parent 761710205a
commit d0fc062892
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
39 changed files with 265 additions and 249 deletions

View file

@ -53,6 +53,7 @@ All user visible changes to `juniper` crate will be documented in this file. Thi
- Removed lifetime parameter from `ParseError`, `GraphlQLError`, `GraphQLBatchRequest` and `GraphQLRequest`. ([#1081], [#528])
- Upgraded [GraphiQL] to 3.0.9 version (requires new [`graphql-transport-ws` GraphQL over WebSocket Protocol] integration on server, see `juniper_warp/examples/subscription.rs`). ([#1188], [#1193], [#1204])
- Made `LookAheadMethods::children()` method to return slice instead of `Vec`. ([#1200])
- Abstracted `Spanning::start` and `Spanning::end` fields into separate struct `Span`. ([#1207], [#1208])
### Added
@ -131,6 +132,8 @@ All user visible changes to `juniper` crate will be documented in this file. Thi
[#1199]: /../../pull/1199
[#1200]: /../../pull/1200
[#1204]: /../../pull/1204
[#1207]: /../../pull/1207
[#1208]: /../../pull/1208
[ba1ed85b]: /../../commit/ba1ed85b3c3dd77fbae7baf6bc4e693321a94083
[CVE-2022-31173]: /../../security/advisories/GHSA-4rx6-g5vg-5f3j

View file

@ -885,7 +885,7 @@ where
schema: &root_node.schema,
context,
errors: &errors,
field_path: Arc::new(FieldPath::Root(operation.start)),
field_path: Arc::new(FieldPath::Root(operation.span.start)),
};
value = match operation.item.operation_type {
@ -983,7 +983,7 @@ where
schema: &root_node.schema,
context,
errors: &errors,
field_path: Arc::new(FieldPath::Root(operation.start)),
field_path: Arc::new(FieldPath::Root(operation.span.start)),
};
value = match operation.item.operation_type {
@ -1129,7 +1129,7 @@ where
schema: &root_node.schema,
context,
errors: &errors,
field_path: Arc::new(FieldPath::Root(operation.start)),
field_path: Arc::new(FieldPath::Root(operation.span.start)),
};
value = match operation.item.operation_type {

View file

@ -252,8 +252,8 @@ impl Serialize for Spanning<ParseError> {
map.serialize_value(&msg)?;
let mut loc = IndexMap::new();
loc.insert("line".to_owned(), self.start.line() + 1);
loc.insert("column".to_owned(), self.start.column() + 1);
loc.insert("line".to_owned(), self.start().line() + 1);
loc.insert("column".to_owned(), self.start().column() + 1);
let locations = vec![loc];
map.serialize_key("locations")?;

View file

@ -73,7 +73,7 @@ pub use crate::{
},
introspection::IntrospectionFormat,
macros::helper::subscription::{ExtractTypeFromStream, IntoFieldResult},
parser::{ParseError, ScalarToken, Spanning},
parser::{ParseError, ScalarToken, Span, Spanning},
schema::{
meta,
model::{RootNode, SchemaType},

View file

@ -82,9 +82,8 @@ where
let fields = fields.as_ref().map(|c| c as &[_]);
let selection_set = parse_selection_set(parser, schema, fields)?;
Ok(Spanning::start_end(
&selection_set.start,
&selection_set.end,
Ok(Spanning::new(
selection_set.span,
Operation {
operation_type: OperationType::Query,
name: None,
@ -94,7 +93,7 @@ where
},
))
} else {
let start_pos = parser.peek().start;
let start_pos = parser.peek().span.start;
let operation_type = parse_operation_type(parser)?;
let op = match operation_type.item {
OperationType::Query => Some(schema.concrete_query_type()),
@ -114,7 +113,7 @@ where
Ok(Spanning::start_end(
&start_pos,
&selection_set.end,
&selection_set.span.end,
Operation {
operation_type: operation_type.item,
name,
@ -133,9 +132,7 @@ fn parse_fragment_definition<'a, 'b, S>(
where
S: ScalarValue,
{
let Spanning {
start: start_pos, ..
} = parser.expect(&Token::Name("fragment"))?;
let start_pos = parser.expect(&Token::Name("fragment"))?.span.start;
let name = match parser.expect_name() {
Ok(n) => {
if n.item == "on" {
@ -160,7 +157,7 @@ where
Ok(Spanning::start_end(
&start_pos,
&selection_set.end,
&selection_set.span.end,
Fragment {
name,
type_condition: type_cond,
@ -222,10 +219,7 @@ fn parse_fragment<'a, 'b, S>(
where
S: ScalarValue,
{
let Spanning {
start: ref start_pos,
..
} = parser.expect(&Token::Ellipsis)?;
let start_pos = parser.expect(&Token::Ellipsis)?.span.start;
match parser.peek().item {
Token::Name("on") => {
@ -240,8 +234,8 @@ where
let selection_set = parse_selection_set(parser, schema, fields)?;
Ok(Selection::InlineFragment(Spanning::start_end(
&start_pos.clone(),
&selection_set.end,
&start_pos,
&selection_set.span.end,
InlineFragment {
type_condition: Some(name),
directives: directives.map(|s| s.item),
@ -253,8 +247,8 @@ where
let selection_set = parse_selection_set(parser, schema, fields)?;
Ok(Selection::InlineFragment(Spanning::start_end(
&start_pos.clone(),
&selection_set.end,
&start_pos,
&selection_set.span.end,
InlineFragment {
type_condition: None,
directives: None,
@ -270,7 +264,7 @@ where
&start_pos.clone(),
&directives
.as_ref()
.map_or(&frag_name.end, |s| &s.end)
.map_or(&frag_name.span.end, |s| &s.span.end)
.clone(),
FragmentSpread {
name: frag_name,
@ -283,8 +277,8 @@ where
let selection_set = parse_selection_set(parser, schema, fields)?;
Ok(Selection::InlineFragment(Spanning::start_end(
&start_pos.clone(),
&selection_set.end,
&start_pos,
&selection_set.span.end,
InlineFragment {
type_condition: None,
directives: directives.map(|s| s.item),
@ -329,13 +323,13 @@ where
let selection_set = parse_optional_selection_set(parser, schema, fields)?;
Ok(Spanning::start_end(
&alias.as_ref().unwrap_or(&name).start.clone(),
&alias.as_ref().unwrap_or(&name).span.start,
&selection_set
.as_ref()
.map(|s| &s.end)
.or_else(|| directives.as_ref().map(|s| &s.end))
.or_else(|| arguments.as_ref().map(|s| &s.end))
.unwrap_or(&name.end)
.map(|s| &s.span.end)
.or_else(|| directives.as_ref().map(|s| &s.span.end))
.or_else(|| arguments.as_ref().map(|s| &s.span.end))
.unwrap_or(&name.span.end)
.clone(),
Field {
alias,
@ -389,8 +383,8 @@ where
let value = parse_value_literal(parser, false, schema, tpe)?;
Ok(Spanning::start_end(
&name.start.clone(),
&value.end.clone(),
&name.span.start,
&value.span.end.clone(),
(name, value),
))
}
@ -437,9 +431,7 @@ fn parse_variable_definition<'a, 'b, S>(
where
S: ScalarValue,
{
let Spanning {
start: start_pos, ..
} = parser.expect(&Token::Dollar)?;
let start_pos = parser.expect(&Token::Dollar)?.span.start;
let var_name = parser.expect_name()?;
parser.expect(&Token::Colon)?;
let var_type = parse_type(parser)?;
@ -457,10 +449,10 @@ where
&start_pos,
&default_value
.as_ref()
.map_or(&var_type.end, |s| &s.end)
.map_or(&var_type.span.end, |s| &s.span.end)
.clone(),
(
Spanning::start_end(&start_pos, &var_name.end, var_name.item),
Spanning::start_end(&start_pos, &var_name.span.end, var_name.item),
VariableDefinition {
var_type,
default_value,
@ -496,9 +488,7 @@ fn parse_directive<'a, 'b, S>(
where
S: ScalarValue,
{
let Spanning {
start: start_pos, ..
} = parser.expect(&Token::At)?;
let start_pos = parser.expect(&Token::At)?.span.start;
let name = parser.expect_name()?;
let directive = schema.directive_by_name(name.item);
@ -511,20 +501,24 @@ where
Ok(Spanning::start_end(
&start_pos,
&arguments.as_ref().map_or(&name.end, |s| &s.end).clone(),
&arguments
.as_ref()
.map_or(&name.span.end, |s| &s.span.end)
.clone(),
Directive { name, arguments },
))
}
pub fn parse_type<'a>(parser: &mut Parser<'a>) -> ParseResult<Type<'a>> {
let parsed_type = if let Some(Spanning {
start: start_pos, ..
span: ref start_span,
..
}) = parser.skip(&Token::BracketOpen)?
{
let inner_type = parse_type(parser)?;
let Spanning { end: end_pos, .. } = parser.expect(&Token::BracketClose)?;
let end_pos = parser.expect(&Token::BracketClose)?.span.end;
Spanning::start_end(
&start_pos,
&start_span.start,
&end_pos,
Type::List(Box::new(inner_type.item), None),
)
@ -542,7 +536,7 @@ pub fn parse_type<'a>(parser: &mut Parser<'a>) -> ParseResult<Type<'a>> {
}
fn wrap_non_null<'a>(parser: &mut Parser<'a>, inner: Spanning<Type<'a>>) -> ParseResult<Type<'a>> {
let Spanning { end: end_pos, .. } = parser.expect(&Token::ExclamationMark)?;
let end_pos = &parser.expect(&Token::ExclamationMark)?.span.end;
let wrapped = match inner.item {
Type::Named(name) => Type::NonNullNamed(name),
@ -550,5 +544,5 @@ fn wrap_non_null<'a>(parser: &mut Parser<'a>, inner: Spanning<Type<'a>>) -> Pars
t => t,
};
Ok(Spanning::start_end(&inner.start, &end_pos, wrapped))
Ok(Spanning::start_end(&inner.span.start, end_pos, wrapped))
}

View file

@ -15,5 +15,5 @@ pub use self::document::parse_document_source;
pub use self::{
lexer::{Lexer, LexerError, ScalarToken, Token},
parser::{OptionParseResult, ParseError, ParseResult, Parser, UnlocatedParseResult},
utils::{SourcePosition, Spanning},
utils::{SourcePosition, Span, Spanning},
};

View file

@ -97,9 +97,8 @@ impl<'a> Parser<'a> {
#[doc(hidden)]
pub fn next_token(&mut self) -> ParseResult<Token<'a>> {
if self.tokens.len() == 1 {
Err(Spanning::start_end(
&self.peek().start,
&self.peek().end,
Err(Spanning::new(
self.peek().span,
ParseError::UnexpectedEndOfFile,
))
} else {
@ -125,7 +124,7 @@ impl<'a> Parser<'a> {
Ok(Some(self.next_token()?))
} else if self.peek().item == Token::EndOfFile {
Err(Spanning::zero_width(
&self.peek().start,
&self.peek().span.start,
ParseError::UnexpectedEndOfFile,
))
} else {
@ -144,14 +143,12 @@ impl<'a> Parser<'a> {
T: fmt::Debug,
F: Fn(&mut Parser<'a>) -> ParseResult<T>,
{
let Spanning {
start: start_pos, ..
} = self.expect(opening)?;
let start_pos = &self.expect(opening)?.span.start;
let mut items = Vec::new();
loop {
if let Some(Spanning { end: end_pos, .. }) = self.skip(closing)? {
return Ok(Spanning::start_end(&start_pos, &end_pos, items));
if let Some(Spanning { span, .. }) = self.skip(closing)? {
return Ok(Spanning::start_end(start_pos, &span.end, items));
}
items.push(parser(self)?);
@ -169,16 +166,14 @@ impl<'a> Parser<'a> {
T: fmt::Debug,
F: Fn(&mut Parser<'a>) -> ParseResult<T>,
{
let Spanning {
start: start_pos, ..
} = self.expect(opening)?;
let start_pos = &self.expect(opening)?.span.start;
let mut items = Vec::new();
loop {
items.push(parser(self)?);
if let Some(Spanning { end: end_pos, .. }) = self.skip(closing)? {
return Ok(Spanning::start_end(&start_pos, &end_pos, items));
if let Some(end_spanning) = self.skip(closing)? {
return Ok(Spanning::start_end(start_pos, &end_spanning.end(), items));
}
}
}
@ -194,16 +189,14 @@ impl<'a> Parser<'a> {
T: fmt::Debug,
F: Fn(&mut Parser<'a>) -> UnlocatedParseResult<T>,
{
let Spanning {
start: start_pos, ..
} = self.expect(opening)?;
let start_pos = &self.expect(opening)?.span.start;
let mut items = Vec::new();
loop {
items.push(parser(self)?);
if let Some(Spanning { end: end_pos, .. }) = self.skip(closing)? {
return Ok(Spanning::start_end(&start_pos, &end_pos, items));
if let Some(end_spanning) = self.skip(closing)? {
return Ok(Spanning::start_end(start_pos, &end_spanning.end(), items));
}
}
}
@ -224,9 +217,8 @@ impl<'a> Parser<'a> {
Spanning {
item: Token::EndOfFile,
..
} => Err(Spanning::start_end(
&self.peek().start,
&self.peek().end,
} => Err(Spanning::new(
self.peek().span,
ParseError::UnexpectedEndOfFile,
)),
_ => Err(self.next_token()?.map(ParseError::unexpected_token)),

View file

@ -342,8 +342,8 @@ fn numbers() {
expected: &str,
) {
let parsed = tokenize_single(source);
assert_eq!(parsed.start, start);
assert_eq!(parsed.end, end);
assert_eq!(parsed.span.start, start);
assert_eq!(parsed.span.end, end);
match parsed.item {
Token::Scalar(ScalarToken::Float(actual)) => {

View file

@ -8,65 +8,90 @@ pub struct SourcePosition {
col: usize,
}
/// Data structure used to wrap items with start and end markers in the input source
///
/// A "span" is a range of characters in the input source, starting at the
/// character pointed by the `start` field and ending just before the `end`
/// marker.
#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
pub struct Spanning<T> {
/// The wrapped item
pub item: T,
/// Start position of the item
/// Range of characters in the input source, starting at the character pointed by the `start` field
/// and ending just before the `end` marker.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct Span {
/// Start position of this [`Span`].
pub start: SourcePosition,
/// End position of the item
/// End position of this [`Span`].
///
/// This points to the first source position _after_ the wrapped item.
/// > __NOTE__: This points to the first source position __after__ this [`Span`].
pub end: SourcePosition,
}
impl Span {
#[doc(hidden)]
#[inline]
pub fn zero_width(pos: SourcePosition) -> Self {
Self {
start: pos,
end: pos,
}
}
#[doc(hidden)]
#[inline]
pub fn single_width(pos: SourcePosition) -> Self {
let mut end = pos;
end.advance_col();
Self { start: pos, end }
}
#[doc(hidden)]
#[inline]
pub fn unlocated() -> Self {
Self {
start: SourcePosition::new_origin(),
end: SourcePosition::new_origin(),
}
}
}
/// Data structure used to wrap items into a [`Span`].
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct Spanning<T> {
/// Wrapped item.
pub item: T,
/// [`Span`] of the wrapped item.
pub span: Span,
}
impl<T> Spanning<T> {
#[doc(hidden)]
pub fn zero_width(pos: &SourcePosition, item: T) -> Spanning<T> {
Spanning {
item,
start: *pos,
end: *pos,
}
pub fn new(span: Span, item: T) -> Self {
Self { item, span }
}
#[doc(hidden)]
pub fn single_width(pos: &SourcePosition, item: T) -> Spanning<T> {
let mut end = *pos;
end.advance_col();
Spanning {
item,
start: *pos,
end,
}
pub fn zero_width(&pos: &SourcePosition, item: T) -> Spanning<T> {
Self::new(Span::zero_width(pos), item)
}
#[doc(hidden)]
pub fn start_end(start: &SourcePosition, end: &SourcePosition, item: T) -> Spanning<T> {
Spanning {
item,
start: *start,
end: *end,
pub fn single_width(&pos: &SourcePosition, item: T) -> Spanning<T> {
Self::new(Span::single_width(pos), item)
}
#[doc(hidden)]
pub fn start_end(&start: &SourcePosition, &end: &SourcePosition, item: T) -> Spanning<T> {
Self::new(Span { start, end }, item)
}
#[doc(hidden)]
#[allow(clippy::self_named_constructors)]
pub fn spanning(v: Vec<Spanning<T>>) -> Option<Spanning<Vec<Spanning<T>>>> {
if let (Some(start), Some(end)) = (v.first().map(|s| s.start), v.last().map(|s| s.end)) {
Some(Spanning {
item: v,
start,
end,
})
if let (Some(start), Some(end)) = (v.first().map(|s| s.span), v.last().map(|s| s.span)) {
Some(Spanning::new(
Span {
start: start.start,
end: end.end,
},
v,
))
} else {
None
}
@ -74,33 +99,38 @@ impl<T> Spanning<T> {
#[doc(hidden)]
pub fn unlocated(item: T) -> Spanning<T> {
Spanning {
item,
start: SourcePosition::new_origin(),
end: SourcePosition::new_origin(),
Self::new(Span::unlocated(), item)
}
/// Returns start position of the item.
#[inline]
pub fn start(&self) -> SourcePosition {
self.span.start
}
/// Returns end position of the item.
///
/// > __NOTE__: This points to the first source position __after__ the item.
#[inline]
pub fn end(&self) -> SourcePosition {
self.span.end
}
/// Modify the contents of the spanned item.
pub fn map<O, F: Fn(T) -> O>(self, f: F) -> Spanning<O> {
Spanning {
item: f(self.item),
start: self.start,
end: self.end,
}
Spanning::new(self.span, f(self.item))
}
/// Modifies the contents of the spanned item in case `f` returns [`Some`],
/// or returns [`None`] otherwise.
pub fn and_then<O, F: Fn(T) -> Option<O>>(self, f: F) -> Option<Spanning<O>> {
let (start, end) = (self.start, self.end);
f(self.item).map(|item| Spanning { item, start, end })
f(self.item).map(|item| Spanning::new(self.span, item))
}
}
impl<T: fmt::Display> fmt::Display for Spanning<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}. At {}", self.item, self.start)
write!(f, "{}. At {}", self.item, self.span.start)
}
}

View file

@ -1,7 +1,7 @@
use crate::ast::InputValue;
use crate::{
parser::{ParseError, ParseResult, Parser, ScalarToken, SourcePosition, Spanning, Token},
parser::{ParseError, ParseResult, Parser, ScalarToken, Spanning, Token},
schema::{
meta::{InputObjectMeta, MetaType},
model::SchemaType,
@ -9,6 +9,8 @@ use crate::{
value::ScalarValue,
};
use super::utils::Span;
pub fn parse_value_literal<'b, S>(
parser: &mut Parser<'_>,
is_const: bool,
@ -56,13 +58,12 @@ where
) => {
if let Spanning {
item: Token::Scalar(scalar),
start,
end,
span,
} = parser.next_token()?
{
(s.parse_fn)(scalar)
.map(|s| Spanning::start_end(&start, &end, InputValue::Scalar(s)))
.or_else(|_| parse_scalar_literal_by_infered_type(scalar, &start, &end, schema))
.map(|s| Spanning::new(span, InputValue::Scalar(s)))
.or_else(|_| parse_scalar_literal_by_infered_type(scalar, span, schema))
} else {
unreachable!()
}
@ -76,11 +77,10 @@ where
) => {
if let Spanning {
item: Token::Scalar(token),
start,
end,
span,
} = parser.next_token()?
{
parse_scalar_literal_by_infered_type(token, &start, &end, schema)
parse_scalar_literal_by_infered_type(token, span, schema)
} else {
unreachable!()
}
@ -173,8 +173,8 @@ where
let value = parse_value_literal(parser, is_const, schema, tpe)?;
Ok(Spanning::start_end(
&key.start,
&value.end.clone(),
&key.span.start,
&value.span.end.clone(),
(key.map(|s| s.to_owned()), value),
))
}
@ -183,26 +183,23 @@ fn parse_variable_literal<S>(parser: &mut Parser<'_>) -> ParseResult<InputValue<
where
S: ScalarValue,
{
let Spanning {
start: start_pos, ..
} = parser.expect(&Token::Dollar)?;
let start_pos = &parser.expect(&Token::Dollar)?.span.start;
let Spanning {
item: name,
end: end_pos,
span: end_span,
..
} = parser.expect_name()?;
Ok(Spanning::start_end(
&start_pos,
&end_pos,
start_pos,
&end_span.end,
InputValue::variable(name),
))
}
fn parse_scalar_literal_by_infered_type<'b, S>(
token: ScalarToken<'_>,
start: &SourcePosition,
end: &SourcePosition,
span: Span,
schema: &'b SchemaType<'b, S>,
) -> ParseResult<InputValue<S>>
where
@ -238,6 +235,6 @@ where
}
};
result
.map(|s| Spanning::start_end(start, end, s))
.map_err(|e| Spanning::start_end(start, end, e))
.map(|s| Spanning::new(span, s))
.map_err(|e| Spanning::new(span, e))
}

View file

@ -207,8 +207,7 @@ where
match *selection {
Selection::Field(Spanning {
item: ref f,
start: ref start_pos,
..
ref span,
}) => {
if is_excluded(&f.directives, executor.variables()) {
continue;
@ -237,7 +236,7 @@ where
let sub_exec = executor.field_sub_executor(
response_name,
f.name.item,
*start_pos,
span.start,
f.selection_set.as_ref().map(|v| &v[..]),
);
let args = Arguments::new(
@ -252,7 +251,7 @@ where
&meta_field.arguments,
);
let pos = *start_pos;
let pos = span.start;
let is_non_null = meta_field.field_type.is_non_null();
let response_name = response_name.to_string();
@ -285,8 +284,7 @@ where
Selection::FragmentSpread(Spanning {
item: ref spread,
start: ref start_pos,
..
ref span,
}) => {
if is_excluded(&spread.directives, executor.variables()) {
continue;
@ -327,15 +325,14 @@ where
));
}
} else if let Err(e) = sub_result {
sub_exec.push_error_at(e, *start_pos);
sub_exec.push_error_at(e, span.start);
}
}
}
Selection::InlineFragment(Spanning {
item: ref fragment,
start: ref start_pos,
..
ref span,
}) => {
if is_excluded(&fragment.directives, executor.variables()) {
continue;
@ -372,7 +369,7 @@ where
));
}
} else if let Err(e) = sub_result {
sub_exec.push_error_at(e, *start_pos);
sub_exec.push_error_at(e, span.start);
}
}
} else {

View file

@ -431,8 +431,7 @@ where
match *selection {
Selection::Field(Spanning {
item: ref f,
start: ref start_pos,
..
ref span,
}) => {
if is_excluded(&f.directives, executor.variables()) {
continue;
@ -461,7 +460,7 @@ where
let sub_exec = executor.field_sub_executor(
response_name,
f.name.item,
*start_pos,
span.start,
f.selection_set.as_ref().map(|v| &v[..]),
);
@ -486,7 +485,7 @@ where
Ok(Value::Null) if meta_field.field_type.is_non_null() => return false,
Ok(v) => merge_key_into(result, response_name, v),
Err(e) => {
sub_exec.push_error_at(e, *start_pos);
sub_exec.push_error_at(e, span.start);
if meta_field.field_type.is_non_null() {
return false;
@ -498,8 +497,7 @@ where
}
Selection::FragmentSpread(Spanning {
item: ref spread,
start: ref start_pos,
..
span,
}) => {
if is_excluded(&spread.directives, executor.variables()) {
continue;
@ -533,14 +531,13 @@ where
merge_key_into(result, &k, v);
}
} else if let Err(e) = sub_result {
sub_exec.push_error_at(e, *start_pos);
sub_exec.push_error_at(e, span.start);
}
}
}
Selection::InlineFragment(Spanning {
item: ref fragment,
start: ref start_pos,
..
ref span,
}) => {
if is_excluded(&fragment.directives, executor.variables()) {
continue;
@ -570,7 +567,7 @@ where
merge_key_into(result, &k, v);
}
} else if let Err(e) = sub_result {
sub_exec.push_error_at(e, *start_pos);
sub_exec.push_error_at(e, span.start);
}
}
} else if !resolve_selection_set_into(

View file

@ -283,8 +283,7 @@ where
match selection {
Selection::Field(Spanning {
item: ref f,
start: ref start_pos,
..
ref span,
}) => {
if is_excluded(&f.directives, executor.variables()) {
continue;
@ -308,7 +307,7 @@ where
let sub_exec = executor.field_sub_executor(
response_name,
f.name.item,
*start_pos,
span.start,
f.selection_set.as_ref().map(|x| &x[..]),
);
@ -336,7 +335,7 @@ where
}
Ok(v) => merge_key_into(&mut object, response_name, v),
Err(e) => {
sub_exec.push_error_at(e, *start_pos);
sub_exec.push_error_at(e, span.start);
if meta_field.field_type.is_non_null() {
return Value::Null;
@ -349,8 +348,7 @@ where
Selection::FragmentSpread(Spanning {
item: ref spread,
start: ref start_pos,
..
ref span,
}) => {
if is_excluded(&spread.directives, executor.variables()) {
continue;
@ -382,14 +380,13 @@ where
_ => unreachable!(),
}
}
Err(e) => sub_exec.push_error_at(e, *start_pos),
Err(e) => sub_exec.push_error_at(e, span.start),
}
}
Selection::InlineFragment(Spanning {
item: ref fragment,
start: ref start_pos,
..
ref span,
}) => {
if is_excluded(&fragment.directives, executor.variables()) {
continue;
@ -410,7 +407,7 @@ where
merge_key_into(&mut object, &k, v);
}
} else if let Err(e) = sub_result {
sub_exec.push_error_at(e, *start_pos);
sub_exec.push_error_at(e, span.start);
}
} else if let Some(type_name) = meta_type.name() {
let sub_result = instance
@ -422,7 +419,7 @@ where
merge_key_into(&mut object, &k, v);
}
} else if let Err(e) = sub_result {
sub_exec.push_error_at(e, *start_pos);
sub_exec.push_error_at(e, span.start);
}
} else {
return Value::Null;

View file

@ -58,12 +58,12 @@ fn validate_var_defs<S>(
r#"Variable "${}" of required type "{}" was not provided."#,
name.item, def.var_type.item,
),
&[name.start],
&[name.span.start],
));
} else if let Some(v) = values.get(name.item) {
errors.append(&mut unify_value(
name.item,
&name.start,
&name.span.start,
v,
&ct,
schema,

View file

@ -61,7 +61,7 @@ where
if !is_valid_literal_value(ctx.schema, &meta_type, &arg_value.item) {
ctx.report_error(
&error_message(arg_name.item, &argument_meta.arg_type),
&[arg_value.start],
&[arg_value.span.start],
);
}
}

View file

@ -25,14 +25,13 @@ where
) {
if let Some(Spanning {
item: ref var_value,
ref start,
..
ref span,
}) = var_def.default_value
{
if var_def.var_type.item.is_non_null() {
ctx.report_error(
&non_null_error_message(var_name.item, &var_def.var_type.item),
&[*start],
&[span.start],
)
} else {
let meta_type = ctx.schema.make_type(&var_def.var_type.item);
@ -40,7 +39,7 @@ where
if !is_valid_literal_value(ctx.schema, &meta_type, var_value) {
ctx.report_error(
&type_error_message(var_name.item, &var_def.var_type.item),
&[*start],
&[span.start],
);
}
}

View file

@ -30,7 +30,7 @@ where
context.report_error(
"`__typename` may not be included as a root \
field in a subscription operation",
&[field.item.name.start],
&[field.item.name.span.start],
);
}
}
@ -60,7 +60,7 @@ where
context.report_error(
&error_message(field_name.item, type_name),
&[field_name.start],
&[field_name.span.start],
);
}
}

View file

@ -28,7 +28,7 @@ where
context.report_error(
&error_message(Some(f.item.name.item), type_name),
&[type_cond.start],
&[type_cond.span.start],
);
}
}
@ -50,7 +50,7 @@ where
.next();
if let Some(name) = invalid_type_name {
context.report_error(&error_message(None, name), &[type_cond.start]);
context.report_error(&error_message(None, name), &[type_cond.span.start]);
}
}
}

View file

@ -84,7 +84,7 @@ where
}
};
ctx.report_error(&message, &[arg_name.start]);
ctx.report_error(&message, &[arg_name.span.start]);
}
}
}

View file

@ -143,12 +143,15 @@ where
{
ctx.report_error(
&misplaced_error_message(directive_name, current_location),
&[directive.start],
&[directive.span.start],
);
}
}
} else {
ctx.report_error(&unknown_error_message(directive_name), &[directive.start]);
ctx.report_error(
&unknown_error_message(directive_name),
&[directive.span.start],
);
}
}
}

View file

@ -22,7 +22,7 @@ where
) {
let spread_name = &spread.item.name;
if !context.is_known_fragment(spread_name.item) {
context.report_error(&error_message(spread_name.item), &[spread_name.start]);
context.report_error(&error_message(spread_name.item), &[spread_name.span.start]);
}
}
}

View file

@ -22,7 +22,7 @@ where
fragment: &'a Spanning<InlineFragment<S>>,
) {
if let Some(ref type_cond) = fragment.item.type_condition {
validate_type(ctx, type_cond.item, &type_cond.start);
validate_type(ctx, type_cond.item, &type_cond.span.start);
}
}
@ -32,7 +32,7 @@ where
fragment: &'a Spanning<Fragment<S>>,
) {
let type_cond = &fragment.item.type_condition;
validate_type(ctx, type_cond.item, &type_cond.start);
validate_type(ctx, type_cond.item, &type_cond.span.start);
}
fn enter_variable_definition(
@ -41,7 +41,7 @@ where
(_, var_def): &'a (Spanning<&'a str>, VariableDefinition<S>),
) {
let type_name = var_def.var_type.item.innermost_name();
validate_type(ctx, type_name, &var_def.var_type.start);
validate_type(ctx, type_name, &var_def.var_type.span.start);
}
}

View file

@ -37,7 +37,7 @@ where
) {
if let Some(operation_count) = self.operation_count {
if operation_count > 1 && op.item.name.is_none() {
ctx.report_error(error_message(), &[op.start]);
ctx.report_error(error_message(), &[op.span.start]);
}
}
}

View file

@ -73,11 +73,7 @@ where
self.spreads
.entry(current_fragment)
.or_default()
.push(Spanning::start_end(
&spread.start,
&spread.end,
spread.item.name.item,
));
.push(Spanning::new(spread.span, spread.item.name.item));
}
}
}
@ -131,7 +127,7 @@ impl<'a> CycleDetector<'a> {
};
self.errors
.push(RuleError::new(&error_message(name), &[err_pos.start]));
.push(RuleError::new(&error_message(name), &[err_pos.span.start]));
} else {
let mut path = path.clone();
path.push(node);

View file

@ -99,7 +99,7 @@ where
unused
.into_iter()
.map(|var| {
RuleError::new(&error_message(var.item, *op_name), &[var.start, *pos])
RuleError::new(&error_message(var.item, *op_name), &[var.span.start, *pos])
})
.collect(),
);
@ -114,7 +114,7 @@ where
let op_name = op.item.name.as_ref().map(|s| s.item);
self.current_scope = Some(Scope::Operation(op_name));
self.defined_variables
.insert(op_name, (op.start, HashSet::new()));
.insert(op_name, (op.span.start, HashSet::new()));
}
fn enter_fragment_definition(
@ -164,7 +164,7 @@ where
.item
.referenced_variables()
.iter()
.map(|&var_name| Spanning::start_end(&value.start, &value.end, var_name))
.map(|&var_name| Spanning::new(value.span, var_name))
.collect(),
);
}

View file

@ -80,7 +80,7 @@ where
for fragment in &self.defined_fragments {
if !reachable.contains(&fragment.item) {
ctx.report_error(&error_message(fragment.item), &[fragment.start]);
ctx.report_error(&error_message(fragment.item), &[fragment.span.start]);
}
}
}
@ -101,7 +101,7 @@ where
) {
self.current_scope = Some(Scope::Fragment(f.item.name.item));
self.defined_fragments
.insert(Spanning::start_end(&f.start, &f.end, f.item.name.item));
.insert(Spanning::new(f.span, f.item.name.item));
}
fn enter_fragment_spread(

View file

@ -99,7 +99,9 @@ where
def_vars
.iter()
.filter(|var| !used.contains(var.item))
.map(|var| RuleError::new(&error_message(var.item, *op_name), &[var.start]))
.map(|var| {
RuleError::new(&error_message(var.item, *op_name), &[var.span.start])
})
.collect(),
);
}

View file

@ -406,8 +406,8 @@ impl<'a, S: Debug> OverlappingFieldsCanBeMerged<'a, S> {
"{name1} and {name2} are different fields",
)),
),
vec![ast1.start],
vec![ast2.start],
vec![ast1.span.start],
vec![ast2.span.start],
));
}
@ -417,8 +417,8 @@ impl<'a, S: Debug> OverlappingFieldsCanBeMerged<'a, S> {
response_name.into(),
ConflictReasonMessage::Message("they have differing arguments".into()),
),
vec![ast1.start],
vec![ast2.start],
vec![ast1.span.start],
vec![ast2.span.start],
));
}
}
@ -435,8 +435,8 @@ impl<'a, S: Debug> OverlappingFieldsCanBeMerged<'a, S> {
"they return conflicting types {t1} and {t2}",
)),
),
vec![ast1.start],
vec![ast2.start],
vec![ast1.span.start],
vec![ast2.span.start],
));
}
}
@ -451,7 +451,12 @@ impl<'a, S: Debug> OverlappingFieldsCanBeMerged<'a, S> {
ctx,
);
return self.subfield_conflicts(&conflicts, response_name, &ast1.start, &ast2.start);
return self.subfield_conflicts(
&conflicts,
response_name,
&ast1.span.start,
&ast2.span.start,
);
}
None

View file

@ -70,7 +70,7 @@ where
parent_type.name().unwrap_or("<unknown>"),
frag_type.name().unwrap_or("<unknown>"),
),
&[frag.start],
&[frag.span.start],
);
}
}
@ -109,7 +109,7 @@ where
parent_type.name().unwrap_or("<unknown>"),
frag_type.name().unwrap_or("<unknown>"),
),
&[spread.start],
&[spread.span.start],
);
}
}

View file

@ -38,7 +38,7 @@ where
{
ctx.report_error(
&field_error_message(field_name, &meta_arg.name, &meta_arg.arg_type),
&[field.start],
&[field.span.start],
);
}
}
@ -72,7 +72,7 @@ where
&meta_arg.name,
&meta_arg.arg_type,
),
&[directive.start],
&[directive.span.start],
);
}
}

View file

@ -26,11 +26,11 @@ where
match (field_type.is_leaf(), &field.item.selection_set) {
(true, &Some(_)) => Some(RuleError::new(
&no_allowed_error_message(field_name, field_type_literal),
&[field.start],
&[field.span.start],
)),
(false, &None) => Some(RuleError::new(
&required_error_message(field_name, field_type_literal),
&[field.start],
&[field.span.start],
)),
_ => None,
}

View file

@ -36,10 +36,13 @@ where
) {
match self.known_names.entry(arg_name.item) {
Entry::Occupied(e) => {
ctx.report_error(&error_message(arg_name.item), &[*e.get(), arg_name.start]);
ctx.report_error(
&error_message(arg_name.item),
&[*e.get(), arg_name.span.start],
);
}
Entry::Vacant(e) => {
e.insert(arg_name.start);
e.insert(arg_name.span.start);
}
}
}

View file

@ -30,11 +30,11 @@ where
Entry::Occupied(e) => {
context.report_error(
&duplicate_message(f.item.name.item),
&[*e.get(), f.item.name.start],
&[*e.get(), f.item.name.span.start],
);
}
Entry::Vacant(e) => {
e.insert(f.item.name.start);
e.insert(f.item.name.span.start);
}
}
}

View file

@ -39,11 +39,11 @@ where
Entry::Occupied(e) => {
ctx.report_error(
&error_message(&field_name.item),
&[*e.get(), field_name.start],
&[*e.get(), field_name.span.start],
);
}
Entry::Vacant(e) => {
e.insert(field_name.start);
e.insert(field_name.span.start);
}
}
}

View file

@ -29,10 +29,10 @@ where
if let Some(ref op_name) = op.item.name {
match self.names.entry(op_name.item) {
Entry::Occupied(e) => {
ctx.report_error(&error_message(op_name.item), &[*e.get(), op.start]);
ctx.report_error(&error_message(op_name.item), &[*e.get(), op.span.start]);
}
Entry::Vacant(e) => {
e.insert(op.start);
e.insert(op.span.start);
}
}
}

View file

@ -36,10 +36,13 @@ where
) {
match self.names.entry(var_name.item) {
Entry::Occupied(e) => {
ctx.report_error(&error_message(var_name.item), &[*e.get(), var_name.start]);
ctx.report_error(
&error_message(var_name.item),
&[*e.get(), var_name.span.start],
);
}
Entry::Vacant(e) => {
e.insert(var_name.start);
e.insert(var_name.span.start);
}
}
}

View file

@ -29,7 +29,7 @@ where
if !var_type.is_input() {
ctx.report_error(
&error_message(var_name.item, &var_def.var_type.item),
&[var_def.var_type.start],
&[var_def.var_type.span.start],
);
}
}

View file

@ -94,7 +94,7 @@ impl<'a, S: fmt::Debug> VariableInAllowedPosition<'a, S> {
if !ctx.schema.is_subtype(&expected_type, var_type) {
ctx.report_error(
&error_message(var_name.item, expected_type, var_type),
&[var_def_name.start, var_name.start],
&[var_def_name.span.start, var_name.span.start],
);
}
}
@ -169,7 +169,7 @@ where
.entry(scope.clone())
.or_default()
.push((
Spanning::start_end(&var_name.start, &var_name.end, var_name.item),
Spanning::new(var_name.span, var_name.item),
input_type.clone(),
));
}

View file

@ -377,16 +377,15 @@ fn enter_input_value<'a, S, V>(
{
use crate::InputValue::*;
let start = &input_value.start;
let end = &input_value.end;
let span = input_value.span;
match input_value.item {
Null => v.enter_null_value(ctx, Spanning::start_end(start, end, ())),
Scalar(ref s) => v.enter_scalar_value(ctx, Spanning::start_end(start, end, s)),
Enum(ref s) => v.enter_enum_value(ctx, Spanning::start_end(start, end, s)),
Variable(ref s) => v.enter_variable_value(ctx, Spanning::start_end(start, end, s)),
List(ref l) => v.enter_list_value(ctx, Spanning::start_end(start, end, l)),
Object(ref o) => v.enter_object_value(ctx, Spanning::start_end(start, end, o)),
Null => v.enter_null_value(ctx, Spanning::new(span, ())),
Scalar(ref s) => v.enter_scalar_value(ctx, Spanning::new(span, s)),
Enum(ref s) => v.enter_enum_value(ctx, Spanning::new(span, s)),
Variable(ref s) => v.enter_variable_value(ctx, Spanning::new(span, s)),
List(ref l) => v.enter_list_value(ctx, Spanning::new(span, l)),
Object(ref o) => v.enter_object_value(ctx, Spanning::new(span, o)),
}
}
@ -400,15 +399,14 @@ fn exit_input_value<'a, S, V>(
{
use crate::InputValue::*;
let start = &input_value.start;
let end = &input_value.end;
let span = input_value.span;
match input_value.item {
Null => v.exit_null_value(ctx, Spanning::start_end(start, end, ())),
Scalar(ref s) => v.exit_scalar_value(ctx, Spanning::start_end(start, end, s)),
Enum(ref s) => v.exit_enum_value(ctx, Spanning::start_end(start, end, s)),
Variable(ref s) => v.exit_variable_value(ctx, Spanning::start_end(start, end, s)),
List(ref l) => v.exit_list_value(ctx, Spanning::start_end(start, end, l)),
Object(ref o) => v.exit_object_value(ctx, Spanning::start_end(start, end, o)),
Null => v.exit_null_value(ctx, Spanning::new(span, ())),
Scalar(ref s) => v.exit_scalar_value(ctx, Spanning::new(span, s)),
Enum(ref s) => v.exit_enum_value(ctx, Spanning::new(span, s)),
Variable(ref s) => v.exit_variable_value(ctx, Spanning::new(span, s)),
List(ref l) => v.exit_list_value(ctx, Spanning::new(span, l)),
Object(ref o) => v.exit_object_value(ctx, Spanning::new(span, o)),
}
}