Skip to content
This repository has been archived by the owner on Oct 2, 2024. It is now read-only.

Commit

Permalink
Merge pull request #368 from comigor/performance-fix
Browse files Browse the repository at this point in the history
performance fix
  • Loading branch information
vasilich6107 authored Jan 23, 2022
2 parents 83af1dd + b2b566c commit 6412324
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 52 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## 7.3.1-beta

- performance improvements

## 7.3.0-beta

- package update
Expand Down
44 changes: 26 additions & 18 deletions lib/generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,13 @@ LibraryDefinition generateLibrary(
List<FragmentDefinitionNode> fragmentsCommon,
DocumentNode schema,
) {
final typeDefinitionNodeVisitor = TypeDefinitionNodeVisitor();
schema.accept(typeDefinitionNodeVisitor);

final canonicalVisitor = CanonicalVisitor(
context: Context(
schema: schema,
typeDefinitionNodeVisitor: typeDefinitionNodeVisitor,
options: options,
schemaMap: schemaMap,
path: [],
Expand All @@ -54,13 +58,14 @@ LibraryDefinition generateLibrary(

final queryDefinitions = gqlDocs
.map((doc) => generateDefinitions(
schema,
path,
doc,
options,
schemaMap,
fragmentsCommon,
canonicalVisitor,
schema: schema,
typeDefinitionNodeVisitor: typeDefinitionNodeVisitor,
path: path,
document: doc,
options: options,
schemaMap: schemaMap,
fragmentsCommon: fragmentsCommon,
canonicalVisitor: canonicalVisitor,
))
.expand((e) => e)
.toList();
Expand Down Expand Up @@ -118,15 +123,16 @@ Set<FragmentDefinitionNode> _extractFragments(SelectionSetNode? selectionSet,

/// Generate a query definition from a GraphQL schema and a query, given
/// Artemis options and schema mappings.
Iterable<QueryDefinition> generateDefinitions(
DocumentNode schema,
String path,
DocumentNode document,
GeneratorOptions options,
SchemaMap schemaMap,
List<FragmentDefinitionNode> fragmentsCommon,
CanonicalVisitor canonicalVisitor,
) {
Iterable<QueryDefinition> generateDefinitions({
required DocumentNode schema,
required TypeDefinitionNodeVisitor typeDefinitionNodeVisitor,
required String path,
required DocumentNode document,
required GeneratorOptions options,
required SchemaMap schemaMap,
required List<FragmentDefinitionNode> fragmentsCommon,
required CanonicalVisitor canonicalVisitor,
}) {
final documentFragments =
document.definitions.whereType<FragmentDefinitionNode>();

Expand Down Expand Up @@ -200,6 +206,7 @@ Iterable<QueryDefinition> generateDefinitions(

final context = Context(
schema: schema,
typeDefinitionNodeVisitor: typeDefinitionNodeVisitor,
options: options,
schemaMap: schemaMap,
path: [
Expand Down Expand Up @@ -248,7 +255,7 @@ List<String> _extractCustomImports(

schema.accept(typeVisitor);

return typeVisitor.types
return typeVisitor.types.values
.whereType<ScalarTypeDefinitionNode>()
.map((type) => gql.importsOfScalar(options, type.name.value))
.expand((i) => i)
Expand Down Expand Up @@ -298,7 +305,8 @@ ClassProperty createClassProperty({
Make sure your query is correct and your schema is updated.''');
}

final nextType = gql.getTypeByName(context.schema, fieldType);
final nextType =
gql.getTypeByName(context.typeDefinitionNodeVisitor, fieldType);

final aliasedContext = context.withAlias(
nextFieldName: fieldName,
Expand Down
12 changes: 12 additions & 0 deletions lib/generator/ephemeral_data.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:artemis/generator/data/data.dart';
import 'package:artemis/generator/data/nullable.dart';
import 'package:artemis/visitor/type_definition_node_visitor.dart';
import 'package:gql/ast.dart';
import '../schema/options.dart';

Expand Down Expand Up @@ -35,6 +36,7 @@ class Context {
/// Instantiates context for [_GeneratorVisitor] iterations.
Context({
required this.schema,
required this.typeDefinitionNodeVisitor,
required this.options,
required this.schemaMap,
required this.path,
Expand All @@ -55,6 +57,9 @@ class Context {
/// The [DocumentNode] parsed from `build.yaml` configuration.
final DocumentNode schema;

/// The [DocumentNode] parsed from `build.yaml` configuration.
final TypeDefinitionNodeVisitor typeDefinitionNodeVisitor;

/// Other options parsed from `build.yaml` configuration.
final GeneratorOptions options;

Expand Down Expand Up @@ -122,6 +127,7 @@ class Context {
}) =>
Context(
schema: schema,
typeDefinitionNodeVisitor: typeDefinitionNodeVisitor,
options: options,
schemaMap: schemaMap,
path: path,
Expand Down Expand Up @@ -151,6 +157,7 @@ class Context {
assert(alias != null || (nextFieldName != null && nextClassName != null));
return Context(
schema: schema,
typeDefinitionNodeVisitor: typeDefinitionNodeVisitor,
options: options,
schemaMap: schemaMap,
path: path
Expand Down Expand Up @@ -182,6 +189,7 @@ class Context {
}) =>
Context(
schema: schema,
typeDefinitionNodeVisitor: typeDefinitionNodeVisitor,
options: options,
schemaMap: schemaMap,
path: path,
Expand Down Expand Up @@ -212,6 +220,7 @@ class Context {
assert(alias != null || (nextFieldName != null && nextClassName != null));
return Context(
schema: schema,
typeDefinitionNodeVisitor: typeDefinitionNodeVisitor,
options: options,
schemaMap: schemaMap,
path: path
Expand Down Expand Up @@ -241,6 +250,7 @@ class Context {
Context rollbackPath() {
return Context(
schema: schema,
typeDefinitionNodeVisitor: typeDefinitionNodeVisitor,
options: options,
schemaMap: schemaMap,
path: [...path]..removeLast(),
Expand Down Expand Up @@ -268,6 +278,7 @@ class Context {
}) =>
Context(
schema: schema,
typeDefinitionNodeVisitor: typeDefinitionNodeVisitor,
options: options,
schemaMap: schemaMap,
path: [],
Expand Down Expand Up @@ -297,6 +308,7 @@ class Context {
}) =>
Context(
schema: schema,
typeDefinitionNodeVisitor: typeDefinitionNodeVisitor,
options: options,
schemaMap: schemaMap,
path: [],
Expand Down
13 changes: 6 additions & 7 deletions lib/generator/graphql_helpers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,23 @@ import 'package:gql/ast.dart';

import '../generator/data/data.dart';
import '../schema/options.dart';
import 'data/definition.dart';

/// Get a full [TypeDefinitionNode] from a type node.
TypeDefinitionNode getTypeByName(DocumentNode schema, TypeNode typeNode) {
TypeDefinitionNode getTypeByName(
TypeDefinitionNodeVisitor typeDefinitionNodeVisitor,
TypeNode typeNode,
) {
late NamedTypeNode namedNode;

if (typeNode is ListTypeNode) {
return getTypeByName(schema, typeNode.type);
return getTypeByName(typeDefinitionNodeVisitor, typeNode.type);
}

if (typeNode is NamedTypeNode) {
namedNode = typeNode;
}

final typeVisitor = TypeDefinitionNodeVisitor();
schema.accept(typeVisitor);

final type = typeVisitor.getByName(namedNode.name.value);
final type = typeDefinitionNodeVisitor.getByName(namedNode.name.value);

if (type == null) {
throw Exception('''Type ${namedNode.name.value} was not found in schema.
Expand Down
11 changes: 4 additions & 7 deletions lib/transformer/add_typename_transformer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ class AppendTypename extends TransformingVisitor {
selectionSet: SelectionSetNode(
selections: <SelectionNode>[
...node.selectionSet.selections.where((element) =>
(element is! FieldNode) ||
(element is FieldNode && element.name.value != typeName)),
(element is! FieldNode) || (element.name.value != typeName)),
FieldNode(name: NameNode(value: typeName)),
],
),
Expand All @@ -51,8 +50,7 @@ class AppendTypename extends TransformingVisitor {
selectionSet: SelectionSetNode(
selections: <SelectionNode>[
...node.selectionSet.selections.where((element) =>
(element is! FieldNode) ||
(element is FieldNode && element.name.value != typeName)),
(element is! FieldNode) || (element.name.value != typeName)),
FieldNode(name: NameNode(value: typeName)),
],
),
Expand All @@ -73,8 +71,7 @@ class AppendTypename extends TransformingVisitor {
selectionSet: SelectionSetNode(
selections: <SelectionNode>[
...node.selectionSet.selections.where((element) =>
(element is! FieldNode) ||
(element is FieldNode && element.name.value != typeName)),
(element is! FieldNode) || (element.name.value != typeName)),
FieldNode(name: NameNode(value: typeName)),
],
),
Expand All @@ -98,7 +95,7 @@ class AppendTypename extends TransformingVisitor {
selections: <SelectionNode>[
...node.selectionSet?.selections.where((element) =>
(element is! FieldNode) ||
(element is FieldNode && element.name.value != typeName)) ??
(element.name.value != typeName)) ??
[],
FieldNode(name: NameNode(value: typeName)),
],
Expand Down
3 changes: 2 additions & 1 deletion lib/visitor/canonical_visitor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ class CanonicalVisitor extends RecursiveVisitor {
final properties = <ClassProperty>[];

properties.addAll(node.fields.map((i) {
final nextType = gql.getTypeByName(nextContext.schema, i.type);
final nextType =
gql.getTypeByName(nextContext.typeDefinitionNodeVisitor, i.type);
return createClassProperty(
fieldName: ClassPropertyName(name: i.name.value),
context: nextContext.nextTypeWithNoPath(
Expand Down
16 changes: 11 additions & 5 deletions lib/visitor/generator_visitor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ class GeneratorVisitor extends RecursiveVisitor {
void visitInlineFragmentNode(InlineFragmentNode node) {
logFn(context, context.align + 1,
'${context.path}: ... on ${node.typeCondition!.on.name.value}');
final nextType = gql.getTypeByName(context.schema, node.typeCondition!.on);
final nextType = gql.getTypeByName(
context.typeDefinitionNodeVisitor, node.typeCondition!.on);

if (nextType.name.value == context.currentType!.name.value) {
final visitor = GeneratorVisitor(
Expand Down Expand Up @@ -131,7 +132,9 @@ class GeneratorVisitor extends RecursiveVisitor {
context.usedInputObjects.add(ClassName(name: node.name.value));

for (final field in node.fields) {
final type = gql.getTypeByName(context.schema, field.type);
final type =
gql.getTypeByName(context.typeDefinitionNodeVisitor, field.type);

if (type is InputObjectTypeDefinitionNode) {
addUsedInputObjectsAndEnums(type);
} else if (type is EnumTypeDefinitionNode) {
Expand All @@ -142,7 +145,9 @@ class GeneratorVisitor extends RecursiveVisitor {

@override
void visitVariableDefinitionNode(VariableDefinitionNode node) {
final leafType = gql.getTypeByName(context.schema, node.type);
print(visitVariableDefinitionNode);
final leafType =
gql.getTypeByName(context.typeDefinitionNodeVisitor, node.type);

final nextClassName = context
.nextTypeWithNoPath(
Expand Down Expand Up @@ -261,11 +266,12 @@ class GeneratorVisitor extends RecursiveVisitor {
'┌ ${nextContext.path}[${node.name.value}]');
nextContext.fragments.add(node);

final nextType =
gql.getTypeByName(nextContext.schema, node.typeCondition.on);
final nextType = gql.getTypeByName(
nextContext.typeDefinitionNodeVisitor, node.typeCondition.on);

final visitorContext = Context(
schema: context.schema,
typeDefinitionNodeVisitor: context.typeDefinitionNodeVisitor,
options: context.options,
schemaMap: context.schemaMap,
path: [nextContext.alias].whereType<Name>().toList(),
Expand Down
28 changes: 15 additions & 13 deletions lib/visitor/type_definition_node_visitor.dart
Original file line number Diff line number Diff line change
@@ -1,71 +1,73 @@
import 'package:gql/ast.dart';

List<TypeDefinitionNode> _defaultScalars =
List<MapEntry<String, TypeDefinitionNode>> _defaultScalars =
['Boolean', 'Float', 'ID', 'Int', 'String']
.map((e) => ScalarTypeDefinitionNode(
.map((e) => MapEntry(
e,
ScalarTypeDefinitionNode(
name: NameNode(value: e),
))
)))
.toList();

/// Visits all type definition nodes recursively
class TypeDefinitionNodeVisitor extends RecursiveVisitor {
/// Stores all type definition nodes
Iterable<TypeDefinitionNode> types = [..._defaultScalars];
Map<String, TypeDefinitionNode> types = Map.fromEntries(_defaultScalars);

@override
void visitObjectTypeDefinitionNode(
ObjectTypeDefinitionNode node,
) {
types = types.followedBy([node]);
types[node.name.value] = node;
super.visitObjectTypeDefinitionNode(node);
}

@override
void visitScalarTypeDefinitionNode(
ScalarTypeDefinitionNode node,
) {
types = types.followedBy([node]);
types[node.name.value] = node;
super.visitScalarTypeDefinitionNode(node);
}

@override
void visitInterfaceTypeDefinitionNode(
InterfaceTypeDefinitionNode node,
) {
types = types.followedBy([node]);
types[node.name.value] = node;
super.visitInterfaceTypeDefinitionNode(node);
}

@override
void visitUnionTypeDefinitionNode(
UnionTypeDefinitionNode node,
) {
types = types.followedBy([node]);
types[node.name.value] = node;
super.visitUnionTypeDefinitionNode(node);
}

@override
void visitInputObjectTypeDefinitionNode(
InputObjectTypeDefinitionNode node,
) {
types = types.followedBy([node]);
types[node.name.value] = node;
super.visitInputObjectTypeDefinitionNode(node);
}

@override
void visitEnumTypeDefinitionNode(
EnumTypeDefinitionNode node,
) {
types = types.followedBy([node]);
types[node.name.value] = node;
super.visitEnumTypeDefinitionNode(node);
}

/// Gets type definition node by type name
TypeDefinitionNode? getByName(String name) {
final type = types.where((type) => type.name.value == name);
final type = types[name];

if (type.isNotEmpty) {
return type.first;
if (type != null) {
return type;
}

return null;
Expand Down
Loading

0 comments on commit 6412324

Please sign in to comment.