Skip to content

Commit c05a17a

Browse files
committed
Initial commmit
0 parents  commit c05a17a

13 files changed

+548
-0
lines changed

.docheader

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/**
2+
* @see https://github.com/open-code-modeling/json-schema-to-php-ast for the canonical source repository
3+
* @copyright https://github.com/open-code-modeling/json-schema-to-php-ast/blob/master/COPYRIGHT.md
4+
* @license https://github.com/open-code-modeling/json-schema-to-php-ast/blob/master/LICENSE.md MIT License
5+
*/

.github/workflows/integration.yml

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
name: Testing JSON schema to PHP
2+
on: [push, pull_request]
3+
4+
jobs:
5+
tests:
6+
strategy:
7+
fail-fast: false
8+
matrix:
9+
php-version:
10+
- "7.4"
11+
os: [ubuntu-latest]
12+
experimental: [false]
13+
include:
14+
- php-version: "8.0"
15+
os: ubuntu-latest
16+
experimental: true
17+
runs-on: ${{ matrix.os }}
18+
name: PHP ${{ matrix.php-version }} Test on ${{ matrix.os }}
19+
continue-on-error: ${{ matrix.experimental }}
20+
steps:
21+
- name: "Checkout"
22+
uses: "actions/checkout@v2.3.1"
23+
24+
- name: "Install PHP"
25+
uses: "shivammathur/setup-php@2.4.1"
26+
with:
27+
php-version: "${{ matrix.php-version }}"
28+
coverage: xdebug
29+
30+
- name: Get composer cache directory
31+
id: composercache
32+
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
33+
34+
- name: Cache composer dependencies
35+
uses: actions/cache@v2
36+
with:
37+
path: ${{ steps.composercache.outputs.dir }}
38+
# Use composer.json for key, if composer.lock is not committed.
39+
# key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
40+
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
41+
restore-keys: ${{ runner.os }}-composer-
42+
43+
- name: Install Composer dependencies
44+
run: |
45+
composer install --no-progress --prefer-dist --optimize-autoloader
46+
47+
#- name: Run Tests
48+
# run: php vendor/bin/phpunit --coverage-text
49+
50+
coding-standard:
51+
name: Coding Standard
52+
runs-on: ubuntu-latest
53+
steps:
54+
- name: Checkout
55+
uses: actions/checkout@v2
56+
57+
- name: Setup PHP
58+
uses: shivammathur/setup-php@v2
59+
with:
60+
php-version: '7.4'
61+
62+
- name: Get composer cache directory
63+
id: composercache
64+
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
65+
66+
- name: Cache composer dependencies
67+
uses: actions/cache@v2
68+
with:
69+
path: ${{ steps.composercache.outputs.dir }}
70+
# Use composer.json for key, if composer.lock is not committed.
71+
# key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
72+
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
73+
restore-keys: ${{ runner.os }}-composer-
74+
75+
- name: Install dependencies
76+
run: composer install --no-progress --prefer-dist --optimize-autoloader
77+
78+
- name: PHP CodeSniffer
79+
run: composer cs
80+
81+
static-analysis:
82+
name: Static Analysis
83+
runs-on: ubuntu-latest
84+
steps:
85+
- name: Checkout
86+
uses: actions/checkout@v2
87+
88+
- name: Setup PHP
89+
uses: shivammathur/setup-php@v2
90+
with:
91+
php-version: '7.4'
92+
93+
- name: Get composer cache directory
94+
id: composercache
95+
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
96+
97+
- name: Cache composer dependencies
98+
uses: actions/cache@v2
99+
with:
100+
path: ${{ steps.composercache.outputs.dir }}
101+
# Use composer.json for key, if composer.lock is not committed.
102+
# key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
103+
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
104+
restore-keys: ${{ runner.os }}-composer-
105+
106+
- name: Install dependencies
107+
run: composer install --no-progress --prefer-dist --optimize-autoloader
108+
109+
- name: Static Analysis using PHPStan
110+
run: composer analyse

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.env
2+
app.env
3+
.phpunit.result.cache
4+
build/*
5+
vendor/
6+
composer.lock
7+
.idea
8+
.php_cs.cache

.php_cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
$config = new Prooph\CS\Config\Prooph();
4+
$config->getFinder()->in(__DIR__);
5+
6+
$cacheDir = getenv('TRAVIS') ? getenv('HOME') . '/.php-cs-fixer' : __DIR__;
7+
8+
$config->setCacheFile($cacheDir . '/.php_cs.cache');
9+
10+
return $config;

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Changelog

COPYRIGHT.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Copyright (c) 2020 Sandro Keil

LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# MIT License
2+
3+
Copyright (c) 2020 Sandro Keil
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# JSON Schema to PHP AST
2+
3+
Compiles a JSON schema to PHP classes / value objects via PHP AST.
4+
5+
## Installation
6+
7+
```bash
8+
$ composer require open-code-modeling/json-schema-to-php-ast --dev
9+
```

composer.json

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
{
2+
"name": "open-code-modeling/json-schema-to-php-ast",
3+
"description": "Provides factories to create PhpParser node visitors from JSON schema e. g. value objects",
4+
"license": "MIT",
5+
"type": "library",
6+
"keywords": [
7+
"php",
8+
"json",
9+
"schema",
10+
"code",
11+
"generation"
12+
],
13+
"authors": [
14+
{
15+
"name": "Sandro Keil",
16+
"homepage": "https://sandro-keil.de",
17+
"role": "maintainer"
18+
}
19+
],
20+
"support": {
21+
"issues": "https://github.com/open-code-modeling/json-schema-to-php-ast/issues",
22+
"source": "https://github.com/open-code-modeling/json-schema-to-php-ast"
23+
},
24+
"autoload": {
25+
"psr-4": {
26+
"OpenCodeModeling\\JsonSchemaToPhpAst\\": "src/"
27+
}
28+
},
29+
"autoload-dev": {
30+
"psr-4": {
31+
"OpenCodeModelingTest\\JsonSchemaToPhpAst\\": "tests/"
32+
}
33+
},
34+
"require": {
35+
"php": "^7.4 || ^8.0",
36+
"open-code-modeling/json-schema-to-php": "dev-master",
37+
"open-code-modeling/php-code-ast": "^0.1.0"
38+
},
39+
"require-dev": {
40+
"jangregor/phpstan-prophecy": "^0.8.0",
41+
"phpspec/prophecy-phpunit": "^2.0",
42+
"phpstan/phpstan": "^0.12.33",
43+
"phpstan/phpstan-strict-rules": "^0.12.4",
44+
"phpunit/phpunit": "^9.2.6",
45+
"prooph/php-cs-fixer-config": "^0.3",
46+
"roave/security-advisories": "dev-master",
47+
"squizlabs/php_codesniffer": "^3.4"
48+
},
49+
"minimum-stability": "dev",
50+
"prefer-stable": true,
51+
"scripts": {
52+
"check": [
53+
"@cs",
54+
"@test"
55+
],
56+
"cs": "php-cs-fixer fix src -v --diff --dry-run",
57+
"cs-fix": "php-cs-fixer fix src -v --diff",
58+
"test": "vendor/bin/phpunit",
59+
"analyse": "php vendor/bin/phpstan.phar analyse --no-interaction"
60+
},
61+
"config": {
62+
"sort-packages": true,
63+
"platform": {
64+
}
65+
},
66+
"archive": {
67+
"exclude": [
68+
"build",
69+
"phpunit.xml*",
70+
"tests"
71+
]
72+
}
73+
}

phpstan.neon.dist

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
parameters:
2+
level: 6
3+
paths:
4+
- src/
5+
- tests/

phpunit.xml.dist

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" colors="true" cacheResult="true" stopOnFailure="false" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" backupGlobals="false" backupStaticAttributes="false" failOnRisky="true" failOnWarning="true" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
3+
<coverage>
4+
<include>
5+
<directory>./src/</directory>
6+
</include>
7+
</coverage>
8+
<testsuite name="Open Code Modeling JSON schema to PHP - Test Suite">
9+
<directory suffix=".php">./tests</directory>
10+
</testsuite>
11+
</phpunit>

src/PropertyFactory.php

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<?php
2+
3+
/**
4+
* @see https://github.com/open-code-modeling/json-schema-to-php-ast for the canonical source repository
5+
* @copyright https://github.com/open-code-modeling/json-schema-to-php-ast/blob/master/COPYRIGHT.md
6+
* @license https://github.com/open-code-modeling/json-schema-to-php-ast/blob/master/LICENSE.md MIT License
7+
*/
8+
9+
declare(strict_types=1);
10+
11+
namespace OpenCodeModeling\JsonSchemaToPhpAst;
12+
13+
use OpenCodeModeling\CodeAst\Code\PropertyGenerator;
14+
use OpenCodeModeling\JsonSchemaToPhp\Type\ArrayType;
15+
use OpenCodeModeling\JsonSchemaToPhp\Type\ObjectType;
16+
use OpenCodeModeling\JsonSchemaToPhp\Type\ReferenceType;
17+
use OpenCodeModeling\JsonSchemaToPhp\Type\TypeDefinition;
18+
use OpenCodeModeling\JsonSchemaToPhp\Type\TypeSet;
19+
use PhpParser\NodeVisitor;
20+
21+
final class PropertyFactory
22+
{
23+
/**
24+
* @param TypeSet $typeSet
25+
* @return array<NodeVisitor>
26+
*/
27+
public function nodeVisitorFromTypeSet(TypeSet $typeSet): array
28+
{
29+
if (\count($typeSet) !== 1) {
30+
throw new \RuntimeException('Can only handle one type');
31+
}
32+
33+
return $this->nodeVisitorFromTypeDefinition($typeSet->first());
34+
}
35+
36+
/**
37+
* @param ObjectType $type
38+
* @return array<NodeVisitor>
39+
*/
40+
public function nodeVisitorFromObjectType(ObjectType $type): array
41+
{
42+
$nodeVisitors = [];
43+
$properties = $type->properties();
44+
45+
/**
46+
* @var TypeSet $typeSet
47+
*/
48+
foreach ($properties as $typeName => $typeSet) {
49+
if (\count($typeSet) !== 1) {
50+
throw new \RuntimeException(\sprintf('Can only handle one type for property "%s"', $typeName));
51+
}
52+
53+
$nodeVisitors = \array_merge($nodeVisitors, $this->nodeVisitorFromTypeDefinition($typeSet->first()));
54+
}
55+
56+
return $nodeVisitors;
57+
}
58+
59+
/**
60+
* @param ArrayType $type
61+
* @return array<NodeVisitor>
62+
*/
63+
public function nodeVisitorFromArrayType(ArrayType $type): array
64+
{
65+
return [];
66+
}
67+
68+
/**
69+
* @param TypeDefinition $type
70+
* @return array<NodeVisitor>
71+
*/
72+
public function nodeVisitorFromTypeDefinition(TypeDefinition $type): array
73+
{
74+
return $this->nodeVisitorFromNative($type->name(), $type->type());
75+
}
76+
77+
/**
78+
* @param string $name
79+
* @param string $type
80+
* @return array<NodeVisitor>
81+
*/
82+
public function nodeVisitorFromNative(string $name, string $type): array
83+
{
84+
return [
85+
new \OpenCodeModeling\CodeAst\NodeVisitor\Property(
86+
new PropertyGenerator($name, $type)
87+
),
88+
];
89+
}
90+
91+
/**
92+
* @param ReferenceType $type
93+
* @return array<NodeVisitor>
94+
*/
95+
public function nodeVisitorFromReferenceType(ReferenceType $type): array
96+
{
97+
$resolvedTypeSet = $type->resolvedType();
98+
99+
if (null === $resolvedTypeSet) {
100+
throw new \RuntimeException(\sprintf('No resolved type available for reference "%s"', $type->ref()));
101+
}
102+
103+
if (\count($resolvedTypeSet) !== 1) {
104+
throw new \RuntimeException(\sprintf('Can only handle handle one type for reference "%s"', $type->ref()));
105+
}
106+
$resolvedType = $resolvedTypeSet->first();
107+
108+
switch (true) {
109+
case $resolvedType instanceof ObjectType:
110+
return $this->nodeVisitorFromObjectType($resolvedType);
111+
case $resolvedType instanceof ArrayType:
112+
return $this->nodeVisitorFromArrayType($resolvedType);
113+
default:
114+
return $this->nodeVisitorFromTypeDefinition($resolvedType);
115+
}
116+
}
117+
}

0 commit comments

Comments
 (0)