Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions src/Highlighter.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Tempest\Highlight\Languages\DotEnv\DotEnvLanguage;
use Tempest\Highlight\Languages\Ellison\EllisonLanguage;
use Tempest\Highlight\Languages\Gdscript\GdscriptLanguage;
use Tempest\Highlight\Languages\Graphql\GraphqlLanguage;
use Tempest\Highlight\Languages\Html\HtmlLanguage;
use Tempest\Highlight\Languages\Ini\IniLanguage;
use Tempest\Highlight\Languages\JavaScript\JavaScriptLanguage;
Expand Down Expand Up @@ -69,6 +70,7 @@ public function __construct(private readonly Theme $theme = new CssTheme())
->addLanguage(new DockerfileLanguage())
->addLanguage(new EllisonLanguage())
->addLanguage(new GdscriptLanguage())
->addLanguage(new GraphqlLanguage())
->addLanguage(new HtmlLanguage())
->addLanguage(new JavaScriptLanguage())
->addLanguage(new JsonLanguage())
Expand Down
73 changes: 73 additions & 0 deletions src/Languages/Graphql/GraphqlLanguage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Graphql;

use Override;
use Tempest\Highlight\Languages\Base\BaseLanguage;
use Tempest\Highlight\Languages\Graphql\Patterns\GraphqlCommentPattern;
use Tempest\Highlight\Languages\Graphql\Patterns\GraphqlDirectivePattern;
use Tempest\Highlight\Languages\Graphql\Patterns\GraphqlFieldPattern;
use Tempest\Highlight\Languages\Graphql\Patterns\GraphqlKeywordPattern;
use Tempest\Highlight\Languages\Graphql\Patterns\GraphqlLiteralPattern;
use Tempest\Highlight\Languages\Graphql\Patterns\GraphqlNumberPattern;
use Tempest\Highlight\Languages\Graphql\Patterns\GraphqlPunctuationPattern;
use Tempest\Highlight\Languages\Graphql\Patterns\GraphqlStringPattern;
use Tempest\Highlight\Languages\Graphql\Patterns\GraphqlVariablePattern;

class GraphqlLanguage extends BaseLanguage
{
public function getName(): string
{
return 'graphql';
}

public function getAliases(): array
{
return ['gql'];
}

#[Override]
public function getInjections(): array
{
return [
...parent::getInjections(),
];
}

#[Override]
public function getPatterns(): array
{
return [
...parent::getPatterns(),

// Comments
new GraphqlCommentPattern(),

// Strings
new GraphqlStringPattern(),

// Keywords: query, mutation, type, etc.
new GraphqlKeywordPattern(),

// Literals: true, false, null, and Types like String, Int
new GraphqlLiteralPattern(),

// Variables: $id
new GraphqlVariablePattern(),

// Directives: @deprecated
new GraphqlDirectivePattern(),

// Numbers
new GraphqlNumberPattern(),

// Symbols/Fields: name followed by a colon
new GraphqlFieldPattern(),

// Punctuation: !, (, ), :, =, [, ], {, |, } and ...
new GraphqlPunctuationPattern(),
];
}
}
35 changes: 35 additions & 0 deletions src/Languages/Graphql/Patterns/GraphqlCommentPattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Graphql\Patterns;

use Tempest\Highlight\IsPattern;
use Tempest\Highlight\Pattern;
use Tempest\Highlight\PatternTest;
use Tempest\Highlight\Tokens\TokenTypeEnum;

#[PatternTest(input: '# Comment', output: '# Comment')]
#[PatternTest(input: '"""Comment"""', output: '"""Comment"""')]
#[PatternTest(
input: '"""
Comment
"""',
output: '"""
Comment
"""'
)]
final class GraphqlCommentPattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return '(?<match>#.*|"""[\s\S]*?""")';
}

public function getTokenType(): TokenTypeEnum
{
return TokenTypeEnum::COMMENT;
}
}
26 changes: 26 additions & 0 deletions src/Languages/Graphql/Patterns/GraphqlDirectivePattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Graphql\Patterns;

use Tempest\Highlight\IsPattern;
use Tempest\Highlight\Pattern;
use Tempest\Highlight\PatternTest;
use Tempest\Highlight\Tokens\TokenTypeEnum;

#[PatternTest(input: '@deprecated', output: '@deprecated')]
final class GraphqlDirectivePattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return '(?<match>@\w+)';
}

public function getTokenType(): TokenTypeEnum
{
return TokenTypeEnum::ATTRIBUTE;
}
}
26 changes: 26 additions & 0 deletions src/Languages/Graphql/Patterns/GraphqlFieldPattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Graphql\Patterns;

use Tempest\Highlight\IsPattern;
use Tempest\Highlight\Pattern;
use Tempest\Highlight\PatternTest;
use Tempest\Highlight\Tokens\TokenTypeEnum;

#[PatternTest(input: 'test: ID!', output: 'test')]
final class GraphqlFieldPattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return '(?<match>[_A-Za-z][_0-9A-Za-z]*)(?=\s*:)';
}

public function getTokenType(): TokenTypeEnum
{
return TokenTypeEnum::PROPERTY;
}
}
26 changes: 26 additions & 0 deletions src/Languages/Graphql/Patterns/GraphqlKeywordPattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Graphql\Patterns;

use Tempest\Highlight\IsPattern;
use Tempest\Highlight\Pattern;
use Tempest\Highlight\PatternTest;
use Tempest\Highlight\Tokens\TokenTypeEnum;

#[PatternTest(input: 'type Test {}', output: 'type')]
final class GraphqlKeywordPattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return '(?<match>\b(query|mutation|subscription|input|schema|implements|type|interface|union|scalar|fragment|enum|on)\b)';
}

public function getTokenType(): TokenTypeEnum
{
return TokenTypeEnum::KEYWORD;
}
}
26 changes: 26 additions & 0 deletions src/Languages/Graphql/Patterns/GraphqlLiteralPattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Graphql\Patterns;

use Tempest\Highlight\IsPattern;
use Tempest\Highlight\Pattern;
use Tempest\Highlight\PatternTest;
use Tempest\Highlight\Tokens\TokenTypeEnum;

#[PatternTest(input: 'isActive: Boolean!', output: 'Boolean')]
final class GraphqlLiteralPattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return '(?<match>\b(true|false|null|ID|ID!|String|Float|Int|Boolean)\b)';
}

public function getTokenType(): TokenTypeEnum
{
return TokenTypeEnum::TYPE;
}
}
26 changes: 26 additions & 0 deletions src/Languages/Graphql/Patterns/GraphqlNumberPattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Graphql\Patterns;

use Tempest\Highlight\IsPattern;
use Tempest\Highlight\Pattern;
use Tempest\Highlight\PatternTest;
use Tempest\Highlight\Tokens\TokenTypeEnum;

#[PatternTest(input: 'isActive: 12.345', output: '12.345')]
final class GraphqlNumberPattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return '(?<match>\b\d+(\.\d+)?)';
}

public function getTokenType(): TokenTypeEnum
{
return TokenTypeEnum::NUMBER;
}
}
27 changes: 27 additions & 0 deletions src/Languages/Graphql/Patterns/GraphqlPunctuationPattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Graphql\Patterns;

use Tempest\Highlight\IsPattern;
use Tempest\Highlight\Pattern;
use Tempest\Highlight\PatternTest;
use Tempest\Highlight\Tokens\TokenTypeEnum;

#[PatternTest(input: '... on User', output: '...')]
#[PatternTest(input: 'id: ID!', output: [':', '!'])]
final class GraphqlPunctuationPattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return '(?<match>\.{3}|[!():=\[\]{|}]|(?<!\.)\.(?!\.))';
}

public function getTokenType(): TokenTypeEnum
{
return TokenTypeEnum::OPERATOR;
}
}
26 changes: 26 additions & 0 deletions src/Languages/Graphql/Patterns/GraphqlStringPattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Graphql\Patterns;

use Tempest\Highlight\IsPattern;
use Tempest\Highlight\Pattern;
use Tempest\Highlight\PatternTest;
use Tempest\Highlight\Tokens\TokenTypeEnum;

#[PatternTest(input: 'isActive: "Test string"', output: 'Test string')]
final class GraphqlStringPattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return '"(?<match>([^"\\\\]|\\\\.)*)"';
}

public function getTokenType(): TokenTypeEnum
{
return TokenTypeEnum::VALUE;
}
}
26 changes: 26 additions & 0 deletions src/Languages/Graphql/Patterns/GraphqlVariablePattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Graphql\Patterns;

use Tempest\Highlight\IsPattern;
use Tempest\Highlight\Pattern;
use Tempest\Highlight\PatternTest;
use Tempest\Highlight\Tokens\TokenTypeEnum;

#[PatternTest(input: 'test: $test', output: '$test')]
final class GraphqlVariablePattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return '(?<match>\$[\w]+)';
}

public function getTokenType(): TokenTypeEnum
{
return TokenTypeEnum::VARIABLE;
}
}
40 changes: 40 additions & 0 deletions tests/Bench/Fixtures/graphql.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Query users by name
query UsersByName($name: String!) {
users($name: $name) {
id
}
}

# ======
# Schema
# ======

"""
A user
"""
type User {
id: ID!
name: String!
}

type Query {
"""
Query users by name.
"""
users(name: String): [User!]!
"""
Query a user by ID.
"""
user(id: ID!): User
}

type Mutation {
"""
Create a user
"""
createUser(input: CreateUserInput!): User
}

input CreateUserInput {
name: String!
}
1 change: 1 addition & 0 deletions tests/Bench/HighlighterBench.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ final class HighlighterBench
'dotenv' => 'dotenv.txt',
'ellison' => 'ellison.txt',
'gdscript' => 'gdscript.txt',
'graphql' => 'graphql.txt',
'html' => 'html.txt',
'ini' => 'ini.txt',
'javascript' => 'javascript.txt',
Expand Down
Loading
Loading