Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

process client pointer #254

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
5acc0d1
process client pointer
PatrykWalach Nov 6, 2024
f8e539f
fix parse
PatrykWalach Nov 6, 2024
dd5582a
update `encountered_fields`
PatrykWalach Nov 6, 2024
753cd98
refactor `validate_isograph_selection_set_directives`
PatrykWalach Nov 6, 2024
050b5aa
use `ClientType`
PatrykWalach Nov 7, 2024
8a113c8
change error message
PatrykWalach Nov 7, 2024
941d72a
Merge branch 'main' into process-client-pointer
PatrykWalach Nov 10, 2024
fdc36c3
replace `None` with `todo!()`
PatrykWalach Nov 12, 2024
61e70e8
map Span with `and_then`
PatrykWalach Nov 12, 2024
e514dff
rename args to `scalar_field_selection` and `object_pointer_selection`
PatrykWalach Nov 12, 2024
a34cb58
refactor span with `and_then`
PatrykWalach Nov 12, 2024
aec18e5
fix typo `encountered` error message
PatrykWalach Nov 12, 2024
61f02e8
remove `unwraps`
PatrykWalach Nov 12, 2024
4f6bc48
update comments
PatrykWalach Nov 12, 2024
13047c5
completely remove `unwraps`
PatrykWalach Nov 12, 2024
81dafea
use `GraphQLTypeAnnotation` for `to_type`
PatrykWalach Nov 13, 2024
8d9614a
Merge branch 'main' into process-client-pointer
PatrykWalach Nov 13, 2024
58b1016
remove outdated comment
PatrykWalach Nov 14, 2024
19919fe
use `.object()` and `.object_mut()`
PatrykWalach Nov 14, 2024
8b0cd4d
use `TypeAnnotation`
PatrykWalach Nov 14, 2024
71048d3
Merge branch 'main' into process-client-pointer
PatrykWalach Nov 14, 2024
df28a5b
Merge branch 'main' into process-client-pointer
PatrykWalach Jan 6, 2025
48899cd
fix merge
PatrykWalach Jan 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions crates/common_lang_types/src/string_key_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ string_key_newtype!(DirectiveArgumentName);
// (client-defined linked fields do not exist, but will.)
string_key_newtype!(SelectableFieldName);

string_key_newtype!(ClientPointerFieldName);
string_key_conversion!(from: ClientPointerFieldName, to: SelectableFieldName);

string_key_newtype!(InputValueName);
string_key_conversion!(from: InputValueName, to: VariableName);
string_key_conversion!(from: InputValueName, to: FieldArgumentName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use common_lang_types::SelectableFieldName;
use graphql_lang_types::{GraphQLNonNullTypeAnnotation, GraphQLTypeAnnotation};

use isograph_lang_types::{
ClientFieldId, SelectableServerFieldId, SelectionType, ServerFieldId, TypeAnnotation,
UnionVariant,
ClientFieldId, ClientPointerId, SelectableServerFieldId, SelectionType, ServerFieldId,
TypeAnnotation, UnionVariant,
};
use isograph_schema::{ClientType, FieldType, ValidatedSchema};

Expand Down Expand Up @@ -75,7 +75,7 @@ fn format_server_field_type(
fn format_field_definition(
schema: &ValidatedSchema,
name: &SelectableFieldName,
type_: &FieldType<ServerFieldId, ClientType<ClientFieldId>>,
type_: &FieldType<ServerFieldId, ClientType<ClientFieldId, ClientPointerId>>,
indentation_level: u8,
) -> String {
match type_ {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ pub fn get_artifact_path_and_content(
}

for user_written_client_field in schema.client_fields.iter().flat_map(|field| match field {
ClientType::ClientPointer(_) => todo!(),
ClientType::ClientField(field) => match field.variant {
ClientFieldVariant::UserWritten(_) => Some(field),
ClientFieldVariant::ImperativelyLoadedField(_) => None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ fn user_written_fields(
.client_fields
.iter()
.filter_map(|client_field| match client_field {
ClientType::ClientPointer(_) => todo!(),
ClientType::ClientField(client_field) => match client_field.variant {
ClientFieldVariant::UserWritten(info) => {
Some((client_field, info.user_written_component_variant))
Expand Down
17 changes: 16 additions & 1 deletion crates/graphql_lang_types/src/graphql_type_annotation.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{fmt, ops::Deref};

use common_lang_types::WithSpan;
use common_lang_types::{Span, WithSpan};

#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum GraphQLTypeAnnotation<TValue> {
Expand All @@ -18,6 +18,14 @@ impl<TValue> GraphQLTypeAnnotation<TValue> {
}
}

pub fn span(&self) -> &Span {
match self {
GraphQLTypeAnnotation::Named(named) => &named.0.span,
GraphQLTypeAnnotation::List(list) => list.0.span(),
GraphQLTypeAnnotation::NonNull(non_null) => non_null.span(),
}
}

pub fn inner_mut(&mut self) -> &mut TValue {
match self {
GraphQLTypeAnnotation::Named(named) => &mut named.0.item,
Expand Down Expand Up @@ -103,6 +111,13 @@ impl<TValue> GraphQLNonNullTypeAnnotation<TValue> {
}
}

pub fn span(&self) -> &Span {
match self {
GraphQLNonNullTypeAnnotation::Named(named) => &named.0.span,
GraphQLNonNullTypeAnnotation::List(list) => list.0.span(),
}
}

pub fn inner_mut(&mut self) -> &mut TValue {
match self {
GraphQLNonNullTypeAnnotation::Named(named) => &mut named.0.item,
Expand Down
98 changes: 72 additions & 26 deletions crates/isograph_compiler/src/field_directives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ use intern::string_key::Intern;
use isograph_lang_types::{
from_isograph_field_directive, ClientFieldDeclaration,
ClientFieldDeclarationWithUnvalidatedDirectives, ClientFieldDeclarationWithValidatedDirectives,
IsographFieldDirective, IsographSelectionVariant, LinkedFieldSelection, ScalarFieldSelection,
ServerFieldSelection,
ClientPointerDeclaration, ClientPointerDeclarationWithUnvalidatedDirectives,
ClientPointerDeclarationWithValidatedDirectives, IsographFieldDirective,
IsographSelectionVariant, LinkedFieldSelection, ScalarFieldSelection, ServerFieldSelection,
UnvalidatedSelection,
};
use isograph_schema::ProcessClientFieldDeclarationError;
use lazy_static::lazy_static;
Expand All @@ -20,19 +22,42 @@ pub fn validate_isograph_field_directives(
WithSpan<ClientFieldDeclarationWithValidatedDirectives>,
Vec<WithLocation<ProcessClientFieldDeclarationError>>,
> {
let ClientFieldDeclaration {
const_export_name,
parent_type,
client_field_name,
description,
selection_set,
directives,
variable_definitions,
definition_path,
dot,
field_keyword,
} = client_field.item;
let new_selecton_set = and_then_selection_set_and_collect_errors(
client_field.and_then(|client_field| {
let ClientFieldDeclaration {
const_export_name,
parent_type,
client_field_name,
description,
selection_set,
directives,
variable_definitions,
definition_path,
dot,
field_keyword,
} = client_field;

Ok(ClientFieldDeclarationWithValidatedDirectives {
const_export_name,
parent_type,
client_field_name,
description,
selection_set: validate_isograph_selection_set_directives(selection_set)?,
directives,
variable_definitions,
definition_path,
dot,
field_keyword,
})
})
}

pub fn validate_isograph_selection_set_directives(
selection_set: Vec<WithSpan<ServerFieldSelection<(), ()>>>,
) -> Result<
Vec<WithSpan<UnvalidatedSelection>>,
Vec<WithLocation<ProcessClientFieldDeclarationError>>,
> {
and_then_selection_set_and_collect_errors(
selection_set,
&|scalar_field_selection| {
if let Some(directive) =
Expand All @@ -55,23 +80,44 @@ pub fn validate_isograph_field_directives(
Ok(IsographSelectionVariant::Regular)
}
},
&|_linked_field_selection| Ok(IsographSelectionVariant::Regular),
)?;
Ok(WithSpan::new(
ClientFieldDeclarationWithValidatedDirectives {
&|_object_pointer_selection| Ok(IsographSelectionVariant::Regular),
)
}

#[allow(clippy::complexity)]
pub fn validate_isograph_pointer_directives(
client_pointer: WithSpan<ClientPointerDeclarationWithUnvalidatedDirectives>,
) -> Result<
WithSpan<ClientPointerDeclarationWithValidatedDirectives>,
Vec<WithLocation<ProcessClientFieldDeclarationError>>,
> {
client_pointer.and_then(|client_pointer| {
let ClientPointerDeclaration {
const_export_name,
parent_type,
client_field_name,
client_pointer_name,
description,
selection_set: new_selecton_set,
directives,
selection_set,
variable_definitions,
definition_path,
dot,
field_keyword,
},
client_field.span,
))
pointer_keyword,
to_type,
} = client_pointer;

Ok(ClientPointerDeclarationWithValidatedDirectives {
const_export_name,
parent_type,
client_pointer_name,
description,
selection_set: validate_isograph_selection_set_directives(selection_set)?,
variable_definitions,
definition_path,
dot,
pointer_keyword,
to_type,
})
})
}

fn and_then_selection_set_and_collect_errors<
Expand Down
20 changes: 18 additions & 2 deletions crates/isograph_compiler/src/isograph_literals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ use lazy_static::lazy_static;
use regex::Regex;

use crate::{
batch_compile::BatchCompileError, field_directives::validate_isograph_field_directives,
batch_compile::BatchCompileError,
field_directives::{validate_isograph_field_directives, validate_isograph_pointer_directives},
source_files::ContainsIso,
};

Expand Down Expand Up @@ -162,7 +163,22 @@ pub(crate) fn process_iso_literals(
Err(e) => errors.extend(e),
};
}
IsoLiteralExtractionResult::ClientPointerDeclaration(_) => todo!(),
IsoLiteralExtractionResult::ClientPointerDeclaration(
client_pointer_declaration,
) => {
match validate_isograph_pointer_directives(client_pointer_declaration) {
Ok(validated_client_pointer_declaration) => {
if let Err(e) = schema.process_client_pointer_declaration(
validated_client_pointer_declaration,
text_source,
) {
errors.push(e);
}
}
Err(e) => errors.extend(e),
};
}

IsoLiteralExtractionResult::EntrypointDeclaration(entrypoint_declaration) => schema
.entrypoints
.push((text_source, entrypoint_declaration)),
Expand Down
5 changes: 3 additions & 2 deletions crates/isograph_compiler/src/refetch_fields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use isograph_schema::{
generate_refetch_field_strategy, id_arguments, id_selection, id_top_level_arguments,
ClientField, ClientFieldVariant, ClientType, FieldType, ImperativelyLoadedFieldVariant,
ObjectTypeAndFieldName, RefetchStrategy, RequiresRefinement, SchemaObject,
UnvalidatedClientField, UnvalidatedSchema, NODE_FIELD_NAME, REFETCH_FIELD_NAME,
UnvalidatedClientField, UnvalidatedClientPointer, UnvalidatedSchema, NODE_FIELD_NAME,
REFETCH_FIELD_NAME,
};

use crate::batch_compile::BatchCompileError;
Expand All @@ -32,7 +33,7 @@ pub fn add_refetch_fields_to_objects(

fn add_refetch_field_to_object(
object: &mut SchemaObject,
client_fields: &mut Vec<ClientType<UnvalidatedClientField>>,
client_fields: &mut Vec<ClientType<UnvalidatedClientField, UnvalidatedClientPointer>>,
query_id: ServerObjectId,
) -> Option<Result<(), BatchCompileError>> {
match object
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use common_lang_types::{FieldNameOrAlias, ScalarFieldName, WithLocation, WithSpan};
use common_lang_types::{FieldNameOrAlias, SelectableFieldName, WithLocation, WithSpan};
use thiserror::Error;

use crate::IsographLangTokenKind;
Expand Down Expand Up @@ -27,11 +27,12 @@ pub enum IsographLiteralParseError {
ExpectedFieldOrPointerOrEntrypoint,

#[error(
"This isograph field literal must be exported as a named export, for example \
"This isograph {literal_type} literal must be exported as a named export, for example \
as `export const {suggested_const_export_name}`"
)]
ExpectedLiteralToBeExported {
suggested_const_export_name: ScalarFieldName,
literal_type: String,
suggested_const_export_name: SelectableFieldName,
},

#[error("Expected a valid value, like $foo, 42, \"bar\", true or false")]
Expand Down
26 changes: 15 additions & 11 deletions crates/isograph_lang_parser/src/parse_iso_literal.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::{collections::HashSet, ops::ControlFlow};

use common_lang_types::{
FilePath, Location, ScalarFieldName, Span, TextSource, UnvalidatedTypeName, WithLocation,
WithSpan,
ClientPointerFieldName, FilePath, Location, ScalarFieldName, Span, TextSource,
UnvalidatedTypeName, WithLocation, WithSpan,
};
use graphql_lang_types::{
GraphQLListTypeAnnotation, GraphQLNamedTypeAnnotation, GraphQLNonNullTypeAnnotation,
Expand All @@ -11,9 +11,10 @@ use graphql_lang_types::{
use intern::string_key::{Intern, StringKey};
use isograph_lang_types::{
ClientFieldDeclaration, ClientFieldDeclarationWithUnvalidatedDirectives,
ClientPointerDeclaration, ConstantValue, EntrypointTypeAndField, IsographFieldDirective,
LinkedFieldSelection, NonConstantValue, ScalarFieldSelection, SelectionFieldArgument,
ServerFieldSelection, UnvalidatedSelectionWithUnvalidatedDirectives, VariableDefinition,
ClientPointerDeclaration, ClientPointerDeclarationWithUnvalidatedDirectives, ConstantValue,
EntrypointTypeAndField, IsographFieldDirective, LinkedFieldSelection, NonConstantValue,
ScalarFieldSelection, SelectionFieldArgument, ServerFieldSelection,
UnvalidatedSelectionWithUnvalidatedDirectives, VariableDefinition,
};

use crate::{
Expand All @@ -23,7 +24,7 @@ use crate::{

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum IsoLiteralExtractionResult {
ClientPointerDeclaration(WithSpan<ClientPointerDeclaration<(), ()>>),
ClientPointerDeclaration(WithSpan<ClientPointerDeclarationWithUnvalidatedDirectives>),
ClientFieldDeclaration(WithSpan<ClientFieldDeclarationWithUnvalidatedDirectives>),
EntrypointDeclaration(WithSpan<EntrypointTypeAndField>),
}
Expand Down Expand Up @@ -161,7 +162,8 @@ fn parse_client_field_declaration_inner(
let const_export_name = const_export_name.ok_or_else(|| {
WithSpan::new(
IsographLiteralParseError::ExpectedLiteralToBeExported {
suggested_const_export_name: client_field_name.item,
literal_type: "field".to_string(),
suggested_const_export_name: client_field_name.item.into(),
},
Span::todo_generated(),
)
Expand Down Expand Up @@ -194,7 +196,7 @@ fn parse_iso_client_pointer_declaration(
const_export_name: Option<&str>,
text_source: TextSource,
field_keyword_span: Span,
) -> ParseResultWithLocation<WithSpan<ClientPointerDeclaration<(), ()>>> {
) -> ParseResultWithLocation<WithSpan<ClientPointerDeclarationWithUnvalidatedDirectives>> {
let client_pointer_declaration = parse_client_pointer_declaration_inner(
tokens,
definition_file_path,
Expand All @@ -220,7 +222,7 @@ fn parse_client_pointer_declaration_inner(
const_export_name: Option<&str>,
text_source: TextSource,
pointer_keyword_span: Span,
) -> ParseResultWithSpan<WithSpan<ClientPointerDeclaration<(), ()>>> {
) -> ParseResultWithSpan<WithSpan<ClientPointerDeclarationWithUnvalidatedDirectives>> {
tokens.with_span(|tokens| {
let parent_type = tokens
.parse_string_key_type(IsographLangTokenKind::Identifier)
Expand All @@ -230,7 +232,7 @@ fn parse_client_pointer_declaration_inner(
.parse_token_of_kind(IsographLangTokenKind::Period)
.map_err(|with_span| with_span.map(IsographLiteralParseError::from))?;

let client_pointer_name: WithSpan<ScalarFieldName> = tokens
let client_pointer_name: WithSpan<ClientPointerFieldName> = tokens
.parse_string_key_type(IsographLangTokenKind::Identifier)
.map_err(|with_span| with_span.map(IsographLiteralParseError::from))?;

Expand All @@ -243,7 +245,8 @@ fn parse_client_pointer_declaration_inner(
let const_export_name = const_export_name.ok_or_else(|| {
WithSpan::new(
IsographLiteralParseError::ExpectedLiteralToBeExported {
suggested_const_export_name: client_pointer_name.item,
literal_type: "pointer".to_string(),
suggested_const_export_name: client_pointer_name.item.into(),
},
Span::todo_generated(),
)
Expand All @@ -252,6 +255,7 @@ fn parse_client_pointer_declaration_inner(
Ok(ClientPointerDeclaration {
parent_type,
client_pointer_name,
to_type: GraphQLTypeAnnotation::Named(GraphQLNamedTypeAnnotation(parent_type)),
description,
selection_set,
definition_path: definition_file_path,
Expand Down
Loading
Loading