Skip to content

Commit

Permalink
Merge e498d72 into d95f7dc
Browse files Browse the repository at this point in the history
  • Loading branch information
gabotechs authored Nov 19, 2022
2 parents d95f7dc + e498d72 commit 934a31e
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 82 deletions.
6 changes: 3 additions & 3 deletions graphqxl_parser/src/ast_spec.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::ast_import::parse_import;
use crate::parser::{GraphqxlParser, Rule};
use crate::utils::{already_defined_error, unknown_rule_error, NoopRuleType};
use crate::parser::{GraphqxlParser, Rule, RuleError};
use crate::utils::{already_defined_error, unknown_rule_error};
use crate::{
parse_block_def, parse_directive_def, parse_generic_block_def, parse_scalar, parse_schema,
parse_union, BlockDef, DirectiveDef, GenericBlockDef, Identifier, OwnedSpan, Scalar, Schema,
Expand Down Expand Up @@ -157,7 +157,7 @@ impl Spec {
match pair.as_rule() {
Rule::schema_def => {
if self.schema_already_defined {
Err(Box::new(pest::error::Error::<NoopRuleType>::new_from_span(
Err(Box::new(RuleError::new_from_span(
pest::error::ErrorVariant::CustomError {
message: "schema is defined multiple times".to_string(),
},
Expand Down
73 changes: 46 additions & 27 deletions graphqxl_parser/src/ast_value_type.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
use crate::ast_value_basic_type::{parse_value_basic_type, ValueBasicType};
use crate::parser::{Rule, RuleError};
use crate::utils::unknown_rule_error;
use crate::Identifier;
use crate::{Identifier, OwnedSpan};
use pest::iterators::Pair;

#[derive(Debug, Clone, PartialEq)]
pub enum ValueType {
Basic(ValueBasicType),
Array(Box<ValueType>),
NonNullable(Box<ValueType>),
Basic(ValueBasicType, OwnedSpan),
Array(Box<ValueType>, OwnedSpan),
NonNullable(Box<ValueType>, OwnedSpan),
}

impl ValueType {
pub fn build(t: ValueBasicType) -> Self {
Self::Basic(t)
Self::Basic(t, OwnedSpan::default())
}

pub fn span(&self) -> &OwnedSpan {
match self {
ValueType::Basic(_, span) => span,
ValueType::Array(_, span) => span,
ValueType::NonNullable(_, span) => span,
}
}

pub fn int() -> Self {
Expand All @@ -36,43 +44,52 @@ impl ValueType {
Self::build(ValueBasicType::Object(identifier))
}

pub fn non_nullable(&mut self) -> Self {
ValueType::NonNullable(Box::new(self.clone()))
pub fn non_nullable(&self) -> Self {
ValueType::NonNullable(Box::new(self.clone()), self.span().clone())
}

pub fn array(&mut self) -> Self {
ValueType::Array(Box::new(self.clone()))
pub fn array(&self) -> Self {
ValueType::Array(Box::new(self.clone()), self.span().clone())
}

pub fn retrieve_basic_type(&self) -> &ValueBasicType {
match self {
ValueType::Basic(b) => b,
ValueType::Array(a) => ValueType::retrieve_basic_type(a),
ValueType::NonNullable(a) => ValueType::retrieve_basic_type(a),
ValueType::Basic(b, _) => b,
ValueType::Array(a, _) => ValueType::retrieve_basic_type(a),
ValueType::NonNullable(a, _) => ValueType::retrieve_basic_type(a),
}
}

pub fn replace_basic_type(&mut self, value: ValueType) {
match self {
ValueType::Basic(_) => *self = value,
ValueType::Array(a) => ValueType::replace_basic_type(a, value),
ValueType::NonNullable(a) => ValueType::replace_basic_type(a, value),
pub fn replace_basic_type(&mut self, value: ValueType) -> Result<(), Box<RuleError>> {
if let ValueType::NonNullable(_, _) = value {
if let ValueType::NonNullable(_, _) = self {
return Err(value.span().make_error(
"cannot use a non-nullable type inside another non-nullable type",
));
}
}
match self {
ValueType::Basic(_, _) => *self = value,
ValueType::Array(a, _) => ValueType::replace_basic_type(a, value)?,
ValueType::NonNullable(a, _) => ValueType::replace_basic_type(a, value)?,
};
Ok(())
}
}

pub(crate) fn parse_value_type(pair: Pair<Rule>, file: &str) -> Result<ValueType, Box<RuleError>> {
let span = OwnedSpan::from(pair.as_span(), file);
match pair.as_rule() {
Rule::value_type => parse_value_type(pair.into_inner().next().unwrap(), file),
Rule::value_basic_type => Ok(ValueType::Basic(parse_value_basic_type(pair, file)?)),
Rule::value_non_nullable => Ok(ValueType::NonNullable(Box::new(parse_value_type(
pair.into_inner().next().unwrap(),
file,
)?))),
Rule::value_array => Ok(ValueType::Array(Box::new(parse_value_type(
pair.into_inner().next().unwrap(),
file,
)?))),
Rule::value_basic_type => Ok(ValueType::Basic(parse_value_basic_type(pair, file)?, span)),
Rule::value_non_nullable => Ok(ValueType::NonNullable(
Box::new(parse_value_type(pair.into_inner().next().unwrap(), file)?),
span,
)),
Rule::value_array => Ok(ValueType::Array(
Box::new(parse_value_type(pair.into_inner().next().unwrap(), file)?),
span,
)),
_unknown => Err(unknown_rule_error(
pair,
"value_type, value_array, value_non_nullable or value_basic_type",
Expand Down Expand Up @@ -131,7 +148,9 @@ mod tests {
#[test]
fn test_replaces_value() {
let mut parsed = parse_input("[Int!]!").unwrap();
parsed.replace_basic_type(ValueType::string().array());
parsed
.replace_basic_type(ValueType::string().array())
.unwrap();
assert_eq!(
parsed,
ValueType::string()
Expand Down
37 changes: 3 additions & 34 deletions graphqxl_parser/src/utils/owned_span.rs
Original file line number Diff line number Diff line change
@@ -1,41 +1,10 @@
use pest::Span;
use std::cmp::Ordering;
use std::error::Error;

use std::hash::{Hash, Hasher};

#[derive(Clone, Debug)]
pub struct NoopRuleType;

impl PartialEq<Self> for NoopRuleType {
fn eq(&self, _other: &Self) -> bool {
true
}
}

impl Hash for NoopRuleType {
fn hash<H: Hasher>(&self, _state: &mut H) {}
}

impl Eq for NoopRuleType {}

impl PartialOrd<Self> for NoopRuleType {
fn partial_cmp(&self, _other: &Self) -> Option<Ordering> {
Some(Ordering::Equal)
}
}

impl Ord for NoopRuleType {
fn cmp(&self, _other: &Self) -> Ordering {
Ordering::Equal
}
}

impl Copy for NoopRuleType {}
use crate::parser::RuleError;

#[derive(Clone, Debug)]
pub struct OwnedSpan {
pub err_placeholder: pest::error::Error<NoopRuleType>,
pub err_placeholder: RuleError,
pub file: String,
pub line: usize,
pub col: usize,
Expand Down Expand Up @@ -65,7 +34,7 @@ impl Default for OwnedSpan {
}

impl OwnedSpan {
pub fn make_error(&self, msg: &str) -> Box<dyn Error> {
pub fn make_error(&self, msg: &str) -> Box<RuleError> {
let mut err = self.err_placeholder.clone();
err.variant = pest::error::ErrorVariant::CustomError {
message: format!("{}:{} {}", self.file, self.line, msg),
Expand Down
2 changes: 1 addition & 1 deletion graphqxl_synthesizer/src/synth_identifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pub(crate) struct IdentifierSynth(pub(crate) Identifier);

impl Synth for IdentifierSynth {
fn synth(&self, context: &mut SynthContext) -> bool {
context.write_with_source(&self.0.id, self.0.span.clone());
context.write_with_source(&self.0.id, &self.0.span);
true
}
}
Expand Down
20 changes: 10 additions & 10 deletions graphqxl_synthesizer/src/synth_value_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,37 @@ pub(crate) struct ValueTypeSynth(pub(crate) ValueType);
impl Synth for ValueTypeSynth {
fn synth(&self, context: &mut SynthContext) -> bool {
match &self.0 {
ValueType::Basic(basic) => match &basic {
ValueType::Basic(basic, span) => match &basic {
ValueBasicType::Int => {
context.write("Int");
context.write_with_source("Int", span);
true
}
ValueBasicType::Float => {
context.write("Float");
context.write_with_source("Float", span);
true
}
ValueBasicType::String => {
context.write("String");
context.write_with_source("String", span);
true
}
ValueBasicType::Boolean => {
context.write("Boolean");
context.write_with_source("Boolean", span);
true
}
ValueBasicType::Object(name) => {
IdentifierSynth(name.clone()).synth(context);
true
}
},
ValueType::NonNullable(value_type) => {
ValueType::NonNullable(value_type, span) => {
ValueTypeSynth(*value_type.clone()).synth(context);
context.write("!");
context.write_with_source("!", span);
true
}
ValueType::Array(value_type) => {
context.write("[");
ValueType::Array(value_type, span) => {
context.write_with_source("[", span);
ValueTypeSynth(*value_type.clone()).synth(context);
context.write("]");
context.write_with_source("]", span);
true
}
}
Expand Down
4 changes: 2 additions & 2 deletions graphqxl_synthesizer/src/synths/synth_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl SynthContext {
text
}

pub(crate) fn write_with_source<'a>(&mut self, text: &'a str, span: OwnedSpan) -> &'a str {
pub(crate) fn write_with_source<'a>(&mut self, text: &'a str, span: &OwnedSpan) -> &'a str {
let start = self.offset;
self.write(text);
let stop = self.offset;
Expand All @@ -64,7 +64,7 @@ impl SynthContext {
col: self.col,
start,
stop,
span,
span: span.clone(),
});
text
}
Expand Down
2 changes: 1 addition & 1 deletion graphqxl_transpiler/src/resolve_expandable_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ pub(crate) fn resolve_expandable_ref(
// ...which is stored in the generic map...
if let Some(generic_replacement) = generic_map.get(&object.id) {
// ...then replace it
value_type.replace_basic_type((*generic_replacement).clone());
value_type.replace_basic_type((*generic_replacement).clone())?;
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions graphqxl_transpiler/src/resolve_modified_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ fn nullable(resolved_ref: &ResolvedRef) -> ResolvedRef {
let mut optional_block_def = resolved_ref.clone();
for field in optional_block_def.fields.iter_mut() {
if let Some(value_type) = &mut field.value_type {
if let ValueType::NonNullable(inner) = value_type {
*value_type = inner.deref().deref().deref().clone()
if let ValueType::NonNullable(inner, _) = value_type {
*value_type = inner.deref().deref().clone()
}
}
}
Expand All @@ -43,10 +43,10 @@ fn non_nullable(resolved_ref: &ResolvedRef) -> ResolvedRef {
let mut required_block_def = resolved_ref.clone();
for field in required_block_def.fields.iter_mut() {
if let Some(value_type) = &mut field.value_type {
if let ValueType::NonNullable(_) = value_type {
if let ValueType::NonNullable(_, _) = value_type {
// do nothing here
} else {
*value_type = ValueType::NonNullable(Box::new(value_type.clone()))
*value_type = value_type.non_nullable();
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions src/test/bad-generic-replacement.graphqxl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
type Type<T> {
foo: T!
}

type Other {
...Type<String!>
}
8 changes: 8 additions & 0 deletions src/test/bad-generic-replacement.graphqxl.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Could not transpile graphqxl spec:

--> 6:13
|
6 | ...Type<String!>
| ^-----^
|
= :6 cannot use a non-nullable type inside another non-nullable type

0 comments on commit 934a31e

Please sign in to comment.