Skip to content

Commit 7a42caf

Browse files
committed
Improve TypeInfoQueryVisitor and support empty ref
added FieldsOnCorrectType rule
1 parent afa4bc8 commit 7a42caf

File tree

7 files changed

+664
-178
lines changed

7 files changed

+664
-178
lines changed

src/ast/ext.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::static_graphql::query::{self};
22
use crate::static_graphql::schema::{self, Field, InterfaceType, ObjectType, UnionType};
33

4-
use super::get_named_type;
4+
use super::{get_named_type, TypeInfoElementRef};
55

66
pub trait AstNodeWithFields {
77
fn find_field(&self, name: String) -> Option<&Field>;
@@ -42,6 +42,15 @@ pub enum CompositeType {
4242
Union(schema::UnionType),
4343
}
4444

45+
impl TypeInfoElementRef<CompositeType> {
46+
pub fn find_field(&self, name: String) -> Option<&Field> {
47+
match self {
48+
TypeInfoElementRef::Empty => None,
49+
TypeInfoElementRef::Ref(composite_type) => composite_type.find_field(name),
50+
}
51+
}
52+
}
53+
4554
impl CompositeType {
4655
pub fn find_field(&self, name: String) -> Option<&Field> {
4756
match self {
@@ -68,6 +77,28 @@ pub trait TypeDefinitionExtension {
6877
fn name(&self) -> String;
6978
}
7079

80+
impl TypeDefinitionExtension for CompositeType {
81+
fn is_leaf_type(&self) -> bool {
82+
false
83+
}
84+
85+
fn is_composite_type(&self) -> bool {
86+
true
87+
}
88+
89+
fn is_input_type(&self) -> bool {
90+
false
91+
}
92+
93+
fn name(&self) -> String {
94+
match self {
95+
CompositeType::Object(o) => o.name.clone(),
96+
CompositeType::Interface(i) => i.name.clone(),
97+
CompositeType::Union(u) => u.name.clone(),
98+
}
99+
}
100+
}
101+
71102
impl TypeDefinitionExtension for schema::TypeDefinition {
72103
fn name(&self) -> String {
73104
match self {

src/ast/type_info.rs

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,19 @@ impl<'a> TypeInfoRegistry<'a> {
8686
}
8787
}
8888

89+
/// This struct is used to mark a "node" or nothing (null, undefined). While tracking TypeInfo, we need to check if there was a node before or not.
90+
#[derive(Debug, Clone, Copy)]
91+
pub enum TypeInfoElementRef<T> {
92+
Empty,
93+
Ref(T),
94+
}
95+
8996
pub struct TypeInfo {
90-
pub type_stack: Vec<schema::Type>,
91-
pub parent_type_stack: Vec<CompositeType>,
92-
pub field_def_stack: Vec<schema::Field>,
93-
pub input_type_stack: Vec<schema::InputObjectType>,
94-
pub argument: Option<schema::InputValue>,
97+
pub type_stack: Vec<TypeInfoElementRef<schema::Type>>,
98+
pub parent_type_stack: Vec<TypeInfoElementRef<CompositeType>>,
99+
pub field_def_stack: Vec<TypeInfoElementRef<schema::Field>>,
100+
pub input_type_stack: Vec<TypeInfoElementRef<schema::InputObjectType>>,
101+
pub argument: Option<TypeInfoElementRef<schema::InputValue>>,
95102
}
96103

97104
impl TypeInfo {
@@ -105,59 +112,59 @@ impl TypeInfo {
105112
};
106113
}
107114

108-
pub fn get_argument(&self) -> Option<schema::InputValue> {
115+
pub fn get_argument(&self) -> Option<TypeInfoElementRef<schema::InputValue>> {
109116
self.argument.clone()
110117
}
111118

112-
pub fn enter_argument(&mut self, input_value: schema::InputValue) {
119+
pub fn enter_argument(&mut self, input_value: TypeInfoElementRef<schema::InputValue>) {
113120
self.argument = Some(input_value);
114121
}
115122

116123
pub fn leave_argument(&mut self) {
117124
self.argument = None;
118125
}
119126

120-
pub fn get_type(&self) -> Option<schema::Type> {
127+
pub fn get_type(&self) -> Option<TypeInfoElementRef<schema::Type>> {
121128
self.type_stack.last().cloned()
122129
}
123130

124-
pub fn enter_type(&mut self, object: schema::Type) {
131+
pub fn enter_type(&mut self, object: TypeInfoElementRef<schema::Type>) {
125132
self.type_stack.push(object);
126133
}
127134

128135
pub fn leave_type(&mut self) {
129136
self.type_stack.pop();
130137
}
131138

132-
pub fn get_input_type(&self) -> Option<schema::InputObjectType> {
139+
pub fn get_input_type(&self) -> Option<TypeInfoElementRef<schema::InputObjectType>> {
133140
self.input_type_stack.last().cloned()
134141
}
135142

136-
pub fn enter_input_type(&mut self, object: schema::InputObjectType) {
143+
pub fn enter_input_type(&mut self, object: TypeInfoElementRef<schema::InputObjectType>) {
137144
self.input_type_stack.push(object);
138145
}
139146

140147
pub fn leave_input_type(&mut self) {
141148
self.input_type_stack.pop();
142149
}
143150

144-
pub fn get_parent_type(&self) -> Option<CompositeType> {
151+
pub fn get_parent_type(&self) -> Option<TypeInfoElementRef<CompositeType>> {
145152
self.parent_type_stack.last().cloned()
146153
}
147154

148-
pub fn enter_parent_type(&mut self, object: CompositeType) {
155+
pub fn enter_parent_type(&mut self, object: TypeInfoElementRef<CompositeType>) {
149156
self.parent_type_stack.push(object);
150157
}
151158

152159
pub fn leave_parent_type(&mut self) {
153160
self.parent_type_stack.pop();
154161
}
155162

156-
pub fn get_field_def(&self) -> Option<schema::Field> {
163+
pub fn get_field_def(&self) -> Option<TypeInfoElementRef<schema::Field>> {
157164
self.field_def_stack.last().cloned()
158165
}
159166

160-
pub fn enter_field_def(&mut self, field: schema::Field) {
167+
pub fn enter_field_def(&mut self, field: TypeInfoElementRef<schema::Field>) {
161168
self.field_def_stack.push(field);
162169
}
163170

0 commit comments

Comments
 (0)