Skip to content

Commit

Permalink
Embedded struct fields, field tag fix, code improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
tuqqu committed Aug 7, 2023
1 parent 0a6a7e3 commit e061fdb
Show file tree
Hide file tree
Showing 73 changed files with 1,441 additions and 219 deletions.
11 changes: 9 additions & 2 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,19 @@

const CONFIG = new PhpCsFixer\Config();
const RULES = [
'@PSR12' => true,
'@PER' => true,
'strict_param' => true,
'braces' => false,
'ternary_operator_spaces' => false,
'no_break_comment' => false,
'array_syntax' => ['syntax' => 'short'],
'no_unused_imports' => true,
'single_line_empty_body' => true,
'statement_indentation' => false,
'global_namespace_import' => [
'import_classes' => true,
'import_constants' => true,
'import_functions' => true,
],
];

CONFIG->setRules(RULES);
Expand Down
13 changes: 6 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,14 @@ $parser = new Parser($program);
$ast = $parser->parse();
$errs = $parser->getErrors();
```
Supported language level: Go 1.18 (generics).

Parser is able to recover itself if a parse error occurs, in this case it will continue parsing at the closest node it is able to recognise.
The parser is capable of recovering itself if a parse error occurs. In such cases, it will continue parsing at the closest node it can recognise.

The resulting AST will be as full as possible, and you have to check `getErrors()` to see errors.
The resulting Abstract Syntax Tree (AST) will be as complete as possible. You need to check `getErrors()` to identify any errors.

## Single declaration parsing

Parser can also handle a single declaration only (e.g. a single function), instead of a fully defined Go program:
The parser can also handle a single declaration (e.g., a single function) instead of an entire Go program:
```php
use GoParser\{Parser, ParseMode};

Expand All @@ -51,11 +50,11 @@ $decl = $parser->parseSingleDecl();

## Abstract Syntax Tree

Parsing results in an Abstract Syntax Tree result. See `src/Ast`.
Parsing results in an Abstract Syntax Tree. Refer to `src/Ast` for details.

For the most part the AST nodes structure follows closely the official Golang [specification][1].
For the most part, the structure of AST nodes closely follows the official Golang [specification][1].

Some Nodes may also have a bit different name (e.g. `ExpressionList` vs `ExprList`), but mostly the names are either the same or easily recognisable.
Some nodes may have slightly different names (e.g., `ExpressionList` instead of `ExprList`), but in most cases, the names are the same or easily recognisable.

## CLI
Package comes with a CLI command:
Expand Down
2 changes: 1 addition & 1 deletion bin/go-parser
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ function parse_argv(array $argv): array
$mode = ParseMode::SingleDecl;
break;
case '--node-dumper':
// default for now
// default
break;
case '-d':
case '--var-dump':
Expand Down
4 changes: 1 addition & 3 deletions src/Ast/AstNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@

namespace GoParser\Ast;

interface AstNode
{
}
interface AstNode {}
4 changes: 1 addition & 3 deletions src/Ast/CaseClause.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@

namespace GoParser\Ast;

interface CaseClause extends AstNode
{
}
interface CaseClause extends AstNode {}
4 changes: 1 addition & 3 deletions src/Ast/CaseLabel.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@

namespace GoParser\Ast;

interface CaseLabel extends AstNode
{
}
interface CaseLabel extends AstNode {}
18 changes: 18 additions & 0 deletions src/Ast/EmbeddedFieldDecl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace GoParser\Ast;

use GoParser\Ast\Expr\PointerType;
use GoParser\Ast\Expr\RawStringLit;
use GoParser\Ast\Expr\StringLit;
use GoParser\Ast\Expr\TypeName;

final class EmbeddedFieldDecl implements AstNode
{
public function __construct(
public readonly TypeName|PointerType $type,
public readonly StringLit|RawStringLit|null $tag,
) {}
}
4 changes: 1 addition & 3 deletions src/Ast/Expr/Expr.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,4 @@

use GoParser\Ast\AstNode;

interface Expr extends AstNode
{
}
interface Expr extends AstNode {}
4 changes: 1 addition & 3 deletions src/Ast/Expr/Literal.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@

namespace GoParser\Ast\Expr;

interface Literal extends Operand
{
}
interface Literal extends Operand {}
4 changes: 1 addition & 3 deletions src/Ast/Expr/Operand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@

namespace GoParser\Ast\Expr;

interface Operand extends PrimaryExpr
{
}
interface Operand extends PrimaryExpr {}
4 changes: 1 addition & 3 deletions src/Ast/Expr/PrimaryExpr.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@

namespace GoParser\Ast\Expr;

interface PrimaryExpr extends Expr
{
}
interface PrimaryExpr extends Expr {}
4 changes: 1 addition & 3 deletions src/Ast/Expr/SliceExpr.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@

namespace GoParser\Ast\Expr;

interface SliceExpr extends PrimaryExpr
{
}
interface SliceExpr extends PrimaryExpr {}
3 changes: 2 additions & 1 deletion src/Ast/Expr/StructType.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@

namespace GoParser\Ast\Expr;

use GoParser\Ast\EmbeddedFieldDecl;
use GoParser\Ast\FieldDecl;
use GoParser\Ast\Keyword;
use GoParser\Ast\Punctuation;

final class StructType implements TypeLit
{
/**
* @param FieldDecl[] $fieldDecls
* @param list<FieldDecl|EmbeddedFieldDecl> $fieldDecls
*/
public function __construct(
public readonly Keyword $keyword,
Expand Down
4 changes: 1 addition & 3 deletions src/Ast/Expr/Type.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@

namespace GoParser\Ast\Expr;

interface Type extends TypeTerm, Expr
{
}
interface Type extends TypeTerm, Expr {}
4 changes: 1 addition & 3 deletions src/Ast/Expr/TypeLit.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@

namespace GoParser\Ast\Expr;

interface TypeLit extends Type
{
}
interface TypeLit extends Type {}
4 changes: 1 addition & 3 deletions src/Ast/Expr/TypeName.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@

namespace GoParser\Ast\Expr;

interface TypeName extends Type
{
}
interface TypeName extends Type {}
4 changes: 1 addition & 3 deletions src/Ast/Expr/TypeTerm.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@

namespace GoParser\Ast\Expr;

interface TypeTerm
{
}
interface TypeTerm {}
1 change: 0 additions & 1 deletion src/Ast/Expr/UnderlyingType.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace GoParser\Ast\Expr;

use GoParser\Ast\Operator;
use GoParser\Lexer\Position;

final class UnderlyingType implements TypeTerm, Expr
{
Expand Down
4 changes: 2 additions & 2 deletions src/Ast/FieldDecl.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
final class FieldDecl implements AstNode
{
public function __construct(
public readonly ?IdentList $identList,
public readonly ?Type $type,
public readonly IdentList $identList,
public readonly Type $type,
public readonly StringLit|RawStringLit|null $tag,
) {}
}
8 changes: 5 additions & 3 deletions src/Ast/IdentList.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@

namespace GoParser\Ast;

use GoParser\Ast\Expr\Type;
use GoParser\Exception\InvalidArgument;
use GoParser\Ast\Expr\Expr;
use GoParser\Ast\Expr\Ident;
use GoParser\Ast\Expr\Type;
use GoParser\Ast\Expr\SingleTypeName;

use function array_map;

final class IdentList implements AstNode
{
/**
Expand All @@ -21,7 +23,7 @@ public function __construct(

public static function fromExprList(ExprList $list): self
{
return new self(\array_map(
return new self(array_map(
static fn (Expr $expr): Ident => $expr instanceof Ident
? $expr
: throw new InvalidArgument('Cannot create IdentList from an arbitrary expression list'),
Expand All @@ -31,7 +33,7 @@ public static function fromExprList(ExprList $list): self

public static function fromTypeList(TypeList $list): self
{
return new self(\array_map(
return new self(array_map(
static fn (Type $type): Ident => $type instanceof SingleTypeName
? $type->name
: throw new InvalidArgument('Cannot create IdentList from an arbitrary type list'),
Expand Down
4 changes: 3 additions & 1 deletion src/Ast/SpecType.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

namespace GoParser\Ast;

enum SpecType implements \JsonSerializable
use JsonSerializable;

enum SpecType implements JsonSerializable
{
case Import;
case Var;
Expand Down
4 changes: 3 additions & 1 deletion src/Ast/Stmt/ConstDecl.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@
use GoParser\Ast\Keyword;
use GoParser\Ast\SpecType;

use function sprintf;

final class ConstDecl implements Decl
{
public function __construct(
public readonly Keyword $keyword,
public readonly GroupSpec|ConstSpec $spec,
) {
if ($spec->type() !== SpecType::Const) {
throw new InvalidArgument(\sprintf('Cannot create a ConstDecl with Spec of type %s', $spec->type()->name));
throw new InvalidArgument(sprintf('Cannot create a ConstDecl with Spec of type %s', $spec->type()->name));
}
}
}
4 changes: 1 addition & 3 deletions src/Ast/Stmt/Decl.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@

namespace GoParser\Ast\Stmt;

interface Decl extends Stmt
{
}
interface Decl extends Stmt {}
6 changes: 3 additions & 3 deletions src/Ast/Stmt/IfStmt.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@
final class IfStmt implements Stmt
{
public function __construct(
public readonly Keyword $if,
public readonly Keyword $keyword,
public readonly ?SimpleStmt $init,
public readonly Expr $condition,
public readonly BlockStmt $ifBody,
public readonly ?Keyword $else,
public readonly ?Keyword $elseKeyword,
public readonly BlockStmt|self|null $elseBody,
) {
if ((bool) $else !== (bool) $elseBody) {
if ((bool) $elseKeyword !== (bool) $elseBody) {
throw new InvalidArgument('Both "else" keyword and the body must be present or neither.');
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/Ast/Stmt/ImportDecl.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@
use GoParser\Ast\Keyword;
use GoParser\Ast\SpecType;

use function sprintf;

final class ImportDecl implements Decl
{
public function __construct(
public readonly Keyword $keyword,
public readonly GroupSpec|ImportSpec $spec,
) {
if ($spec->type() !== SpecType::Import) {
throw new InvalidArgument(\sprintf('Cannot create a ImportDecl with Spec of type %s', $spec->type()->name));
throw new InvalidArgument(sprintf('Cannot create a ImportDecl with Spec of type %s', $spec->type()->name));
}
}
}
4 changes: 1 addition & 3 deletions src/Ast/Stmt/SimpleStmt.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@

namespace GoParser\Ast\Stmt;

interface SimpleStmt extends Stmt
{
}
interface SimpleStmt extends Stmt {}
4 changes: 1 addition & 3 deletions src/Ast/Stmt/Stmt.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,4 @@

use GoParser\Ast\AstNode;

interface Stmt extends AstNode
{
}
interface Stmt extends AstNode {}
4 changes: 1 addition & 3 deletions src/Ast/Stmt/SwitchStmt.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@

namespace GoParser\Ast\Stmt;

interface SwitchStmt extends Stmt
{
}
interface SwitchStmt extends Stmt {}
4 changes: 3 additions & 1 deletion src/Ast/Stmt/TypeDecl.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@
use GoParser\Ast\SpecType;
use GoParser\Ast\TypeSpec;

use function sprintf;

final class TypeDecl implements Decl
{
public function __construct(
public readonly Keyword $keyword,
public readonly GroupSpec|TypeSpec $spec,
) {
if ($spec->type() !== SpecType::Type) {
throw new InvalidArgument(\sprintf('Cannot create a TypeDecl with Spec of type %s', $spec->type()->name));
throw new InvalidArgument(sprintf('Cannot create a TypeDecl with Spec of type %s', $spec->type()->name));
}
}
}
4 changes: 3 additions & 1 deletion src/Ast/Stmt/VarDecl.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@
use GoParser\Ast\SpecType;
use GoParser\Ast\VarSpec;

use function sprintf;

final class VarDecl implements Decl
{
public function __construct(
public readonly Keyword $keyword,
public readonly GroupSpec|VarSpec $spec,
) {
if ($spec->type() !== SpecType::Var) {
throw new InvalidArgument(\sprintf('Cannot create a VarDecl with Spec of type %s', $spec->type()->name));
throw new InvalidArgument(sprintf('Cannot create a VarDecl with Spec of type %s', $spec->type()->name));
}
}
}
4 changes: 3 additions & 1 deletion src/Exception/InvalidArgument.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

namespace GoParser\Exception;

final class InvalidArgument extends \InvalidArgumentException
use InvalidArgumentException;

final class InvalidArgument extends InvalidArgumentException
{
public function __construct(string $message)
{
Expand Down

0 comments on commit e061fdb

Please sign in to comment.