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 @@ -26,6 +26,7 @@
use Tempest\Highlight\Languages\Scss\ScssLanguage;
use Tempest\Highlight\Languages\Sql\SqlLanguage;
use Tempest\Highlight\Languages\Terminal\TerminalLanguage;
use Tempest\Highlight\Languages\Terraform\TerraformLanguage;
use Tempest\Highlight\Languages\Text\TextLanguage;
use Tempest\Highlight\Languages\Twig\TwigLanguage;
use Tempest\Highlight\Languages\Xml\XmlLanguage;
Expand Down Expand Up @@ -73,6 +74,7 @@ public function __construct(private readonly Theme $theme = new CssTheme())
->addLanguage(new ScssLanguage())
->addLanguage(new SqlLanguage())
->addLanguage(new TerminalLanguage())
->addLanguage(new TerraformLanguage())
->addLanguage(new XmlLanguage())
->addLanguage(new YamlLanguage())
->addLanguage(new DotEnvLanguage())
Expand Down
32 changes: 32 additions & 0 deletions src/Languages/Terraform/Patterns/TerraformBlockTypePattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Terraform\Patterns;

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

#[PatternTest(input: 'resource "aws_instance" "web" {', output: 'resource')]
#[PatternTest(input: 'variable "instance_type" {', output: 'variable')]
final readonly class TerraformBlockTypePattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
$blockTypes = implode('|', [
'resource', 'data', 'variable', 'output', 'locals',
'module', 'provider', 'terraform', 'moved', 'import', 'check',
]);

return "/^(?<match>{$blockTypes})\b/m";
}

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

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Terraform\Patterns;

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

#[PatternTest(input: 'enabled = true', output: 'true')]
#[PatternTest(input: 'value = null', output: 'null')]
final readonly class TerraformBooleanPattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return '\b(?<match>true|false|null)\b';
}

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

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Terraform\Patterns;

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

#[PatternTest(
input: '<<EOT
hello world
EOT',
output: '<<EOT
hello world
EOT',
)]
#[PatternTest(
input: '<<-POLICY
some content
POLICY',
output: '<<-POLICY
some content
POLICY',
)]
final readonly class TerraformHeredocPattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return '/(?<match><<-?\s*([A-Z_][A-Z0-9_]*)\n.*?\n\s*\2)/s';
}

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

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Terraform\Patterns;

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

#[PatternTest(input: '"Hello ${var.name}"', output: '${var.name}')]
final readonly class TerraformInterpolationPattern implements Pattern
{
use IsPattern;

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

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

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Terraform\Patterns;

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

#[PatternTest(input: 'for_each = var.instances', output: 'for_each')]
#[PatternTest(input: 'count = 3', output: 'count')]
final readonly class TerraformKeywordPattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
$keywords = implode('|', [
'for', 'in', 'if', 'else', 'for_each', 'count',
'depends_on', 'lifecycle', 'dynamic', 'content', 'each', 'self',
]);

return "\b(?<match>(?:{$keywords}))\b";
}

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

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Terraform\Patterns;

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

#[PatternTest(input: 'ami = "abc"', output: '=')]
#[PatternTest(input: 'a == b', output: '==')]
#[PatternTest(input: 'key => value', output: '=>')]
final readonly class TerraformOperatorPattern implements Pattern
{
use IsPattern;

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

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

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Terraform\Patterns;

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

#[PatternTest(input: ' ami = "abc-123"', output: 'ami')]
#[PatternTest(input: ' instance_type = "t2.micro"', output: 'instance_type')]
final readonly class TerraformPropertyPattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
return '/^\s*(?<match>[a-zA-Z_][a-zA-Z0-9_]*)\s*=/m';
}

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

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Terraform\Patterns;

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

#[PatternTest(input: 'type = string', output: 'string')]
#[PatternTest(input: 'type = list(string)', output: 'list')]
final readonly class TerraformTypePattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
$types = implode('|', [
'string', 'number', 'bool', 'list', 'map',
'set', 'object', 'tuple', 'any', 'optional',
]);

return "\b(?<match>(?:{$types}))\b";
}

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

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Terraform\Patterns;

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

#[PatternTest(input: 'ami = var.ami_id', output: 'var.ami_id')]
#[PatternTest(input: 'name = local.name', output: 'local.name')]
#[PatternTest(input: 'id = module.vpc.id', output: 'module.vpc.id')]
final readonly class TerraformVariablePattern implements Pattern
{
use IsPattern;

public function getPattern(): string
{
$prefixes = 'var|local|module|data|each|self';

return "(?<match>(?:{$prefixes})(?:\\.[a-zA-Z_][a-zA-Z0-9_]*)+)";
}

public function getTokenType(): TokenTypeEnum
{
return TokenTypeEnum::VARIABLE;
}
}
88 changes: 88 additions & 0 deletions src/Languages/Terraform/TerraformLanguage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php

declare(strict_types=1);

namespace Tempest\Highlight\Languages\Terraform;

use Override;
use Tempest\Highlight\Languages\Base\BaseLanguage;
use Tempest\Highlight\Languages\Bash\Patterns\BashCommentPattern;
use Tempest\Highlight\Languages\Bash\Patterns\BashNumberPattern;
use Tempest\Highlight\Languages\Css\Patterns\CssCommentPattern;
use Tempest\Highlight\Languages\JavaScript\Patterns\JsSinglelineCommentPattern;
use Tempest\Highlight\Languages\Php\Patterns\DoubleQuoteValuePattern;
use Tempest\Highlight\Languages\Terraform\Patterns\TerraformBlockTypePattern;
use Tempest\Highlight\Languages\Terraform\Patterns\TerraformBooleanPattern;
use Tempest\Highlight\Languages\Terraform\Patterns\TerraformHeredocPattern;
use Tempest\Highlight\Languages\Terraform\Patterns\TerraformInterpolationPattern;
use Tempest\Highlight\Languages\Terraform\Patterns\TerraformKeywordPattern;
use Tempest\Highlight\Languages\Terraform\Patterns\TerraformOperatorPattern;
use Tempest\Highlight\Languages\Terraform\Patterns\TerraformPropertyPattern;
use Tempest\Highlight\Languages\Terraform\Patterns\TerraformTypePattern;
use Tempest\Highlight\Languages\Terraform\Patterns\TerraformVariablePattern;

class TerraformLanguage extends BaseLanguage
{
public function getName(): string
{
return 'terraform';
}

#[Override]
public function getAliases(): array
{
return ['tf', 'hcl', 'terragrunt'];
}

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

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

// COMMENTS
new CssCommentPattern(),
new BashCommentPattern(),
new JsSinglelineCommentPattern(),

// VALUES
new TerraformHeredocPattern(),
new DoubleQuoteValuePattern(),

// BLOCK TYPES
new TerraformBlockTypePattern(),

// KEYWORDS
new TerraformKeywordPattern(),

// TYPES
new TerraformTypePattern(),

// BOOLEANS
new TerraformBooleanPattern(),

// VARIABLES
new TerraformVariablePattern(),

// INTERPOLATION
new TerraformInterpolationPattern(),

// PROPERTIES
new TerraformPropertyPattern(),

// OPERATORS
new TerraformOperatorPattern(),

// NUMBERS
new BashNumberPattern(),
];
}
}
Loading
Loading