Skip to content

Commit

Permalink
feat: format with comments (#263)
Browse files Browse the repository at this point in the history
* feat(ast): add comment fields

* feat(formatter): implement getComment

* feat(parser): store comments in parser

* feat(ast): add Comment field for Definition

* feat(ast): implement Dumper interface for CommentGroup

* feat(parser): add comment support for schema parsing

* fix(parser): add comments to schema extensions

* test(formatter): add comments for schema test

* fix(ast,parser): treat multiline comments

* feat(formatter): format schema comments

* test(formatter): update golden

* feat(parser): implement comment parsing

* test(formatter): add query comment tests

* refactor(formatter): remove unused function

* refactor(parser): use dot import

* refactor(ast): remove unused methods

* fix: support comments before and after description

* test(parser): add test case with comments and descriptions

* fix: fix lost of comments after desription

* test(formatter): add description to scalar test case

* fix(parser): remove empty line
  • Loading branch information
Warashi authored Jun 24, 2023
1 parent 5e5180f commit 98e9b07
Show file tree
Hide file tree
Showing 33 changed files with 645 additions and 73 deletions.
31 changes: 31 additions & 0 deletions ast/comment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package ast

import (
"strconv"
"strings"
)

type Comment struct {
Value string
Position *Position
}

func (c *Comment) Text() string {
return strings.TrimSpace(strings.TrimPrefix(c.Value, "#"))
}

type CommentGroup struct {
List []*Comment
}

func (c *CommentGroup) Dump() string {
if len(c.List) == 0 {
return ""
}
var builder strings.Builder
for _, comment := range c.List {
builder.WriteString(comment.Value)
builder.WriteString("\n")
}
return strconv.Quote(builder.String())
}
15 changes: 15 additions & 0 deletions ast/definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ type Definition struct {

Position *Position `dump:"-"`
BuiltIn bool `dump:"-"`

BeforeDescriptionComment *CommentGroup
AfterDescriptionComment *CommentGroup
}

func (d *Definition) IsLeafType() bool {
Expand Down Expand Up @@ -66,6 +69,9 @@ type FieldDefinition struct {
Type *Type
Directives DirectiveList
Position *Position `dump:"-"`

BeforeDescriptionComment *CommentGroup
AfterDescriptionComment *CommentGroup
}

type ArgumentDefinition struct {
Expand All @@ -75,13 +81,19 @@ type ArgumentDefinition struct {
Type *Type
Directives DirectiveList
Position *Position `dump:"-"`

BeforeDescriptionComment *CommentGroup
AfterDescriptionComment *CommentGroup
}

type EnumValueDefinition struct {
Description string
Name string
Directives DirectiveList
Position *Position `dump:"-"`

BeforeDescriptionComment *CommentGroup
AfterDescriptionComment *CommentGroup
}

type DirectiveDefinition struct {
Expand All @@ -91,4 +103,7 @@ type DirectiveDefinition struct {
Locations []DirectiveLocation
IsRepeatable bool
Position *Position `dump:"-"`

BeforeDescriptionComment *CommentGroup
AfterDescriptionComment *CommentGroup
}
8 changes: 8 additions & 0 deletions ast/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ type QueryDocument struct {
Operations OperationList
Fragments FragmentDefinitionList
Position *Position `dump:"-"`
Comment *CommentGroup
}

type SchemaDocument struct {
Expand All @@ -13,6 +14,7 @@ type SchemaDocument struct {
Definitions DefinitionList
Extensions DefinitionList
Position *Position `dump:"-"`
Comment *CommentGroup
}

func (d *SchemaDocument) Merge(other *SchemaDocument) {
Expand All @@ -35,6 +37,8 @@ type Schema struct {
Implements map[string][]*Definition

Description string

Comment *CommentGroup
}

// AddTypes is the helper to add types definition to the schema
Expand Down Expand Up @@ -70,10 +74,14 @@ type SchemaDefinition struct {
Directives DirectiveList
OperationTypes OperationTypeDefinitionList
Position *Position `dump:"-"`

BeforeDescriptionComment *CommentGroup
AfterDescriptionComment *CommentGroup
}

type OperationTypeDefinition struct {
Operation Operation
Type string
Position *Position `dump:"-"`
Comment *CommentGroup
}
3 changes: 3 additions & 0 deletions ast/fragment.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type FragmentSpread struct {
Definition *FragmentDefinition

Position *Position `dump:"-"`
Comment *CommentGroup
}

type InlineFragment struct {
Expand All @@ -20,6 +21,7 @@ type InlineFragment struct {
ObjectDefinition *Definition

Position *Position `dump:"-"`
Comment *CommentGroup
}

type FragmentDefinition struct {
Expand All @@ -35,4 +37,5 @@ type FragmentDefinition struct {
Definition *Definition

Position *Position `dump:"-"`
Comment *CommentGroup
}
2 changes: 2 additions & 0 deletions ast/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type OperationDefinition struct {
Directives DirectiveList
SelectionSet SelectionSet
Position *Position `dump:"-"`
Comment *CommentGroup
}

type VariableDefinition struct {
Expand All @@ -23,6 +24,7 @@ type VariableDefinition struct {
DefaultValue *Value
Directives DirectiveList
Position *Position `dump:"-"`
Comment *CommentGroup

// Requires validation
Definition *Definition
Expand Down
2 changes: 2 additions & 0 deletions ast/selection.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type Field struct {
Directives DirectiveList
SelectionSet SelectionSet
Position *Position `dump:"-"`
Comment *CommentGroup

// Require validation
Definition *FieldDefinition
Expand All @@ -32,6 +33,7 @@ type Argument struct {
Name string
Value *Value
Position *Position `dump:"-"`
Comment *CommentGroup
}

func (s *Field) ArgumentMap(vars map[string]interface{}) map[string]interface{} {
Expand Down
2 changes: 2 additions & 0 deletions ast/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type Value struct {
Children ChildValueList
Kind ValueKind
Position *Position `dump:"-"`
Comment *CommentGroup

// Require validation
Definition *Definition
Expand All @@ -37,6 +38,7 @@ type ChildValue struct {
Name string
Value *Value
Position *Position `dump:"-"`
Comment *CommentGroup
}

func (v *Value) Value(vars map[string]interface{}) (interface{}, error) {
Expand Down
64 changes: 64 additions & 0 deletions formatter/formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ func (f *formatter) FormatSchema(schema *ast.Schema) {
return
}

f.FormatCommentGroup(schema.Comment)

var inSchema bool
startSchema := func() {
if !inSchema {
Expand Down Expand Up @@ -194,6 +196,8 @@ func (f *formatter) FormatSchemaDocument(doc *ast.SchemaDocument) {
return
}

f.FormatCommentGroup(doc.Comment)

f.FormatSchemaDefinitionList(doc.Schema, false)
f.FormatSchemaDefinitionList(doc.SchemaExtension, true)

Expand All @@ -210,6 +214,8 @@ func (f *formatter) FormatQueryDocument(doc *ast.QueryDocument) {
return
}

f.FormatCommentGroup(doc.Comment)

f.FormatOperationList(doc.Operations)
f.FormatFragmentDefinitionList(doc.Fragments)
}
Expand All @@ -234,8 +240,12 @@ func (f *formatter) FormatSchemaDefinitionList(lists ast.SchemaDefinitionList, e
}

func (f *formatter) FormatSchemaDefinition(def *ast.SchemaDefinition) {
f.FormatCommentGroup(def.BeforeDescriptionComment)

f.WriteDescription(def.Description)

f.FormatCommentGroup(def.AfterDescriptionComment)

f.FormatDirectiveList(def.Directives)

f.FormatOperationTypeDefinitionList(def.OperationTypes)
Expand All @@ -248,6 +258,7 @@ func (f *formatter) FormatOperationTypeDefinitionList(lists ast.OperationTypeDef
}

func (f *formatter) FormatOperationTypeDefinition(def *ast.OperationTypeDefinition) {
f.FormatCommentGroup(def.Comment)
f.WriteWord(string(def.Operation)).NoPadding().WriteString(":").NeedPadding()
f.WriteWord(def.Type)
f.WriteNewline()
Expand All @@ -274,8 +285,12 @@ func (f *formatter) FormatFieldDefinition(field *ast.FieldDefinition) {
return
}

f.FormatCommentGroup(field.BeforeDescriptionComment)

f.WriteDescription(field.Description)

f.FormatCommentGroup(field.AfterDescriptionComment)

f.WriteWord(field.Name).NoPadding()
f.FormatArgumentDefinitionList(field.Arguments)
f.NoPadding().WriteString(":").NeedPadding()
Expand Down Expand Up @@ -310,11 +325,15 @@ func (f *formatter) FormatArgumentDefinitionList(lists ast.ArgumentDefinitionLis
}

func (f *formatter) FormatArgumentDefinition(def *ast.ArgumentDefinition) {
f.FormatCommentGroup(def.BeforeDescriptionComment)

if def.Description != "" {
f.WriteNewline().IncrementIndent()
f.WriteDescription(def.Description)
}

f.FormatCommentGroup(def.AfterDescriptionComment)

f.WriteWord(def.Name).NoPadding().WriteString(":").NeedPadding()
f.FormatType(def.Type)

Expand Down Expand Up @@ -352,7 +371,12 @@ func (f *formatter) FormatDirectiveDefinition(def *ast.DirectiveDefinition) {
}
}

f.FormatCommentGroup(def.BeforeDescriptionComment)

f.WriteDescription(def.Description)

f.FormatCommentGroup(def.AfterDescriptionComment)

f.WriteWord("directive").WriteString("@").WriteWord(def.Name)

if len(def.Arguments) != 0 {
Expand Down Expand Up @@ -394,8 +418,12 @@ func (f *formatter) FormatDefinition(def *ast.Definition, extend bool) {
return
}

f.FormatCommentGroup(def.BeforeDescriptionComment)

f.WriteDescription(def.Description)

f.FormatCommentGroup(def.AfterDescriptionComment)

if extend {
f.WriteWord("extend")
}
Expand Down Expand Up @@ -454,8 +482,12 @@ func (f *formatter) FormatEnumValueList(lists ast.EnumValueList) {
}

func (f *formatter) FormatEnumValueDefinition(def *ast.EnumValueDefinition) {
f.FormatCommentGroup(def.BeforeDescriptionComment)

f.WriteDescription(def.Description)

f.FormatCommentGroup(def.AfterDescriptionComment)

f.WriteWord(def.Name)
f.FormatDirectiveList(def.Directives)

Expand All @@ -469,6 +501,8 @@ func (f *formatter) FormatOperationList(lists ast.OperationList) {
}

func (f *formatter) FormatOperationDefinition(def *ast.OperationDefinition) {
f.FormatCommentGroup(def.Comment)

f.WriteWord(string(def.Operation))
if def.Name != "" {
f.WriteWord(def.Name)
Expand Down Expand Up @@ -513,6 +547,8 @@ func (f *formatter) FormatArgumentList(lists ast.ArgumentList) {
}

func (f *formatter) FormatArgument(arg *ast.Argument) {
f.FormatCommentGroup(arg.Comment)

f.WriteWord(arg.Name).NoPadding().WriteString(":").NeedPadding()
f.WriteString(arg.Value.String())
}
Expand All @@ -524,6 +560,8 @@ func (f *formatter) FormatFragmentDefinitionList(lists ast.FragmentDefinitionLis
}

func (f *formatter) FormatFragmentDefinition(def *ast.FragmentDefinition) {
f.FormatCommentGroup(def.Comment)

f.WriteWord("fragment").WriteWord(def.Name)
f.FormatVariableDefinitionList(def.VariableDefinition)
f.WriteWord("on").WriteWord(def.TypeCondition)
Expand Down Expand Up @@ -552,6 +590,8 @@ func (f *formatter) FormatVariableDefinitionList(lists ast.VariableDefinitionLis
}

func (f *formatter) FormatVariableDefinition(def *ast.VariableDefinition) {
f.FormatCommentGroup(def.Comment)

f.WriteString("$").WriteWord(def.Variable).NoPadding().WriteString(":").NeedPadding()
f.FormatType(def.Type)

Expand Down Expand Up @@ -599,6 +639,8 @@ func (f *formatter) FormatSelection(selection ast.Selection) {
}

func (f *formatter) FormatField(field *ast.Field) {
f.FormatCommentGroup(field.Comment)

if field.Alias != "" && field.Alias != field.Name {
f.WriteWord(field.Alias).NoPadding().WriteString(":").NeedPadding()
}
Expand All @@ -616,12 +658,16 @@ func (f *formatter) FormatField(field *ast.Field) {
}

func (f *formatter) FormatFragmentSpread(spread *ast.FragmentSpread) {
f.FormatCommentGroup(spread.Comment)

f.WriteWord("...").WriteWord(spread.Name)

f.FormatDirectiveList(spread.Directives)
}

func (f *formatter) FormatInlineFragment(inline *ast.InlineFragment) {
f.FormatCommentGroup(inline.Comment)

f.WriteWord("...")
if inline.TypeCondition != "" {
f.WriteWord("on").WriteWord(inline.TypeCondition)
Expand All @@ -637,5 +683,23 @@ func (f *formatter) FormatType(t *ast.Type) {
}

func (f *formatter) FormatValue(value *ast.Value) {
f.FormatCommentGroup(value.Comment)

f.WriteString(value.String())
}

func (f *formatter) FormatCommentGroup(group *ast.CommentGroup) {
if group == nil {
return
}
for _, comment := range group.List {
f.FormatComment(comment)
}
}

func (f *formatter) FormatComment(comment *ast.Comment) {
if comment == nil {
return
}
f.WriteString("# ").WriteString(comment.Text()).WriteNewline()
}
Loading

0 comments on commit 98e9b07

Please sign in to comment.