Improve parser performance.

This commit is contained in:
sunli 2020-05-10 10:59:51 +08:00
parent d343c0c2f6
commit bc2966bc0d
38 changed files with 494 additions and 383 deletions

View File

@ -287,7 +287,7 @@ pub fn generate(interface_args: &args::Interface, input: &DeriveInput) -> Result
fn collect_inline_fields<'a>(
&'a self,
name: &#crate_name::Spanned<String>,
name: &#crate_name::Positioned<String>,
ctx: &#crate_name::ContextSelectionSet<'a>,
futures: &mut Vec<#crate_name::BoxFieldFuture<'a>>,
) -> #crate_name::Result<()> {

View File

@ -113,7 +113,7 @@ pub fn generate(interface_args: &args::Interface, input: &DeriveInput) -> Result
fn collect_inline_fields<'a>(
&'a self,
name: &#crate_name::Spanned<String>,
name: &#crate_name::Positioned<String>,
ctx: &#crate_name::ContextSelectionSet<'a>,
futures: &mut Vec<#crate_name::BoxFieldFuture<'a>>,
) -> #crate_name::Result<()> {

View File

@ -1,4 +1,4 @@
use crate::span::Spanned;
use crate::pos::Positioned;
use crate::value::Value;
use std::fmt;
@ -21,12 +21,12 @@ impl fmt::Display for Type {
#[derive(Clone, Debug)]
pub struct Directive {
pub name: Spanned<String>,
pub arguments: Vec<(Spanned<String>, Spanned<Value>)>,
pub name: Positioned<String>,
pub arguments: Vec<(Positioned<String>, Positioned<Value>)>,
}
impl Directive {
pub fn get_argument(&self, name: &str) -> Option<&Spanned<Value>> {
pub fn get_argument(&self, name: &str) -> Option<&Positioned<Value>> {
self.arguments
.iter()
.find(|item| item.0.as_str() == name)
@ -36,90 +36,90 @@ impl Directive {
#[derive(Clone, Debug)]
pub struct Document {
pub definitions: Vec<Spanned<Definition>>,
pub definitions: Vec<Positioned<Definition>>,
}
#[derive(Clone, Debug)]
pub enum Definition {
Operation(Spanned<OperationDefinition>),
Fragment(Spanned<FragmentDefinition>),
Operation(Positioned<OperationDefinition>),
Fragment(Positioned<FragmentDefinition>),
}
#[derive(Clone, Debug)]
pub enum TypeCondition {
On(Spanned<String>),
On(Positioned<String>),
}
#[derive(Clone, Debug)]
pub struct FragmentDefinition {
pub name: Spanned<String>,
pub type_condition: Spanned<TypeCondition>,
pub directives: Vec<Spanned<Directive>>,
pub selection_set: Spanned<SelectionSet>,
pub name: Positioned<String>,
pub type_condition: Positioned<TypeCondition>,
pub directives: Vec<Positioned<Directive>>,
pub selection_set: Positioned<SelectionSet>,
}
#[derive(Clone, Debug)]
pub enum OperationDefinition {
SelectionSet(Spanned<SelectionSet>),
Query(Spanned<Query>),
Mutation(Spanned<Mutation>),
Subscription(Spanned<Subscription>),
SelectionSet(Positioned<SelectionSet>),
Query(Positioned<Query>),
Mutation(Positioned<Mutation>),
Subscription(Positioned<Subscription>),
}
#[derive(Clone, Debug)]
pub struct Query {
pub name: Option<Spanned<String>>,
pub variable_definitions: Vec<Spanned<VariableDefinition>>,
pub directives: Vec<Spanned<Directive>>,
pub selection_set: Spanned<SelectionSet>,
pub name: Option<Positioned<String>>,
pub variable_definitions: Vec<Positioned<VariableDefinition>>,
pub directives: Vec<Positioned<Directive>>,
pub selection_set: Positioned<SelectionSet>,
}
#[derive(Clone, Debug)]
pub struct Mutation {
pub name: Option<Spanned<String>>,
pub variable_definitions: Vec<Spanned<VariableDefinition>>,
pub directives: Vec<Spanned<Directive>>,
pub selection_set: Spanned<SelectionSet>,
pub name: Option<Positioned<String>>,
pub variable_definitions: Vec<Positioned<VariableDefinition>>,
pub directives: Vec<Positioned<Directive>>,
pub selection_set: Positioned<SelectionSet>,
}
#[derive(Clone, Debug)]
pub struct Subscription {
pub name: Option<Spanned<String>>,
pub variable_definitions: Vec<Spanned<VariableDefinition>>,
pub directives: Vec<Spanned<Directive>>,
pub selection_set: Spanned<SelectionSet>,
pub name: Option<Positioned<String>>,
pub variable_definitions: Vec<Positioned<VariableDefinition>>,
pub directives: Vec<Positioned<Directive>>,
pub selection_set: Positioned<SelectionSet>,
}
#[derive(Clone, Debug, Default)]
pub struct SelectionSet {
pub items: Vec<Spanned<Selection>>,
pub items: Vec<Positioned<Selection>>,
}
#[derive(Clone, Debug)]
pub struct VariableDefinition {
pub name: Spanned<String>,
pub var_type: Spanned<Type>,
pub default_value: Option<Spanned<Value>>,
pub name: Positioned<String>,
pub var_type: Positioned<Type>,
pub default_value: Option<Positioned<Value>>,
}
#[derive(Clone, Debug)]
pub enum Selection {
Field(Spanned<Field>),
FragmentSpread(Spanned<FragmentSpread>),
InlineFragment(Spanned<InlineFragment>),
Field(Positioned<Field>),
FragmentSpread(Positioned<FragmentSpread>),
InlineFragment(Positioned<InlineFragment>),
}
#[derive(Clone, Debug)]
pub struct Field {
pub alias: Option<Spanned<String>>,
pub name: Spanned<String>,
pub arguments: Vec<(Spanned<String>, Spanned<Value>)>,
pub directives: Vec<Spanned<Directive>>,
pub selection_set: Spanned<SelectionSet>,
pub alias: Option<Positioned<String>>,
pub name: Positioned<String>,
pub arguments: Vec<(Positioned<String>, Positioned<Value>)>,
pub directives: Vec<Positioned<Directive>>,
pub selection_set: Positioned<SelectionSet>,
}
impl Field {
pub fn get_argument(&self, name: &str) -> Option<&Spanned<Value>> {
pub fn get_argument(&self, name: &str) -> Option<&Positioned<Value>> {
self.arguments
.iter()
.find(|item| item.0.as_str() == name)
@ -129,13 +129,13 @@ impl Field {
#[derive(Clone, Debug)]
pub struct FragmentSpread {
pub fragment_name: Spanned<String>,
pub directives: Vec<Spanned<Directive>>,
pub fragment_name: Positioned<String>,
pub directives: Vec<Positioned<Directive>>,
}
#[derive(Clone, Debug)]
pub struct InlineFragment {
pub type_condition: Option<Spanned<TypeCondition>>,
pub directives: Vec<Spanned<Directive>>,
pub selection_set: Spanned<SelectionSet>,
pub type_condition: Option<Positioned<TypeCondition>>,
pub directives: Vec<Positioned<Directive>>,
pub selection_set: Positioned<SelectionSet>,
}

View File

@ -5,9 +5,9 @@ extern crate thiserror;
pub mod ast;
mod query_parser;
mod span;
mod pos;
mod value;
pub use query_parser::{parse_query, Error, Result};
pub use span::{Pos, Span, Spanned};
pub use pos::{Pos, Positioned};
pub use value::Value;

View File

@ -26,27 +26,21 @@ impl fmt::Display for Pos {
}
}
#[derive(Copy, Clone, Debug, Default)]
pub struct Span {
pub start: Pos,
pub end: Pos,
}
/// Represents the location of a AST node
/// Represents the position of a AST node
#[derive(Clone, Debug, Copy, Default)]
#[allow(missing_docs)]
pub struct Spanned<T: ?Sized> {
pub span: Span,
pub struct Positioned<T: ?Sized> {
pub pos: Pos,
pub node: T,
}
impl<T: fmt::Display> fmt::Display for Spanned<T> {
impl<T: fmt::Display> fmt::Display for Positioned<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.node.fmt(f)
}
}
impl<T: Clone> Spanned<T> {
impl<T: Clone> Positioned<T> {
#[inline]
#[allow(missing_docs)]
pub fn clone_inner(&self) -> T {
@ -54,27 +48,27 @@ impl<T: Clone> Spanned<T> {
}
}
impl<T: PartialEq> PartialEq for Spanned<T> {
impl<T: PartialEq> PartialEq for Positioned<T> {
fn eq(&self, other: &Self) -> bool {
self.node.eq(&other.node)
}
}
impl<T: PartialOrd> PartialOrd for Spanned<T> {
impl<T: PartialOrd> PartialOrd for Positioned<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.node.partial_cmp(&other.node)
}
}
impl<T: Ord> Ord for Spanned<T> {
impl<T: Ord> Ord for Positioned<T> {
fn cmp(&self, other: &Self) -> Ordering {
self.node.cmp(&other.node)
}
}
impl<T: Ord> Eq for Spanned<T> {}
impl<T: Ord> Eq for Positioned<T> {}
impl<T: ?Sized> Deref for Spanned<T> {
impl<T: ?Sized> Deref for Positioned<T> {
type Target = T;
fn deref(&self) -> &T {
@ -82,49 +76,33 @@ impl<T: ?Sized> Deref for Spanned<T> {
}
}
impl<T: ?Sized> DerefMut for Spanned<T> {
impl<T: ?Sized> DerefMut for Positioned<T> {
fn deref_mut(&mut self) -> &mut T {
&mut self.node
}
}
impl<T: Hash> Hash for Spanned<T> {
impl<T: Hash> Hash for Positioned<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.node.hash(state)
}
}
impl Borrow<str> for Spanned<String> {
impl Borrow<str> for Positioned<String> {
fn borrow(&self) -> &str {
self.node.as_str()
}
}
impl BorrowMut<str> for Spanned<String> {
impl BorrowMut<str> for Positioned<String> {
fn borrow_mut(&mut self) -> &mut str {
self.node.as_mut_str()
}
}
impl<T> Spanned<T> {
pub(crate) fn new(node: T, pair_span: pest::Span<'_>) -> Spanned<T> {
let ((start_line, start_column), (end_line, end_column)) = (
pair_span.start_pos().line_col(),
pair_span.end_pos().line_col(),
);
Spanned {
node,
span: Span {
start: Pos {
line: start_line,
column: start_column,
},
end: Pos {
line: end_line,
column: end_column,
},
},
}
impl<T> Positioned<T> {
pub(crate) fn new(node: T, pos: Pos) -> Positioned<T> {
Positioned { node, pos }
}
#[inline]
@ -135,13 +113,13 @@ impl<T> Spanned<T> {
/// Get start position
#[inline]
pub fn position(&self) -> Pos {
self.span.start
self.pos
}
#[inline]
pub(crate) fn pack<F: FnOnce(Self) -> R, R>(self, f: F) -> Spanned<R> {
Spanned {
span: self.span,
pub(crate) fn pack<F: FnOnce(Self) -> R, R>(self, f: F) -> Positioned<R> {
Positioned {
pos: self.pos,
node: f(self),
}
}

View File

@ -1,5 +1,5 @@
use crate::ast::*;
use crate::span::Spanned;
use crate::pos::Positioned;
use crate::value::Value;
use crate::Pos;
use pest::error::LineColLocation;
@ -7,6 +7,8 @@ use pest::iterators::Pair;
use pest::Parser;
use std::collections::BTreeMap;
use std::fmt;
use std::iter::Peekable;
use std::str::Chars;
#[derive(Parser)]
#[grammar = "query.pest"]
@ -43,25 +45,74 @@ impl From<pest::error::Error<Rule>> for Error {
/// Parser result
pub type Result<T> = std::result::Result<T, Error>;
pub(crate) struct PositionCalculator<'a> {
input: Peekable<Chars<'a>>,
pos: usize,
line: usize,
column: usize,
}
impl<'a> PositionCalculator<'a> {
fn new(input: &'a str) -> PositionCalculator<'a> {
Self {
input: input.chars().peekable(),
pos: 0,
line: 1,
column: 1,
}
}
pub fn step(&mut self, pair: &Pair<Rule>) -> Pos {
let pos = pair.as_span().start();
debug_assert!(pos >= self.pos);
for _ in 0..pos - self.pos {
match self.input.next() {
Some('\r') => {
if let Some(&'\n') = self.input.peek() {
self.input.next();
self.line += 1;
self.column = 1;
} else {
self.column += 1;
}
}
Some('\n') => {
self.line += 1;
self.column = 1;
}
Some(_) => {
self.column += 1;
}
None => break,
}
}
self.pos = pos;
Pos {
line: self.line,
column: self.column,
}
}
}
/// Parse a GraphQL query.
pub fn parse_query<T: AsRef<str>>(input: T) -> Result<Document> {
let document_pair: Pair<Rule> = QueryParser::parse(Rule::document, input.as_ref())?
.next()
.unwrap();
let mut definitions = Vec::new();
let mut pc = PositionCalculator::new(input.as_ref());
for pair in document_pair.into_inner() {
match pair.as_rule() {
Rule::named_operation_definition => definitions
.push(parse_named_operation_definition(pair)?.pack(Definition::Operation)),
.push(parse_named_operation_definition(pair, &mut pc)?.pack(Definition::Operation)),
Rule::selection_set => definitions.push(
parse_selection_set(pair)?
parse_selection_set(pair, &mut pc)?
.pack(OperationDefinition::SelectionSet)
.pack(Definition::Operation),
),
Rule::fragment_definition => {
definitions.push(parse_fragment_definition(pair)?.pack(Definition::Fragment))
}
Rule::fragment_definition => definitions
.push(parse_fragment_definition(pair, &mut pc)?.pack(Definition::Fragment)),
Rule::EOI => {}
_ => unreachable!(),
}
@ -69,14 +120,17 @@ pub fn parse_query<T: AsRef<str>>(input: T) -> Result<Document> {
Ok(Document { definitions })
}
fn parse_named_operation_definition(pair: Pair<Rule>) -> Result<Spanned<OperationDefinition>> {
fn parse_named_operation_definition(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<Positioned<OperationDefinition>> {
enum OperationType {
Query,
Mutation,
Subscription,
}
let span = pair.as_span();
let pos = pc.step(&pair);
let mut operation_type = OperationType::Query;
let mut name = None;
let mut variable_definitions = None;
@ -94,160 +148,177 @@ fn parse_named_operation_definition(pair: Pair<Rule>) -> Result<Spanned<Operatio
};
}
Rule::name => {
name = Some(Spanned::new(pair.as_str().to_string(), pair.as_span()));
name = Some(Positioned::new(pair.as_str().to_string(), pc.step(&pair)));
}
Rule::variable_definitions => {
variable_definitions = Some(parse_variable_definitions(pair)?);
variable_definitions = Some(parse_variable_definitions(pair, pc)?);
}
Rule::directives => {
directives = Some(parse_directives(pair)?);
directives = Some(parse_directives(pair, pc)?);
}
Rule::selection_set => {
selection_set = Some(parse_selection_set(pair)?);
selection_set = Some(parse_selection_set(pair, pc)?);
}
_ => unreachable!(),
}
}
Ok(match operation_type {
OperationType::Query => Spanned::new(
OperationType::Query => Positioned::new(
Query {
name,
variable_definitions: variable_definitions.unwrap_or_default(),
directives: directives.unwrap_or_default(),
selection_set: selection_set.unwrap(),
},
span,
pos,
)
.pack(OperationDefinition::Query),
OperationType::Mutation => Spanned::new(
OperationType::Mutation => Positioned::new(
Mutation {
name,
variable_definitions: variable_definitions.unwrap_or_default(),
directives: directives.unwrap_or_default(),
selection_set: selection_set.unwrap(),
},
span,
pos,
)
.pack(OperationDefinition::Mutation),
OperationType::Subscription => Spanned::new(
OperationType::Subscription => Positioned::new(
Subscription {
name,
variable_definitions: variable_definitions.unwrap_or_default(),
directives: directives.unwrap_or_default(),
selection_set: selection_set.unwrap(),
},
span,
pos,
)
.pack(OperationDefinition::Subscription),
})
}
fn parse_default_value(pair: Pair<Rule>) -> Result<Value> {
fn parse_default_value(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Value> {
for pair in pair.into_inner() {
match pair.as_rule() {
Rule::value => return Ok(parse_value(pair)?),
Rule::value => return Ok(parse_value(pair, pc)?),
_ => unreachable!(),
}
}
unreachable!()
}
fn parse_type(pair: Pair<Rule>) -> Result<Type> {
fn parse_type(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Type> {
let pair = pair.into_inner().next().unwrap();
match pair.as_rule() {
Rule::nonnull_type => Ok(Type::NonNull(Box::new(parse_type(pair)?))),
Rule::list_type => Ok(Type::List(Box::new(parse_type(pair)?))),
Rule::nonnull_type => Ok(Type::NonNull(Box::new(parse_type(pair, pc)?))),
Rule::list_type => Ok(Type::List(Box::new(parse_type(pair, pc)?))),
Rule::name => Ok(Type::Named(pair.as_str().to_string())),
Rule::type_ => parse_type(pair),
Rule::type_ => parse_type(pair, pc),
_ => unreachable!(),
}
}
fn parse_variable_definition(pair: Pair<Rule>) -> Result<Spanned<VariableDefinition>> {
let span = pair.as_span();
fn parse_variable_definition(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<Positioned<VariableDefinition>> {
let pos = pc.step(&pair);
let mut variable = None;
let mut ty = None;
let mut default_value = None;
for pair in pair.into_inner() {
let span = pair.as_span();
match pair.as_rule() {
Rule::variable => variable = Some(parse_variable(pair)?),
Rule::type_ => ty = Some(Spanned::new(parse_type(pair)?, span)),
Rule::variable => variable = Some(parse_variable(pair, pc)?),
Rule::type_ => {
ty = {
let pos = pc.step(&pair);
Some(Positioned::new(parse_type(pair, pc)?, pos))
}
}
Rule::default_value => {
default_value = Some(Spanned::new(parse_default_value(pair)?, span))
let pos = pc.step(&pair);
default_value = Some(Positioned::new(parse_default_value(pair, pc)?, pos))
}
_ => unreachable!(),
}
}
Ok(Spanned::new(
Ok(Positioned::new(
VariableDefinition {
name: variable.unwrap(),
var_type: ty.unwrap(),
default_value,
},
span,
pos,
))
}
fn parse_variable_definitions(pair: Pair<Rule>) -> Result<Vec<Spanned<VariableDefinition>>> {
fn parse_variable_definitions(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<Vec<Positioned<VariableDefinition>>> {
let mut vars = Vec::new();
for pair in pair.into_inner() {
match pair.as_rule() {
Rule::variable_definition => vars.push(parse_variable_definition(pair)?),
Rule::variable_definition => vars.push(parse_variable_definition(pair, pc)?),
_ => unreachable!(),
}
}
Ok(vars)
}
fn parse_directive(pair: Pair<Rule>) -> Result<Spanned<Directive>> {
let span = pair.as_span();
fn parse_directive(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Positioned<Directive>> {
let pos = pc.step(&pair);
let mut name = None;
let mut arguments = None;
for pair in pair.into_inner() {
match pair.as_rule() {
Rule::name => name = Some(Spanned::new(pair.as_str().to_string(), pair.as_span())),
Rule::arguments => arguments = Some(parse_arguments(pair)?),
Rule::name => {
let pos = pc.step(&pair);
name = Some(Positioned::new(pair.as_str().to_string(), pos))
}
Rule::arguments => arguments = Some(parse_arguments(pair, pc)?),
_ => unreachable!(),
}
}
Ok(Spanned::new(
Ok(Positioned::new(
Directive {
name: name.unwrap(),
arguments: arguments.unwrap_or_default(),
},
span,
pos,
))
}
fn parse_directives(pair: Pair<Rule>) -> Result<Vec<Spanned<Directive>>> {
fn parse_directives(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<Vec<Positioned<Directive>>> {
let mut directives = Vec::new();
for pair in pair.into_inner() {
match pair.as_rule() {
Rule::directive => directives.push(parse_directive(pair)?),
Rule::directive => directives.push(parse_directive(pair, pc)?),
_ => unreachable!(),
}
}
Ok(directives)
}
fn parse_variable(pair: Pair<Rule>) -> Result<Spanned<String>> {
fn parse_variable(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Positioned<String>> {
for pair in pair.into_inner() {
if let Rule::name = pair.as_rule() {
return Ok(Spanned::new(pair.as_str().to_string(), pair.as_span()));
return Ok(Positioned::new(pair.as_str().to_string(), pc.step(&pair)));
}
}
unreachable!()
}
fn parse_value(pair: Pair<Rule>) -> Result<Value> {
fn parse_value(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Value> {
let pair = pair.into_inner().next().unwrap();
Ok(match pair.as_rule() {
Rule::object => parse_object_value(pair)?,
Rule::array => parse_array_value(pair)?,
Rule::variable => Value::Variable(parse_variable(pair)?.into_inner()),
Rule::object => parse_object_value(pair, pc)?,
Rule::array => parse_array_value(pair, pc)?,
Rule::variable => Value::Variable(parse_variable(pair, pc)?.into_inner()),
Rule::float => Value::Float(pair.as_str().parse().unwrap()),
Rule::int => Value::Int(pair.as_str().parse().unwrap()),
Rule::string => Value::String({
@ -271,25 +342,25 @@ fn parse_value(pair: Pair<Rule>) -> Result<Value> {
})
}
fn parse_object_pair(pair: Pair<Rule>) -> Result<(String, Value)> {
fn parse_object_pair(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<(String, Value)> {
let mut name = None;
let mut value = None;
for pair in pair.into_inner() {
match pair.as_rule() {
Rule::name => name = Some(pair.as_str().to_string()),
Rule::value => value = Some(parse_value(pair)?),
Rule::value => value = Some(parse_value(pair, pc)?),
_ => unreachable!(),
}
}
Ok((name.unwrap(), value.unwrap()))
}
fn parse_object_value(pair: Pair<Rule>) -> Result<Value> {
fn parse_object_value(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Value> {
let mut map = BTreeMap::new();
for pair in pair.into_inner() {
match pair.as_rule() {
Rule::pair => {
map.extend(std::iter::once(parse_object_pair(pair)?));
map.extend(std::iter::once(parse_object_pair(pair, pc)?));
}
_ => unreachable!(),
}
@ -297,12 +368,12 @@ fn parse_object_value(pair: Pair<Rule>) -> Result<Value> {
Ok(Value::Object(map))
}
fn parse_array_value(pair: Pair<Rule>) -> Result<Value> {
fn parse_array_value(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Value> {
let mut array = Vec::new();
for pair in pair.into_inner() {
match pair.as_rule() {
Rule::value => {
array.push(parse_value(pair)?);
array.push(parse_value(pair, pc)?);
}
_ => unreachable!(),
}
@ -310,42 +381,52 @@ fn parse_array_value(pair: Pair<Rule>) -> Result<Value> {
Ok(Value::List(array))
}
fn parse_pair(pair: Pair<Rule>) -> Result<(Spanned<String>, Spanned<Value>)> {
fn parse_pair(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<(Positioned<String>, Positioned<Value>)> {
let mut name = None;
let mut value = None;
for pair in pair.into_inner() {
let span = pair.as_span();
match pair.as_rule() {
Rule::name => name = Some(Spanned::new(pair.as_str().to_string(), span)),
Rule::value => value = Some(Spanned::new(parse_value(pair)?, span)),
Rule::name => name = Some(Positioned::new(pair.as_str().to_string(), pc.step(&pair))),
Rule::value => {
value = {
let pos = pc.step(&pair);
Some(Positioned::new(parse_value(pair, pc)?, pos))
}
}
_ => unreachable!(),
}
}
Ok((name.unwrap(), value.unwrap()))
}
fn parse_arguments(pair: Pair<Rule>) -> Result<Vec<(Spanned<String>, Spanned<Value>)>> {
fn parse_arguments(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<Vec<(Positioned<String>, Positioned<Value>)>> {
let mut arguments = Vec::new();
for pair in pair.into_inner() {
match pair.as_rule() {
Rule::pair => arguments.extend(std::iter::once(parse_pair(pair)?)),
Rule::pair => arguments.extend(std::iter::once(parse_pair(pair, pc)?)),
_ => unreachable!(),
}
}
Ok(arguments)
}
fn parse_alias(pair: Pair<Rule>) -> Result<Spanned<String>> {
fn parse_alias(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Positioned<String>> {
for pair in pair.into_inner() {
if let Rule::name = pair.as_rule() {
return Ok(Spanned::new(pair.as_str().to_string(), pair.as_span()));
return Ok(Positioned::new(pair.as_str().to_string(), pc.step(&pair)));
}
}
unreachable!()
}
fn parse_field(pair: Pair<Rule>) -> Result<Spanned<Field>> {
let span = pair.as_span();
fn parse_field(pair: Pair<Rule>, pc: &mut PositionCalculator) -> Result<Positioned<Field>> {
let pos = pc.step(&pair);
let mut alias = None;
let mut name = None;
let mut directives = None;
@ -354,16 +435,16 @@ fn parse_field(pair: Pair<Rule>) -> Result<Spanned<Field>> {
for pair in pair.into_inner() {
match pair.as_rule() {
Rule::alias => alias = Some(parse_alias(pair)?),
Rule::name => name = Some(Spanned::new(pair.as_str().to_string(), pair.as_span())),
Rule::arguments => arguments = Some(parse_arguments(pair)?),
Rule::directives => directives = Some(parse_directives(pair)?),
Rule::selection_set => selection_set = Some(parse_selection_set(pair)?),
Rule::alias => alias = Some(parse_alias(pair, pc)?),
Rule::name => name = Some(Positioned::new(pair.as_str().to_string(), pc.step(&pair))),
Rule::arguments => arguments = Some(parse_arguments(pair, pc)?),
Rule::directives => directives = Some(parse_directives(pair, pc)?),
Rule::selection_set => selection_set = Some(parse_selection_set(pair, pc)?),
_ => unreachable!(),
}
}
Ok(Spanned::new(
Ok(Positioned::new(
Field {
alias,
name: name.unwrap(),
@ -371,87 +452,103 @@ fn parse_field(pair: Pair<Rule>) -> Result<Spanned<Field>> {
directives: directives.unwrap_or_default(),
selection_set: selection_set.unwrap_or_default(),
},
span,
pos,
))
}
fn parse_fragment_spread(pair: Pair<Rule>) -> Result<Spanned<FragmentSpread>> {
let span = pair.as_span();
fn parse_fragment_spread(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<Positioned<FragmentSpread>> {
let pos = pc.step(&pair);
let mut name = None;
let mut directives = None;
for pair in pair.into_inner() {
match pair.as_rule() {
Rule::name => name = Some(Spanned::new(pair.as_str().to_string(), pair.as_span())),
Rule::directives => directives = Some(parse_directives(pair)?),
Rule::name => name = Some(Positioned::new(pair.as_str().to_string(), pc.step(&pair))),
Rule::directives => directives = Some(parse_directives(pair, pc)?),
_ => unreachable!(),
}
}
Ok(Spanned::new(
Ok(Positioned::new(
FragmentSpread {
fragment_name: name.unwrap(),
directives: directives.unwrap_or_default(),
},
span,
pos,
))
}
fn parse_type_condition(pair: Pair<Rule>) -> Result<Spanned<TypeCondition>> {
fn parse_type_condition(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<Positioned<TypeCondition>> {
for pair in pair.into_inner() {
if let Rule::name = pair.as_rule() {
return Ok(Spanned::new(
TypeCondition::On(Spanned::new(pair.as_str().to_string(), pair.as_span())),
pair.as_span(),
let pos = pc.step(&pair);
return Ok(Positioned::new(
TypeCondition::On(Positioned::new(pair.as_str().to_string(), pc.step(&pair))),
pos,
));
}
}
unreachable!()
}
fn parse_inline_fragment(pair: Pair<Rule>) -> Result<Spanned<InlineFragment>> {
let span = pair.as_span();
fn parse_inline_fragment(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<Positioned<InlineFragment>> {
let pos = pc.step(&pair);
let mut type_condition = None;
let mut directives = None;
let mut selection_set = None;
for pair in pair.into_inner() {
match pair.as_rule() {
Rule::type_condition => type_condition = Some(parse_type_condition(pair)?),
Rule::directives => directives = Some(parse_directives(pair)?),
Rule::selection_set => selection_set = Some(parse_selection_set(pair)?),
Rule::type_condition => type_condition = Some(parse_type_condition(pair, pc)?),
Rule::directives => directives = Some(parse_directives(pair, pc)?),
Rule::selection_set => selection_set = Some(parse_selection_set(pair, pc)?),
_ => unreachable!(),
}
}
Ok(Spanned::new(
Ok(Positioned::new(
InlineFragment {
type_condition,
directives: directives.unwrap_or_default(),
selection_set: selection_set.unwrap(),
},
span,
pos,
))
}
fn parse_selection_set(pair: Pair<Rule>) -> Result<Spanned<SelectionSet>> {
let span = pair.as_span();
fn parse_selection_set(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<Positioned<SelectionSet>> {
let pos = pc.step(&pair);
let mut items = Vec::new();
for pair in pair.into_inner().map(|pair| pair.into_inner()).flatten() {
match pair.as_rule() {
Rule::field => items.push(parse_field(pair)?.pack(Selection::Field)),
Rule::field => items.push(parse_field(pair, pc)?.pack(Selection::Field)),
Rule::fragment_spread => {
items.push(parse_fragment_spread(pair)?.pack(Selection::FragmentSpread))
items.push(parse_fragment_spread(pair, pc)?.pack(Selection::FragmentSpread))
}
Rule::inline_fragment => {
items.push(parse_inline_fragment(pair)?.pack(Selection::InlineFragment))
items.push(parse_inline_fragment(pair, pc)?.pack(Selection::InlineFragment))
}
_ => unreachable!(),
}
}
Ok(Spanned::new(SelectionSet { items }, span))
Ok(Positioned::new(SelectionSet { items }, pos))
}
fn parse_fragment_definition(pair: Pair<Rule>) -> Result<Spanned<FragmentDefinition>> {
let span = pair.as_span();
fn parse_fragment_definition(
pair: Pair<Rule>,
pc: &mut PositionCalculator,
) -> Result<Positioned<FragmentDefinition>> {
let pos = pc.step(&pair);
let mut name = None;
let mut type_condition = None;
let mut directives = None;
@ -459,22 +556,22 @@ fn parse_fragment_definition(pair: Pair<Rule>) -> Result<Spanned<FragmentDefinit
for pair in pair.into_inner() {
match pair.as_rule() {
Rule::name => name = Some(Spanned::new(pair.as_str().to_string(), pair.as_span())),
Rule::type_condition => type_condition = Some(parse_type_condition(pair)?),
Rule::directives => directives = Some(parse_directives(pair)?),
Rule::selection_set => selection_set = Some(parse_selection_set(pair)?),
Rule::name => name = Some(Positioned::new(pair.as_str().to_string(), pc.step(&pair))),
Rule::type_condition => type_condition = Some(parse_type_condition(pair, pc)?),
Rule::directives => directives = Some(parse_directives(pair, pc)?),
Rule::selection_set => selection_set = Some(parse_selection_set(pair, pc)?),
_ => unreachable!(),
}
}
Ok(Spanned::new(
Ok(Positioned::new(
FragmentDefinition {
name: name.unwrap(),
type_condition: type_condition.unwrap(),
directives: directives.unwrap_or_default(),
selection_set: selection_set.unwrap(),
},
span,
pos,
))
}

View File

@ -1,7 +1,7 @@
use crate::parser::Pos;
use crate::registry::Registry;
use crate::{
registry, Context, ContextSelectionSet, FieldResult, QueryError, Result, Spanned, Value, ID,
registry, Context, ContextSelectionSet, FieldResult, Positioned, QueryError, Result, Value, ID,
};
use std::borrow::Cow;
use std::future::Future;
@ -80,7 +80,7 @@ pub trait ObjectType: OutputValueType {
/// Collect the fields with the `name` inline object
fn collect_inline_fields<'a>(
&'a self,
name: &Spanned<String>,
name: &Positioned<String>,
ctx: &ContextSelectionSet<'a>,
futures: &mut Vec<BoxFieldFuture<'a>>,
) -> Result<()>

View File

@ -2,7 +2,7 @@ use crate::extensions::BoxExtension;
use crate::parser::ast::{Directive, Field, FragmentDefinition, SelectionSet, VariableDefinition};
use crate::registry::Registry;
use crate::{InputValueType, QueryError, Result, Schema, Type};
use crate::{Pos, Spanned, Value};
use crate::{Pos, Positioned, Value};
use fnv::FnvHashMap;
use std::any::{Any, TypeId};
use std::collections::{BTreeMap, HashMap};
@ -121,10 +121,10 @@ impl Data {
}
/// Context for `SelectionSet`
pub type ContextSelectionSet<'a> = ContextBase<'a, &'a Spanned<SelectionSet>>;
pub type ContextSelectionSet<'a> = ContextBase<'a, &'a Positioned<SelectionSet>>;
/// Context object for resolve field
pub type Context<'a> = ContextBase<'a, &'a Spanned<Field>>;
pub type Context<'a> = ContextBase<'a, &'a Positioned<Field>>;
/// The query path segment
#[derive(Clone)]
@ -241,7 +241,7 @@ pub struct ContextBase<'a, T> {
pub(crate) extensions: &'a [BoxExtension],
pub(crate) item: T,
pub(crate) variables: &'a Variables,
pub(crate) variable_definitions: &'a [Spanned<VariableDefinition>],
pub(crate) variable_definitions: &'a [Positioned<VariableDefinition>],
pub(crate) registry: &'a Registry,
pub(crate) data: &'a Data,
pub(crate) ctx_data: Option<&'a Data>,
@ -259,7 +259,7 @@ impl<'a, T> Deref for ContextBase<'a, T> {
#[doc(hidden)]
pub struct Environment {
pub variables: Variables,
pub variable_definitions: Vec<Spanned<VariableDefinition>>,
pub variable_definitions: Vec<Positioned<VariableDefinition>>,
pub fragments: HashMap<String, FragmentDefinition>,
pub ctx_data: Arc<Data>,
}
@ -302,7 +302,10 @@ impl<'a, T> ContextBase<'a, T> {
}
#[doc(hidden)]
pub fn with_field(&'a self, field: &'a Spanned<Field>) -> ContextBase<'a, &'a Spanned<Field>> {
pub fn with_field(
&'a self,
field: &'a Positioned<Field>,
) -> ContextBase<'a, &'a Positioned<Field>> {
ContextBase {
path_node: Some(QueryPathNode {
parent: self.path_node.as_ref(),
@ -330,8 +333,8 @@ impl<'a, T> ContextBase<'a, T> {
#[doc(hidden)]
pub fn with_selection_set(
&self,
selection_set: &'a Spanned<SelectionSet>,
) -> ContextBase<'a, &'a Spanned<SelectionSet>> {
selection_set: &'a Positioned<SelectionSet>,
) -> ContextBase<'a, &'a Positioned<SelectionSet>> {
ContextBase {
path_node: self.path_node.clone(),
extensions: self.extensions,
@ -403,7 +406,7 @@ impl<'a, T> ContextBase<'a, T> {
}
#[doc(hidden)]
pub fn is_skip(&self, directives: &[Spanned<Directive>]) -> Result<bool> {
pub fn is_skip(&self, directives: &[Positioned<Directive>]) -> Result<bool> {
for directive in directives {
if directive.name.as_str() == "skip" {
if let Some(value) = directive.get_argument("if") {
@ -459,9 +462,9 @@ impl<'a, T> ContextBase<'a, T> {
}
}
impl<'a> ContextBase<'a, &'a Spanned<SelectionSet>> {
impl<'a> ContextBase<'a, &'a Positioned<SelectionSet>> {
#[doc(hidden)]
pub fn with_index(&'a self, idx: usize) -> ContextBase<'a, &'a Spanned<SelectionSet>> {
pub fn with_index(&'a self, idx: usize) -> ContextBase<'a, &'a Positioned<SelectionSet>> {
ContextBase {
path_node: Some(QueryPathNode {
parent: self.path_node.as_ref(),
@ -481,7 +484,7 @@ impl<'a> ContextBase<'a, &'a Spanned<SelectionSet>> {
}
}
impl<'a> ContextBase<'a, &'a Spanned<Field>> {
impl<'a> ContextBase<'a, &'a Positioned<Field>> {
#[doc(hidden)]
pub fn param_value<T: InputValueType, F: FnOnce() -> Value>(
&self,

View File

@ -118,7 +118,7 @@ pub use context::{
pub use error::{
Error, ErrorExtensions, FieldError, FieldResult, ParseRequestError, QueryError, ResultExt,
};
pub use parser::{Pos, Spanned, Value};
pub use parser::{Pos, Positioned, Value};
pub use query::{IntoQueryBuilder, IntoQueryBuilderOpts, QueryBuilder, QueryResponse};
pub use registry::CacheControl;
pub use scalars::{Any, Json, ID};

View File

@ -8,7 +8,8 @@ use crate::parser::parse_query;
use crate::registry::CacheControl;
use crate::validation::{check_rules, CheckResult};
use crate::{
do_resolve, ContextBase, Error, ObjectType, Pos, QueryError, Result, Schema, Spanned, Variables,
do_resolve, ContextBase, Error, ObjectType, Pos, Positioned, QueryError, Result, Schema,
Variables,
};
use itertools::Itertools;
use std::any::Any;
@ -238,8 +239,8 @@ fn current_operation<'a>(
document: &'a Document,
operation_name: Option<&str>,
) -> Option<(
&'a Spanned<SelectionSet>,
&'a [Spanned<VariableDefinition>],
&'a Positioned<SelectionSet>,
&'a [Positioned<VariableDefinition>],
bool,
)> {
for definition in &document.definitions {

View File

@ -3,7 +3,7 @@ use crate::parser::ast::{Directive, Field};
use crate::registry::InputValue;
use crate::validation::utils::is_valid_input_value;
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::{QueryPathSegment, Spanned, Value};
use crate::{Positioned, QueryPathSegment, Value};
use std::collections::HashMap;
#[derive(Default)]
@ -12,7 +12,11 @@ pub struct ArgumentsOfCorrectType<'a> {
}
impl<'a> Visitor<'a> for ArgumentsOfCorrectType<'a> {
fn enter_directive(&mut self, ctx: &mut VisitorContext<'a>, directive: &'a Spanned<Directive>) {
fn enter_directive(
&mut self,
ctx: &mut VisitorContext<'a>,
directive: &'a Positioned<Directive>,
) {
self.current_args = ctx
.registry
.directives
@ -23,7 +27,7 @@ impl<'a> Visitor<'a> for ArgumentsOfCorrectType<'a> {
fn exit_directive(
&mut self,
_ctx: &mut VisitorContext<'a>,
_directive: &'a Spanned<Directive>,
_directive: &'a Positioned<Directive>,
) {
self.current_args = None;
}
@ -31,8 +35,8 @@ impl<'a> Visitor<'a> for ArgumentsOfCorrectType<'a> {
fn enter_argument(
&mut self,
ctx: &mut VisitorContext<'a>,
name: &'a Spanned<String>,
value: &'a Spanned<Value>,
name: &'a Positioned<String>,
value: &'a Positioned<Value>,
) {
if let Some(arg) = self
.current_args
@ -65,14 +69,14 @@ impl<'a> Visitor<'a> for ArgumentsOfCorrectType<'a> {
}
}
fn enter_field(&mut self, ctx: &mut VisitorContext<'a>, field: &'a Spanned<Field>) {
fn enter_field(&mut self, ctx: &mut VisitorContext<'a>, field: &'a Positioned<Field>) {
self.current_args = ctx
.parent_type()
.and_then(|p| p.field_by_name(&field.name))
.map(|f| &f.args);
}
fn exit_field(&mut self, _ctx: &mut VisitorContext<'a>, _field: &'a Spanned<Field>) {
fn exit_field(&mut self, _ctx: &mut VisitorContext<'a>, _field: &'a Positioned<Field>) {
self.current_args = None;
}
}

View File

@ -2,7 +2,7 @@ use crate::context::QueryPathNode;
use crate::parser::ast::{Type, VariableDefinition};
use crate::validation::utils::is_valid_input_value;
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::{QueryPathSegment, Spanned};
use crate::{Positioned, QueryPathSegment};
pub struct DefaultValuesOfCorrectType;
@ -10,7 +10,7 @@ impl<'a> Visitor<'a> for DefaultValuesOfCorrectType {
fn enter_variable_definition(
&mut self,
ctx: &mut VisitorContext<'a>,
variable_definition: &'a Spanned<VariableDefinition>,
variable_definition: &'a Positioned<VariableDefinition>,
) {
if let Some(value) = &variable_definition.default_value {
if let Type::NonNull(_) = &variable_definition.var_type.node {

View File

@ -1,13 +1,13 @@
use crate::parser::ast::Field;
use crate::validation::suggestion::make_suggestion;
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::{registry, Spanned};
use crate::{registry, Positioned};
#[derive(Default)]
pub struct FieldsOnCorrectType;
impl<'a> Visitor<'a> for FieldsOnCorrectType {
fn enter_field(&mut self, ctx: &mut VisitorContext<'a>, field: &'a Spanned<Field>) {
fn enter_field(&mut self, ctx: &mut VisitorContext<'a>, field: &'a Positioned<Field>) {
if let Some(parent_type) = ctx.parent_type() {
if let Some(registry::Type::Union { .. }) | Some(registry::Type::Interface { .. }) =
ctx.parent_type()

View File

@ -1,6 +1,6 @@
use crate::parser::ast::{FragmentDefinition, InlineFragment, TypeCondition};
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::Spanned;
use crate::Positioned;
#[derive(Default)]
pub struct FragmentsOnCompositeTypes;
@ -9,7 +9,7 @@ impl<'a> Visitor<'a> for FragmentsOnCompositeTypes {
fn enter_fragment_definition(
&mut self,
ctx: &mut VisitorContext<'a>,
fragment_definition: &'a Spanned<FragmentDefinition>,
fragment_definition: &'a Positioned<FragmentDefinition>,
) {
if let Some(current_type) = ctx.current_type() {
if !current_type.is_composite() {
@ -28,7 +28,7 @@ impl<'a> Visitor<'a> for FragmentsOnCompositeTypes {
fn enter_inline_fragment(
&mut self,
ctx: &mut VisitorContext<'a>,
inline_fragment: &'a Spanned<InlineFragment>,
inline_fragment: &'a Positioned<InlineFragment>,
) {
if let Some(current_type) = ctx.current_type() {
if !current_type.is_composite() {

View File

@ -2,7 +2,7 @@ use crate::parser::ast::{Directive, Field};
use crate::registry::InputValue;
use crate::validation::suggestion::make_suggestion;
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::{Spanned, Value};
use crate::{Positioned, Value};
use std::collections::HashMap;
enum ArgsType<'a> {
@ -33,7 +33,11 @@ impl<'a> KnownArgumentNames<'a> {
}
impl<'a> Visitor<'a> for KnownArgumentNames<'a> {
fn enter_directive(&mut self, ctx: &mut VisitorContext<'a>, directive: &'a Spanned<Directive>) {
fn enter_directive(
&mut self,
ctx: &mut VisitorContext<'a>,
directive: &'a Positioned<Directive>,
) {
self.current_args = ctx
.registry
.directives
@ -44,7 +48,7 @@ impl<'a> Visitor<'a> for KnownArgumentNames<'a> {
fn exit_directive(
&mut self,
_ctx: &mut VisitorContext<'a>,
_directive: &'a Spanned<Directive>,
_directive: &'a Positioned<Directive>,
) {
self.current_args = None;
}
@ -52,8 +56,8 @@ impl<'a> Visitor<'a> for KnownArgumentNames<'a> {
fn enter_argument(
&mut self,
ctx: &mut VisitorContext<'a>,
name: &'a Spanned<String>,
_value: &'a Spanned<Value>,
name: &'a Positioned<String>,
_value: &'a Positioned<Value>,
) {
if let Some((args, arg_type)) = &self.current_args {
if !args.contains_key(name.as_str()) {
@ -89,7 +93,7 @@ impl<'a> Visitor<'a> for KnownArgumentNames<'a> {
}
}
fn enter_field(&mut self, ctx: &mut VisitorContext<'a>, field: &'a Spanned<Field>) {
fn enter_field(&mut self, ctx: &mut VisitorContext<'a>, field: &'a Positioned<Field>) {
if let Some(parent_type) = ctx.parent_type() {
if let Some(schema_field) = parent_type.field_by_name(&field.name) {
self.current_args = Some((
@ -103,7 +107,7 @@ impl<'a> Visitor<'a> for KnownArgumentNames<'a> {
}
}
fn exit_field(&mut self, _ctx: &mut VisitorContext<'a>, _field: &'a Spanned<Field>) {
fn exit_field(&mut self, _ctx: &mut VisitorContext<'a>, _field: &'a Positioned<Field>) {
self.current_args = None;
}
}

View File

@ -3,7 +3,7 @@ use crate::parser::ast::{
Directive, Field, FragmentDefinition, FragmentSpread, InlineFragment, OperationDefinition,
};
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::Spanned;
use crate::Positioned;
#[derive(Default)]
pub struct KnownDirectives {
@ -14,7 +14,7 @@ impl<'a> Visitor<'a> for KnownDirectives {
fn enter_operation_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
operation_definition: &'a Spanned<OperationDefinition>,
operation_definition: &'a Positioned<OperationDefinition>,
) {
self.location_stack.push(match &operation_definition.node {
OperationDefinition::SelectionSet(_) | OperationDefinition::Query(_) => {
@ -28,7 +28,7 @@ impl<'a> Visitor<'a> for KnownDirectives {
fn exit_operation_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
_operation_definition: &'a Spanned<OperationDefinition>,
_operation_definition: &'a Positioned<OperationDefinition>,
) {
self.location_stack.pop();
}
@ -36,7 +36,7 @@ impl<'a> Visitor<'a> for KnownDirectives {
fn enter_fragment_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
_fragment_definition: &'a Spanned<FragmentDefinition>,
_fragment_definition: &'a Positioned<FragmentDefinition>,
) {
self.location_stack
.push(__DirectiveLocation::FRAGMENT_DEFINITION);
@ -45,12 +45,16 @@ impl<'a> Visitor<'a> for KnownDirectives {
fn exit_fragment_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
_fragment_definition: &'a Spanned<FragmentDefinition>,
_fragment_definition: &'a Positioned<FragmentDefinition>,
) {
self.location_stack.pop();
}
fn enter_directive(&mut self, ctx: &mut VisitorContext<'a>, directive: &'a Spanned<Directive>) {
fn enter_directive(
&mut self,
ctx: &mut VisitorContext<'a>,
directive: &'a Positioned<Directive>,
) {
if let Some(schema_directive) = ctx.registry.directives.get(directive.name.as_str()) {
if let Some(current_location) = self.location_stack.last() {
if !schema_directive.locations.contains(current_location) {
@ -71,18 +75,18 @@ impl<'a> Visitor<'a> for KnownDirectives {
}
}
fn enter_field(&mut self, _ctx: &mut VisitorContext<'a>, _field: &'a Spanned<Field>) {
fn enter_field(&mut self, _ctx: &mut VisitorContext<'a>, _field: &'a Positioned<Field>) {
self.location_stack.push(__DirectiveLocation::FIELD);
}
fn exit_field(&mut self, _ctx: &mut VisitorContext<'a>, _field: &'a Spanned<Field>) {
fn exit_field(&mut self, _ctx: &mut VisitorContext<'a>, _field: &'a Positioned<Field>) {
self.location_stack.pop();
}
fn enter_fragment_spread(
&mut self,
_ctx: &mut VisitorContext<'a>,
_fragment_spread: &'a Spanned<FragmentSpread>,
_fragment_spread: &'a Positioned<FragmentSpread>,
) {
self.location_stack
.push(__DirectiveLocation::FRAGMENT_SPREAD);
@ -91,7 +95,7 @@ impl<'a> Visitor<'a> for KnownDirectives {
fn exit_fragment_spread(
&mut self,
_ctx: &mut VisitorContext<'a>,
_fragment_spread: &'a Spanned<FragmentSpread>,
_fragment_spread: &'a Positioned<FragmentSpread>,
) {
self.location_stack.pop();
}
@ -99,7 +103,7 @@ impl<'a> Visitor<'a> for KnownDirectives {
fn enter_inline_fragment(
&mut self,
_ctx: &mut VisitorContext<'a>,
_inline_fragment: &'a Spanned<InlineFragment>,
_inline_fragment: &'a Positioned<InlineFragment>,
) {
self.location_stack
.push(__DirectiveLocation::INLINE_FRAGMENT);
@ -108,7 +112,7 @@ impl<'a> Visitor<'a> for KnownDirectives {
fn exit_inline_fragment(
&mut self,
_ctx: &mut VisitorContext<'a>,
_inline_fragment: &'a Spanned<InlineFragment>,
_inline_fragment: &'a Positioned<InlineFragment>,
) {
self.location_stack.pop();
}

View File

@ -1,6 +1,6 @@
use crate::parser::ast::FragmentSpread;
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::Spanned;
use crate::Positioned;
#[derive(Default)]
pub struct KnownFragmentNames;
@ -9,7 +9,7 @@ impl<'a> Visitor<'a> for KnownFragmentNames {
fn enter_fragment_spread(
&mut self,
ctx: &mut VisitorContext<'a>,
fragment_spread: &'a Spanned<FragmentSpread>,
fragment_spread: &'a Positioned<FragmentSpread>,
) {
if !ctx.is_known_fragment(&fragment_spread.fragment_name) {
ctx.report_error(

View File

@ -1,7 +1,7 @@
use crate::parser::ast::{FragmentDefinition, InlineFragment, TypeCondition, VariableDefinition};
use crate::registry::TypeName;
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::{Pos, Spanned};
use crate::{Pos, Positioned};
#[derive(Default)]
pub struct KnownTypeNames;
@ -10,7 +10,7 @@ impl<'a> Visitor<'a> for KnownTypeNames {
fn enter_fragment_definition(
&mut self,
ctx: &mut VisitorContext<'a>,
fragment_definition: &'a Spanned<FragmentDefinition>,
fragment_definition: &'a Positioned<FragmentDefinition>,
) {
let TypeCondition::On(name) = &fragment_definition.type_condition.node;
validate_type(ctx, name.as_str(), fragment_definition.position());
@ -19,7 +19,7 @@ impl<'a> Visitor<'a> for KnownTypeNames {
fn enter_variable_definition(
&mut self,
ctx: &mut VisitorContext<'a>,
variable_definition: &'a Spanned<VariableDefinition>,
variable_definition: &'a Positioned<VariableDefinition>,
) {
validate_type(
ctx,
@ -31,7 +31,7 @@ impl<'a> Visitor<'a> for KnownTypeNames {
fn enter_inline_fragment(
&mut self,
ctx: &mut VisitorContext<'a>,
inline_fragment: &'a Spanned<InlineFragment>,
inline_fragment: &'a Positioned<InlineFragment>,
) {
if let Some(TypeCondition::On(name)) =
inline_fragment.type_condition.as_ref().map(|c| &c.node)

View File

@ -1,6 +1,6 @@
use crate::parser::ast::{Definition, Document, OperationDefinition};
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::Spanned;
use crate::Positioned;
#[derive(Default)]
pub struct LoneAnonymousOperation {
@ -23,7 +23,7 @@ impl<'a> Visitor<'a> for LoneAnonymousOperation {
fn enter_operation_definition(
&mut self,
ctx: &mut VisitorContext<'a>,
operation_definition: &'a Spanned<OperationDefinition>,
operation_definition: &'a Positioned<OperationDefinition>,
) {
if let Some(operation_count) = self.operation_count {
let (err, pos) = match &operation_definition.node {

View File

@ -1,7 +1,7 @@
use crate::error::RuleError;
use crate::parser::ast::{Document, FragmentDefinition, FragmentSpread};
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::{Pos, Spanned};
use crate::{Pos, Positioned};
use std::collections::{HashMap, HashSet};
struct CycleDetector<'a> {
@ -75,7 +75,7 @@ impl<'a> Visitor<'a> for NoFragmentCycles<'a> {
fn enter_fragment_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
fragment_definition: &'a Spanned<FragmentDefinition>,
fragment_definition: &'a Positioned<FragmentDefinition>,
) {
self.current_fragment = Some(&fragment_definition.name);
self.fragment_order.push(&fragment_definition.name);
@ -84,7 +84,7 @@ impl<'a> Visitor<'a> for NoFragmentCycles<'a> {
fn exit_fragment_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
_fragment_definition: &'a Spanned<FragmentDefinition>,
_fragment_definition: &'a Positioned<FragmentDefinition>,
) {
self.current_fragment = None;
}
@ -92,7 +92,7 @@ impl<'a> Visitor<'a> for NoFragmentCycles<'a> {
fn enter_fragment_spread(
&mut self,
_ctx: &mut VisitorContext<'a>,
fragment_spread: &'a Spanned<FragmentSpread>,
fragment_spread: &'a Positioned<FragmentSpread>,
) {
if let Some(current_fragment) = self.current_fragment {
self.spreads

View File

@ -3,7 +3,7 @@ use crate::parser::ast::{
};
use crate::validation::utils::{operation_name, referenced_variables, Scope};
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::{Pos, Spanned, Value};
use crate::{Pos, Positioned, Value};
use std::collections::{HashMap, HashSet};
#[derive(Default)]
@ -75,7 +75,7 @@ impl<'a> Visitor<'a> for NoUndefinedVariables<'a> {
fn enter_operation_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
operation_definition: &'a Spanned<OperationDefinition>,
operation_definition: &'a Positioned<OperationDefinition>,
) {
let (op_name, pos) = operation_name(&operation_definition);
self.current_scope = Some(Scope::Operation(op_name));
@ -86,7 +86,7 @@ impl<'a> Visitor<'a> for NoUndefinedVariables<'a> {
fn enter_fragment_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
fragment_definition: &'a Spanned<FragmentDefinition>,
fragment_definition: &'a Positioned<FragmentDefinition>,
) {
self.current_scope = Some(Scope::Fragment(fragment_definition.name.as_str()));
}
@ -94,7 +94,7 @@ impl<'a> Visitor<'a> for NoUndefinedVariables<'a> {
fn enter_variable_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
variable_definition: &'a Spanned<VariableDefinition>,
variable_definition: &'a Positioned<VariableDefinition>,
) {
if let Some(Scope::Operation(ref name)) = self.current_scope {
if let Some(&mut (_, ref mut vars)) = self.defined_variables.get_mut(name) {
@ -106,8 +106,8 @@ impl<'a> Visitor<'a> for NoUndefinedVariables<'a> {
fn enter_argument(
&mut self,
_ctx: &mut VisitorContext<'a>,
name: &'a Spanned<String>,
value: &'a Spanned<Value>,
name: &'a Positioned<String>,
value: &'a Positioned<Value>,
) {
if let Some(ref scope) = self.current_scope {
self.used_variables
@ -124,7 +124,7 @@ impl<'a> Visitor<'a> for NoUndefinedVariables<'a> {
fn enter_fragment_spread(
&mut self,
_ctx: &mut VisitorContext<'a>,
fragment_spread: &'a Spanned<FragmentSpread>,
fragment_spread: &'a Positioned<FragmentSpread>,
) {
if let Some(ref scope) = self.current_scope {
self.spreads

View File

@ -3,7 +3,7 @@ use crate::parser::ast::{
};
use crate::validation::utils::{operation_name, Scope};
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::{Pos, Spanned};
use crate::{Pos, Positioned};
use std::collections::{HashMap, HashSet};
#[derive(Default)]
@ -55,7 +55,7 @@ impl<'a> Visitor<'a> for NoUnusedFragments<'a> {
fn enter_operation_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
operation_definition: &'a Spanned<OperationDefinition>,
operation_definition: &'a Positioned<OperationDefinition>,
) {
let (op_name, _) = operation_name(operation_definition);
self.current_scope = Some(Scope::Operation(op_name));
@ -64,7 +64,7 @@ impl<'a> Visitor<'a> for NoUnusedFragments<'a> {
fn enter_fragment_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
fragment_definition: &'a Spanned<FragmentDefinition>,
fragment_definition: &'a Positioned<FragmentDefinition>,
) {
self.current_scope = Some(Scope::Fragment(fragment_definition.name.as_str()));
self.defined_fragments.insert((
@ -76,7 +76,7 @@ impl<'a> Visitor<'a> for NoUnusedFragments<'a> {
fn enter_fragment_spread(
&mut self,
_ctx: &mut VisitorContext<'a>,
fragment_spread: &'a Spanned<FragmentSpread>,
fragment_spread: &'a Positioned<FragmentSpread>,
) {
if let Some(ref scope) = self.current_scope {
self.spreads

View File

@ -3,7 +3,7 @@ use crate::parser::ast::{
};
use crate::validation::utils::{operation_name, referenced_variables, Scope};
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::{Pos, Spanned, Value};
use crate::{Pos, Positioned, Value};
use std::collections::{HashMap, HashSet};
#[derive(Default)]
@ -75,7 +75,7 @@ impl<'a> Visitor<'a> for NoUnusedVariables<'a> {
fn enter_operation_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
operation_definition: &'a Spanned<OperationDefinition>,
operation_definition: &'a Positioned<OperationDefinition>,
) {
let (op_name, _) = operation_name(operation_definition);
self.current_scope = Some(Scope::Operation(op_name));
@ -85,7 +85,7 @@ impl<'a> Visitor<'a> for NoUnusedVariables<'a> {
fn enter_fragment_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
fragment_definition: &'a Spanned<FragmentDefinition>,
fragment_definition: &'a Positioned<FragmentDefinition>,
) {
self.current_scope = Some(Scope::Fragment(fragment_definition.name.as_str()));
}
@ -93,7 +93,7 @@ impl<'a> Visitor<'a> for NoUnusedVariables<'a> {
fn enter_variable_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
variable_definition: &'a Spanned<VariableDefinition>,
variable_definition: &'a Positioned<VariableDefinition>,
) {
if let Some(Scope::Operation(ref name)) = self.current_scope {
if let Some(vars) = self.defined_variables.get_mut(name) {
@ -108,8 +108,8 @@ impl<'a> Visitor<'a> for NoUnusedVariables<'a> {
fn enter_argument(
&mut self,
_ctx: &mut VisitorContext<'a>,
_name: &'a Spanned<String>,
value: &'a Spanned<Value>,
_name: &'a Positioned<String>,
value: &'a Positioned<Value>,
) {
if let Some(ref scope) = self.current_scope {
self.used_variables
@ -122,7 +122,7 @@ impl<'a> Visitor<'a> for NoUnusedVariables<'a> {
fn enter_fragment_spread(
&mut self,
_ctx: &mut VisitorContext<'a>,
fragment_spread: &'a Spanned<FragmentSpread>,
fragment_spread: &'a Positioned<FragmentSpread>,
) {
if let Some(ref scope) = self.current_scope {
self.spreads

View File

@ -1,6 +1,6 @@
use crate::parser::ast::{Field, Selection, SelectionSet};
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::Spanned;
use crate::Positioned;
use std::collections::HashMap;
#[derive(Default)]
@ -10,7 +10,7 @@ impl<'a> Visitor<'a> for OverlappingFieldsCanBeMerged {
fn enter_selection_set(
&mut self,
ctx: &mut VisitorContext<'a>,
selection_set: &'a Spanned<SelectionSet>,
selection_set: &'a Positioned<SelectionSet>,
) {
let mut find_conflicts = FindConflicts {
outputs: Default::default(),
@ -21,12 +21,12 @@ impl<'a> Visitor<'a> for OverlappingFieldsCanBeMerged {
}
struct FindConflicts<'a, 'ctx> {
outputs: HashMap<&'a str, &'a Spanned<Field>>,
outputs: HashMap<&'a str, &'a Positioned<Field>>,
ctx: &'a mut VisitorContext<'ctx>,
}
impl<'a, 'ctx> FindConflicts<'a, 'ctx> {
pub fn find(&mut self, selection_set: &'a Spanned<SelectionSet>) {
pub fn find(&mut self, selection_set: &'a Positioned<SelectionSet>) {
for selection in &selection_set.items {
match &selection.node {
Selection::Field(field) => {
@ -49,7 +49,7 @@ impl<'a, 'ctx> FindConflicts<'a, 'ctx> {
}
}
fn add_output(&mut self, name: &'a str, field: &'a Spanned<Field>) {
fn add_output(&mut self, name: &'a str, field: &'a Positioned<Field>) {
if let Some(prev_field) = self.outputs.get(name) {
if prev_field.name != field.name {
self.ctx.report_error(

View File

@ -1,6 +1,6 @@
use crate::parser::ast::{Definition, Document, FragmentSpread, InlineFragment, TypeCondition};
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::Spanned;
use crate::Positioned;
use std::collections::HashMap;
#[derive(Default)]
@ -22,7 +22,7 @@ impl<'a> Visitor<'a> for PossibleFragmentSpreads<'a> {
fn enter_fragment_spread(
&mut self,
ctx: &mut VisitorContext<'a>,
fragment_spread: &'a Spanned<FragmentSpread>,
fragment_spread: &'a Positioned<FragmentSpread>,
) {
if let Some(fragment_type) = self
.fragment_types
@ -47,7 +47,7 @@ impl<'a> Visitor<'a> for PossibleFragmentSpreads<'a> {
fn enter_inline_fragment(
&mut self,
ctx: &mut VisitorContext<'a>,
inline_fragment: &'a Spanned<InlineFragment>,
inline_fragment: &'a Positioned<InlineFragment>,
) {
if let Some(parent_type) = ctx.parent_type() {
if let Some(TypeCondition::On(fragment_type)) =

View File

@ -1,13 +1,17 @@
use crate::parser::ast::{Directive, Field};
use crate::registry::TypeName;
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::Spanned;
use crate::Positioned;
#[derive(Default)]
pub struct ProvidedNonNullArguments;
impl<'a> Visitor<'a> for ProvidedNonNullArguments {
fn enter_directive(&mut self, ctx: &mut VisitorContext<'a>, directive: &'a Spanned<Directive>) {
fn enter_directive(
&mut self,
ctx: &mut VisitorContext<'a>,
directive: &'a Positioned<Directive>,
) {
if let Some(schema_directive) = ctx.registry.directives.get(directive.name.as_str()) {
for arg in schema_directive.args.values() {
if TypeName::create(&arg.ty).is_non_null()
@ -28,7 +32,7 @@ impl<'a> Visitor<'a> for ProvidedNonNullArguments {
}
}
fn enter_field(&mut self, ctx: &mut VisitorContext<'a>, field: &'a Spanned<Field>) {
fn enter_field(&mut self, ctx: &mut VisitorContext<'a>, field: &'a Positioned<Field>) {
if let Some(parent_type) = ctx.parent_type() {
if let Some(schema_field) = parent_type.field_by_name(&field.name) {
for arg in schema_field.args.values() {

View File

@ -1,12 +1,12 @@
use crate::parser::ast::Field;
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::Spanned;
use crate::Positioned;
#[derive(Default)]
pub struct ScalarLeafs;
impl<'a> Visitor<'a> for ScalarLeafs {
fn enter_field(&mut self, ctx: &mut VisitorContext<'a>, field: &'a Spanned<Field>) {
fn enter_field(&mut self, ctx: &mut VisitorContext<'a>, field: &'a Positioned<Field>) {
if let Some(ty) = ctx.parent_type() {
if let Some(schema_field) = ty.field_by_name(&field.name) {
if let Some(ty) = ctx.registry.concrete_type_by_name(&schema_field.ty) {

View File

@ -1,6 +1,6 @@
use crate::parser::ast::{Directive, Field};
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::{Spanned, Value};
use crate::{Positioned, Value};
use std::collections::HashSet;
#[derive(Default)]
@ -12,7 +12,7 @@ impl<'a> Visitor<'a> for UniqueArgumentNames<'a> {
fn enter_directive(
&mut self,
_ctx: &mut VisitorContext<'a>,
_directive: &'a Spanned<Directive>,
_directive: &'a Positioned<Directive>,
) {
self.names.clear();
}
@ -20,8 +20,8 @@ impl<'a> Visitor<'a> for UniqueArgumentNames<'a> {
fn enter_argument(
&mut self,
ctx: &mut VisitorContext<'a>,
name: &'a Spanned<String>,
_value: &'a Spanned<Value>,
name: &'a Positioned<String>,
_value: &'a Positioned<Value>,
) {
if !self.names.insert(name) {
ctx.report_error(
@ -31,7 +31,7 @@ impl<'a> Visitor<'a> for UniqueArgumentNames<'a> {
}
}
fn enter_field(&mut self, _ctx: &mut VisitorContext<'a>, _field: &'a Spanned<Field>) {
fn enter_field(&mut self, _ctx: &mut VisitorContext<'a>, _field: &'a Positioned<Field>) {
self.names.clear();
}
}

View File

@ -1,6 +1,6 @@
use crate::parser::ast::FragmentDefinition;
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::Spanned;
use crate::Positioned;
use std::collections::HashSet;
#[derive(Default)]
@ -12,7 +12,7 @@ impl<'a> Visitor<'a> for UniqueFragmentNames<'a> {
fn enter_fragment_definition(
&mut self,
ctx: &mut VisitorContext<'a>,
fragment_definition: &'a Spanned<FragmentDefinition>,
fragment_definition: &'a Positioned<FragmentDefinition>,
) {
if !self.names.insert(&fragment_definition.name) {
ctx.report_error(

View File

@ -1,6 +1,6 @@
use crate::parser::ast::{Mutation, OperationDefinition, Query, Subscription};
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::Spanned;
use crate::Positioned;
use std::collections::HashSet;
#[derive(Default)]
@ -12,18 +12,18 @@ impl<'a> Visitor<'a> for UniqueOperationNames<'a> {
fn enter_operation_definition(
&mut self,
ctx: &mut VisitorContext<'a>,
operation_definition: &'a Spanned<OperationDefinition>,
operation_definition: &'a Positioned<OperationDefinition>,
) {
let name = match &operation_definition.node {
OperationDefinition::Query(Spanned {
OperationDefinition::Query(Positioned {
node: Query { name, .. },
..
}) => name.as_ref(),
OperationDefinition::Mutation(Spanned {
OperationDefinition::Mutation(Positioned {
node: Mutation { name, .. },
..
}) => name.as_ref(),
OperationDefinition::Subscription(Spanned {
OperationDefinition::Subscription(Positioned {
node: Subscription { name, .. },
..
}) => name.as_ref(),

View File

@ -1,6 +1,6 @@
use crate::parser::ast::{OperationDefinition, VariableDefinition};
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::Spanned;
use crate::Positioned;
use std::collections::HashSet;
#[derive(Default)]
@ -12,7 +12,7 @@ impl<'a> Visitor<'a> for UniqueVariableNames<'a> {
fn enter_operation_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
_operation_definition: &'a Spanned<OperationDefinition>,
_operation_definition: &'a Positioned<OperationDefinition>,
) {
self.names.clear();
}
@ -20,7 +20,7 @@ impl<'a> Visitor<'a> for UniqueVariableNames<'a> {
fn enter_variable_definition(
&mut self,
ctx: &mut VisitorContext<'a>,
variable_definition: &'a Spanned<VariableDefinition>,
variable_definition: &'a Positioned<VariableDefinition>,
) {
if !self.names.insert(variable_definition.name.as_str()) {
ctx.report_error(

View File

@ -1,6 +1,6 @@
use crate::parser::ast::OperationDefinition;
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::Spanned;
use crate::Positioned;
#[derive(Default)]
pub struct UploadFile;
@ -9,7 +9,7 @@ impl<'a> Visitor<'a> for UploadFile {
fn enter_operation_definition(
&mut self,
ctx: &mut VisitorContext<'a>,
operation_definition: &'a Spanned<OperationDefinition>,
operation_definition: &'a Positioned<OperationDefinition>,
) {
if let OperationDefinition::Query(query) = &operation_definition.node {
for var in &query.variable_definitions {

View File

@ -1,6 +1,6 @@
use crate::parser::ast::VariableDefinition;
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::Spanned;
use crate::Positioned;
#[derive(Default)]
pub struct VariablesAreInputTypes;
@ -9,7 +9,7 @@ impl<'a> Visitor<'a> for VariablesAreInputTypes {
fn enter_variable_definition(
&mut self,
ctx: &mut VisitorContext<'a>,
variable_definition: &'a Spanned<VariableDefinition>,
variable_definition: &'a Positioned<VariableDefinition>,
) {
if let Some(ty) = ctx
.registry

View File

@ -4,14 +4,14 @@ use crate::parser::ast::{
use crate::registry::TypeName;
use crate::validation::utils::{operation_name, Scope};
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::{Pos, Spanned, Value};
use crate::{Pos, Positioned, Value};
use std::collections::{HashMap, HashSet};
#[derive(Default)]
pub struct VariableInAllowedPosition<'a> {
spreads: HashMap<Scope<'a>, HashSet<&'a str>>,
variable_usages: HashMap<Scope<'a>, Vec<(&'a str, Pos, TypeName<'a>)>>,
variable_defs: HashMap<Scope<'a>, Vec<&'a Spanned<VariableDefinition>>>,
variable_defs: HashMap<Scope<'a>, Vec<&'a Positioned<VariableDefinition>>>,
current_scope: Option<Scope<'a>>,
}
@ -19,7 +19,7 @@ impl<'a> VariableInAllowedPosition<'a> {
fn collect_incorrect_usages(
&self,
from: &Scope<'a>,
var_defs: &[&'a Spanned<VariableDefinition>],
var_defs: &[&'a Positioned<VariableDefinition>],
ctx: &mut VisitorContext<'a>,
visited: &mut HashSet<Scope<'a>>,
) {
@ -69,7 +69,7 @@ impl<'a> Visitor<'a> for VariableInAllowedPosition<'a> {
fn enter_operation_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
operation_definition: &'a Spanned<OperationDefinition>,
operation_definition: &'a Positioned<OperationDefinition>,
) {
let (op_name, _) = operation_name(operation_definition);
self.current_scope = Some(Scope::Operation(op_name));
@ -78,7 +78,7 @@ impl<'a> Visitor<'a> for VariableInAllowedPosition<'a> {
fn enter_fragment_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
fragment_definition: &'a Spanned<FragmentDefinition>,
fragment_definition: &'a Positioned<FragmentDefinition>,
) {
self.current_scope = Some(Scope::Fragment(fragment_definition.name.as_str()));
}
@ -86,7 +86,7 @@ impl<'a> Visitor<'a> for VariableInAllowedPosition<'a> {
fn enter_variable_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
variable_definition: &'a Spanned<VariableDefinition>,
variable_definition: &'a Positioned<VariableDefinition>,
) {
if let Some(ref scope) = self.current_scope {
self.variable_defs
@ -99,7 +99,7 @@ impl<'a> Visitor<'a> for VariableInAllowedPosition<'a> {
fn enter_fragment_spread(
&mut self,
_ctx: &mut VisitorContext<'a>,
fragment_spread: &'a Spanned<FragmentSpread>,
fragment_spread: &'a Positioned<FragmentSpread>,
) {
if let Some(ref scope) = self.current_scope {
self.spreads

View File

@ -4,7 +4,7 @@ use crate::parser::ast::{
OperationDefinition, Selection, SelectionSet, TypeCondition, VariableDefinition,
};
use crate::registry::{self, Type, TypeName};
use crate::{Pos, Spanned, Value};
use crate::{Pos, Positioned, Value};
use std::collections::HashMap;
pub struct VisitorContext<'a> {
@ -12,7 +12,7 @@ pub struct VisitorContext<'a> {
pub errors: Vec<RuleError>,
type_stack: Vec<Option<&'a registry::Type>>,
input_type: Vec<Option<TypeName<'a>>>,
fragments: HashMap<&'a str, &'a Spanned<FragmentDefinition>>,
fragments: HashMap<&'a str, &'a Positioned<FragmentDefinition>>,
}
impl<'a> VisitorContext<'a> {
@ -83,7 +83,7 @@ impl<'a> VisitorContext<'a> {
self.fragments.contains_key(name)
}
pub fn fragment(&self, name: &str) -> Option<&'a Spanned<FragmentDefinition>> {
pub fn fragment(&self, name: &str) -> Option<&'a Positioned<FragmentDefinition>> {
self.fragments.get(name).copied()
}
}
@ -95,122 +95,122 @@ pub trait Visitor<'a> {
fn enter_operation_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
_operation_definition: &'a Spanned<OperationDefinition>,
_operation_definition: &'a Positioned<OperationDefinition>,
) {
}
fn exit_operation_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
_operation_definition: &'a Spanned<OperationDefinition>,
_operation_definition: &'a Positioned<OperationDefinition>,
) {
}
fn enter_fragment_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
_fragment_definition: &'a Spanned<FragmentDefinition>,
_fragment_definition: &'a Positioned<FragmentDefinition>,
) {
}
fn exit_fragment_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
_fragment_definition: &'a Spanned<FragmentDefinition>,
_fragment_definition: &'a Positioned<FragmentDefinition>,
) {
}
fn enter_variable_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
_variable_definition: &'a Spanned<VariableDefinition>,
_variable_definition: &'a Positioned<VariableDefinition>,
) {
}
fn exit_variable_definition(
&mut self,
_ctx: &mut VisitorContext<'a>,
_variable_definition: &'a Spanned<VariableDefinition>,
_variable_definition: &'a Positioned<VariableDefinition>,
) {
}
fn enter_directive(
&mut self,
_ctx: &mut VisitorContext<'a>,
_directive: &'a Spanned<Directive>,
_directive: &'a Positioned<Directive>,
) {
}
fn exit_directive(
&mut self,
_ctx: &mut VisitorContext<'a>,
_directive: &'a Spanned<Directive>,
_directive: &'a Positioned<Directive>,
) {
}
fn enter_argument(
&mut self,
_ctx: &mut VisitorContext<'a>,
_name: &'a Spanned<String>,
_value: &'a Spanned<Value>,
_name: &'a Positioned<String>,
_value: &'a Positioned<Value>,
) {
}
fn exit_argument(
&mut self,
_ctx: &mut VisitorContext<'a>,
_name: &'a Spanned<String>,
_value: &'a Spanned<Value>,
_name: &'a Positioned<String>,
_value: &'a Positioned<Value>,
) {
}
fn enter_selection_set(
&mut self,
_ctx: &mut VisitorContext<'a>,
_selection_set: &'a Spanned<SelectionSet>,
_selection_set: &'a Positioned<SelectionSet>,
) {
}
fn exit_selection_set(
&mut self,
_ctx: &mut VisitorContext<'a>,
_selection_set: &'a Spanned<SelectionSet>,
_selection_set: &'a Positioned<SelectionSet>,
) {
}
fn enter_selection(
&mut self,
_ctx: &mut VisitorContext<'a>,
_selection: &'a Spanned<Selection>,
_selection: &'a Positioned<Selection>,
) {
}
fn exit_selection(
&mut self,
_ctx: &mut VisitorContext<'a>,
_selection: &'a Spanned<Selection>,
_selection: &'a Positioned<Selection>,
) {
}
fn enter_field(&mut self, _ctx: &mut VisitorContext<'a>, _field: &'a Spanned<Field>) {}
fn exit_field(&mut self, _ctx: &mut VisitorContext<'a>, _field: &'a Spanned<Field>) {}
fn enter_field(&mut self, _ctx: &mut VisitorContext<'a>, _field: &'a Positioned<Field>) {}
fn exit_field(&mut self, _ctx: &mut VisitorContext<'a>, _field: &'a Positioned<Field>) {}
fn enter_fragment_spread(
&mut self,
_ctx: &mut VisitorContext<'a>,
_fragment_spread: &'a Spanned<FragmentSpread>,
_fragment_spread: &'a Positioned<FragmentSpread>,
) {
}
fn exit_fragment_spread(
&mut self,
_ctx: &mut VisitorContext<'a>,
_fragment_spread: &'a Spanned<FragmentSpread>,
_fragment_spread: &'a Positioned<FragmentSpread>,
) {
}
fn enter_inline_fragment(
&mut self,
_ctx: &mut VisitorContext<'a>,
_inline_fragment: &'a Spanned<InlineFragment>,
_inline_fragment: &'a Positioned<InlineFragment>,
) {
}
fn exit_inline_fragment(
&mut self,
_ctx: &mut VisitorContext<'a>,
_inline_fragment: &'a Spanned<InlineFragment>,
_inline_fragment: &'a Positioned<InlineFragment>,
) {
}
@ -268,7 +268,7 @@ where
fn enter_operation_definition(
&mut self,
ctx: &mut VisitorContext<'a>,
operation_definition: &'a Spanned<OperationDefinition>,
operation_definition: &'a Positioned<OperationDefinition>,
) {
self.0.enter_operation_definition(ctx, operation_definition);
self.1.enter_operation_definition(ctx, operation_definition);
@ -277,7 +277,7 @@ where
fn exit_operation_definition(
&mut self,
ctx: &mut VisitorContext<'a>,
operation_definition: &'a Spanned<OperationDefinition>,
operation_definition: &'a Positioned<OperationDefinition>,
) {
self.0.exit_operation_definition(ctx, operation_definition);
self.1.exit_operation_definition(ctx, operation_definition);
@ -286,7 +286,7 @@ where
fn enter_fragment_definition(
&mut self,
ctx: &mut VisitorContext<'a>,
fragment_definition: &'a Spanned<FragmentDefinition>,
fragment_definition: &'a Positioned<FragmentDefinition>,
) {
self.0.enter_fragment_definition(ctx, fragment_definition);
self.1.enter_fragment_definition(ctx, fragment_definition);
@ -295,7 +295,7 @@ where
fn exit_fragment_definition(
&mut self,
ctx: &mut VisitorContext<'a>,
fragment_definition: &'a Spanned<FragmentDefinition>,
fragment_definition: &'a Positioned<FragmentDefinition>,
) {
self.0.exit_fragment_definition(ctx, fragment_definition);
self.1.exit_fragment_definition(ctx, fragment_definition);
@ -304,7 +304,7 @@ where
fn enter_variable_definition(
&mut self,
ctx: &mut VisitorContext<'a>,
variable_definition: &'a Spanned<VariableDefinition>,
variable_definition: &'a Positioned<VariableDefinition>,
) {
self.0.enter_variable_definition(ctx, variable_definition);
self.1.enter_variable_definition(ctx, variable_definition);
@ -313,18 +313,26 @@ where
fn exit_variable_definition(
&mut self,
ctx: &mut VisitorContext<'a>,
variable_definition: &'a Spanned<VariableDefinition>,
variable_definition: &'a Positioned<VariableDefinition>,
) {
self.0.exit_variable_definition(ctx, variable_definition);
self.1.exit_variable_definition(ctx, variable_definition);
}
fn enter_directive(&mut self, ctx: &mut VisitorContext<'a>, directive: &'a Spanned<Directive>) {
fn enter_directive(
&mut self,
ctx: &mut VisitorContext<'a>,
directive: &'a Positioned<Directive>,
) {
self.0.enter_directive(ctx, directive);
self.1.enter_directive(ctx, directive);
}
fn exit_directive(&mut self, ctx: &mut VisitorContext<'a>, directive: &'a Spanned<Directive>) {
fn exit_directive(
&mut self,
ctx: &mut VisitorContext<'a>,
directive: &'a Positioned<Directive>,
) {
self.0.exit_directive(ctx, directive);
self.1.exit_directive(ctx, directive);
}
@ -332,8 +340,8 @@ where
fn enter_argument(
&mut self,
ctx: &mut VisitorContext<'a>,
name: &'a Spanned<String>,
value: &'a Spanned<Value>,
name: &'a Positioned<String>,
value: &'a Positioned<Value>,
) {
self.0.enter_argument(ctx, name, value);
self.1.enter_argument(ctx, name, value);
@ -342,8 +350,8 @@ where
fn exit_argument(
&mut self,
ctx: &mut VisitorContext<'a>,
name: &'a Spanned<String>,
value: &'a Spanned<Value>,
name: &'a Positioned<String>,
value: &'a Positioned<Value>,
) {
self.0.exit_argument(ctx, name, value);
self.1.exit_argument(ctx, name, value);
@ -352,7 +360,7 @@ where
fn enter_selection_set(
&mut self,
ctx: &mut VisitorContext<'a>,
selection_set: &'a Spanned<SelectionSet>,
selection_set: &'a Positioned<SelectionSet>,
) {
self.0.enter_selection_set(ctx, selection_set);
self.1.enter_selection_set(ctx, selection_set);
@ -361,28 +369,36 @@ where
fn exit_selection_set(
&mut self,
ctx: &mut VisitorContext<'a>,
selection_set: &'a Spanned<SelectionSet>,
selection_set: &'a Positioned<SelectionSet>,
) {
self.0.exit_selection_set(ctx, selection_set);
self.1.exit_selection_set(ctx, selection_set);
}
fn enter_selection(&mut self, ctx: &mut VisitorContext<'a>, selection: &'a Spanned<Selection>) {
fn enter_selection(
&mut self,
ctx: &mut VisitorContext<'a>,
selection: &'a Positioned<Selection>,
) {
self.0.enter_selection(ctx, selection);
self.1.enter_selection(ctx, selection);
}
fn exit_selection(&mut self, ctx: &mut VisitorContext<'a>, selection: &'a Spanned<Selection>) {
fn exit_selection(
&mut self,
ctx: &mut VisitorContext<'a>,
selection: &'a Positioned<Selection>,
) {
self.0.exit_selection(ctx, selection);
self.1.exit_selection(ctx, selection);
}
fn enter_field(&mut self, ctx: &mut VisitorContext<'a>, field: &'a Spanned<Field>) {
fn enter_field(&mut self, ctx: &mut VisitorContext<'a>, field: &'a Positioned<Field>) {
self.0.enter_field(ctx, field);
self.1.enter_field(ctx, field);
}
fn exit_field(&mut self, ctx: &mut VisitorContext<'a>, field: &'a Spanned<Field>) {
fn exit_field(&mut self, ctx: &mut VisitorContext<'a>, field: &'a Positioned<Field>) {
self.0.exit_field(ctx, field);
self.1.exit_field(ctx, field);
}
@ -390,7 +406,7 @@ where
fn enter_fragment_spread(
&mut self,
ctx: &mut VisitorContext<'a>,
fragment_spread: &'a Spanned<FragmentSpread>,
fragment_spread: &'a Positioned<FragmentSpread>,
) {
self.0.enter_fragment_spread(ctx, fragment_spread);
self.1.enter_fragment_spread(ctx, fragment_spread);
@ -399,7 +415,7 @@ where
fn exit_fragment_spread(
&mut self,
ctx: &mut VisitorContext<'a>,
fragment_spread: &'a Spanned<FragmentSpread>,
fragment_spread: &'a Positioned<FragmentSpread>,
) {
self.0.exit_fragment_spread(ctx, fragment_spread);
self.1.exit_fragment_spread(ctx, fragment_spread);
@ -408,7 +424,7 @@ where
fn enter_inline_fragment(
&mut self,
ctx: &mut VisitorContext<'a>,
inline_fragment: &'a Spanned<InlineFragment>,
inline_fragment: &'a Positioned<InlineFragment>,
) {
self.0.enter_inline_fragment(ctx, inline_fragment);
self.1.enter_inline_fragment(ctx, inline_fragment);
@ -417,7 +433,7 @@ where
fn exit_inline_fragment(
&mut self,
ctx: &mut VisitorContext<'a>,
inline_fragment: &'a Spanned<InlineFragment>,
inline_fragment: &'a Positioned<InlineFragment>,
) {
self.0.exit_inline_fragment(ctx, inline_fragment);
self.1.exit_inline_fragment(ctx, inline_fragment);
@ -453,7 +469,7 @@ fn visit_definitions<'a, V: Visitor<'a>>(
fn visit_operation_definition<'a, V: Visitor<'a>>(
v: &mut V,
ctx: &mut VisitorContext<'a>,
operation: &'a Spanned<OperationDefinition>,
operation: &'a Positioned<OperationDefinition>,
) {
v.enter_operation_definition(ctx, operation);
match &operation.node {
@ -504,7 +520,7 @@ fn visit_operation_definition<'a, V: Visitor<'a>>(
fn visit_selection_set<'a, V: Visitor<'a>>(
v: &mut V,
ctx: &mut VisitorContext<'a>,
selection_set: &'a Spanned<SelectionSet>,
selection_set: &'a Positioned<SelectionSet>,
) {
if !selection_set.items.is_empty() {
v.enter_selection_set(ctx, selection_set);
@ -518,7 +534,7 @@ fn visit_selection_set<'a, V: Visitor<'a>>(
fn visit_selection<'a, V: Visitor<'a>>(
v: &mut V,
ctx: &mut VisitorContext<'a>,
selection: &'a Spanned<Selection>,
selection: &'a Positioned<Selection>,
) {
v.enter_selection(ctx, selection);
match &selection.node {
@ -555,7 +571,7 @@ fn visit_selection<'a, V: Visitor<'a>>(
fn visit_field<'a, V: Visitor<'a>>(
v: &mut V,
ctx: &mut VisitorContext<'a>,
field: &'a Spanned<Field>,
field: &'a Positioned<Field>,
) {
v.enter_field(ctx, field);
@ -632,7 +648,7 @@ fn visit_input_value<'a, V: Visitor<'a>>(
fn visit_variable_definitions<'a, V: Visitor<'a>>(
v: &mut V,
ctx: &mut VisitorContext<'a>,
variable_definitions: &'a [Spanned<VariableDefinition>],
variable_definitions: &'a [Positioned<VariableDefinition>],
) {
for d in variable_definitions {
v.enter_variable_definition(ctx, d);
@ -643,7 +659,7 @@ fn visit_variable_definitions<'a, V: Visitor<'a>>(
fn visit_directives<'a, V: Visitor<'a>>(
v: &mut V,
ctx: &mut VisitorContext<'a>,
directives: &'a [Spanned<Directive>],
directives: &'a [Positioned<Directive>],
) {
for d in directives {
v.enter_directive(ctx, d);
@ -668,7 +684,7 @@ fn visit_directives<'a, V: Visitor<'a>>(
fn visit_fragment_definition<'a, V: Visitor<'a>>(
v: &mut V,
ctx: &mut VisitorContext<'a>,
fragment: &'a Spanned<FragmentDefinition>,
fragment: &'a Positioned<FragmentDefinition>,
) {
v.enter_fragment_definition(ctx, fragment);
visit_directives(v, ctx, &fragment.directives);
@ -679,7 +695,7 @@ fn visit_fragment_definition<'a, V: Visitor<'a>>(
fn visit_fragment_spread<'a, V: Visitor<'a>>(
v: &mut V,
ctx: &mut VisitorContext<'a>,
fragment_spread: &'a Spanned<FragmentSpread>,
fragment_spread: &'a Positioned<FragmentSpread>,
) {
v.enter_fragment_spread(ctx, fragment_spread);
visit_directives(v, ctx, &fragment_spread.directives);
@ -689,7 +705,7 @@ fn visit_fragment_spread<'a, V: Visitor<'a>>(
fn visit_inline_fragment<'a, V: Visitor<'a>>(
v: &mut V,
ctx: &mut VisitorContext<'a>,
inline_fragment: &'a Spanned<InlineFragment>,
inline_fragment: &'a Positioned<InlineFragment>,
) {
v.enter_inline_fragment(ctx, inline_fragment);
visit_directives(v, ctx, &inline_fragment.directives);

View File

@ -1,7 +1,7 @@
use crate::parser::ast::{Field, SelectionSet};
use crate::registry::Type;
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::{CacheControl, Spanned};
use crate::{CacheControl, Positioned};
pub struct CacheControlCalculate<'a> {
pub cache_control: &'a mut CacheControl,
@ -11,7 +11,7 @@ impl<'ctx, 'a> Visitor<'ctx> for CacheControlCalculate<'a> {
fn enter_selection_set(
&mut self,
ctx: &mut VisitorContext<'_>,
_selection_set: &Spanned<SelectionSet>,
_selection_set: &Positioned<SelectionSet>,
) {
if let Some(current_type) = ctx.current_type() {
if let Type::Object { cache_control, .. } = current_type {
@ -20,7 +20,7 @@ impl<'ctx, 'a> Visitor<'ctx> for CacheControlCalculate<'a> {
}
}
fn enter_field(&mut self, ctx: &mut VisitorContext<'_>, field: &Spanned<Field>) {
fn enter_field(&mut self, ctx: &mut VisitorContext<'_>, field: &Positioned<Field>) {
if let Some(registry_field) = ctx
.parent_type()
.and_then(|parent| parent.field_by_name(&field.name))

View File

@ -1,13 +1,13 @@
use crate::parser::ast::Field;
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::Spanned;
use crate::Positioned;
pub struct ComplexityCalculate<'a> {
pub complexity: &'a mut usize,
}
impl<'ctx, 'a> Visitor<'ctx> for ComplexityCalculate<'a> {
fn enter_field(&mut self, _ctx: &mut VisitorContext<'_>, _field: &Spanned<Field>) {
fn enter_field(&mut self, _ctx: &mut VisitorContext<'_>, _field: &Positioned<Field>) {
*self.complexity += 1;
}
}

View File

@ -1,6 +1,6 @@
use crate::parser::ast::{FragmentSpread, InlineFragment, SelectionSet};
use crate::validation::visitor::{Visitor, VisitorContext};
use crate::Spanned;
use crate::Positioned;
pub struct DepthCalculate<'a> {
max_depth: &'a mut i32,
@ -21,7 +21,7 @@ impl<'ctx, 'a> Visitor<'ctx> for DepthCalculate<'a> {
fn enter_selection_set(
&mut self,
_ctx: &mut VisitorContext<'ctx>,
_selection_set: &'ctx Spanned<SelectionSet>,
_selection_set: &'ctx Positioned<SelectionSet>,
) {
self.current_depth += 1;
*self.max_depth = (*self.max_depth).max(self.current_depth);
@ -30,7 +30,7 @@ impl<'ctx, 'a> Visitor<'ctx> for DepthCalculate<'a> {
fn exit_selection_set(
&mut self,
_ctx: &mut VisitorContext<'ctx>,
_selection_set: &'ctx Spanned<SelectionSet>,
_selection_set: &'ctx Positioned<SelectionSet>,
) {
self.current_depth -= 1;
}
@ -38,7 +38,7 @@ impl<'ctx, 'a> Visitor<'ctx> for DepthCalculate<'a> {
fn enter_fragment_spread(
&mut self,
_ctx: &mut VisitorContext<'ctx>,
_fragment_spread: &'ctx Spanned<FragmentSpread>,
_fragment_spread: &'ctx Positioned<FragmentSpread>,
) {
self.current_depth -= 1;
}
@ -46,7 +46,7 @@ impl<'ctx, 'a> Visitor<'ctx> for DepthCalculate<'a> {
fn exit_fragment_spread(
&mut self,
_ctx: &mut VisitorContext<'ctx>,
_fragment_spread: &'ctx Spanned<FragmentSpread>,
_fragment_spread: &'ctx Positioned<FragmentSpread>,
) {
self.current_depth += 1;
}
@ -54,7 +54,7 @@ impl<'ctx, 'a> Visitor<'ctx> for DepthCalculate<'a> {
fn enter_inline_fragment(
&mut self,
_ctx: &mut VisitorContext<'ctx>,
_inline_fragment: &'ctx Spanned<InlineFragment>,
_inline_fragment: &'ctx Positioned<InlineFragment>,
) {
self.current_depth -= 1;
}
@ -62,7 +62,7 @@ impl<'ctx, 'a> Visitor<'ctx> for DepthCalculate<'a> {
fn exit_inline_fragment(
&mut self,
_ctx: &mut VisitorContext<'ctx>,
_inline_fragment: &'ctx Spanned<InlineFragment>,
_inline_fragment: &'ctx Positioned<InlineFragment>,
) {
self.current_depth += 1;
}