Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Pôle IS
Bundles Symfony 2
ng-model-generator-bundle
Commits
59a0bce5
Commit
59a0bce5
authored
Aug 27, 2018
by
Guillaume Perréal
Browse files
Refactoring pour simplifier l'optimisation des représentations vides.
parent
cac0db1e
Changes
13
Hide whitespace changes
Inline
Side-by-side
src/Iterators/UniqueFilter.php
View file @
59a0bce5
<?php
declare
(
strict_types
=
1
);
/**
/*
* irstea/ng-model-generator-bundle generates Typescript interfaces for Angular using api-platform metadata.
* Copyright (C) 2018 IRSTEA
* All rights reserved.
* @copyright 2018 IRSTEA
* @author guillaume.perreal
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License and the GNU
* Lesser General Public License along with this program. If not, see
* <https://www.gnu.org/licenses/>.
*/
namespace
Irstea\NgModelGeneratorBundle\Iterators
;
/**
* Class UniqueFilter
* Class UniqueFilter
.
*/
final
class
UniqueFilter
{
...
...
@@ -25,18 +36,15 @@ final class UniqueFilter
*/
public
function
__invoke
(
$value
):
bool
{
$key
=
is_object
(
$value
)
?
spl_object_hash
(
$value
)
:
(
string
)
$value
;
if
(
isset
(
$this
->
seen
[
$key
]))
{
return
false
;
}
$key
=
is_object
(
$value
)
?
spl_object_hash
(
$value
)
:
(
string
)
$value
;
$alreadySeen
=
isset
(
$this
->
seen
[
$key
]);
$this
->
seen
[
$key
]
=
true
;
return
true
;
return
!
$alreadySeen
;
}
/**
*
*/
public
function
reset
():
void
{
public
function
reset
():
void
{
$this
->
seen
=
[];
}
}
src/Models/Declaration.php
0 → 100644
View file @
59a0bce5
<?php
declare
(
strict_types
=
1
);
/*
* irstea/ng-model-generator-bundle generates Typescript interfaces for Angular using api-platform metadata.
* Copyright (C) 2018 IRSTEA
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License and the GNU
* Lesser General Public License along with this program. If not, see
* <https://www.gnu.org/licenses/>.
*/
namespace
Irstea\NgModelGeneratorBundle\Models
;
/**
* Interface Declaration.
*/
interface
Declaration
{
/**
* @return string
*/
public
function
getName
():
string
;
/**
* @return string
*/
public
function
getDeclaration
():
string
;
}
src/Models/Types/AbstractType.php
View file @
59a0bce5
...
...
@@ -19,6 +19,8 @@
namespace
Irstea\NgModelGeneratorBundle\Models\Types
;
use
Irstea\NgModelGeneratorBundle\FQCN
;
/**
* Class AbstractType.
*/
...
...
@@ -33,10 +35,10 @@ abstract class AbstractType implements Type
}
/**
*
{@inheritdoc}
*
@return string
*/
public
function
getDeclaration
(
string
$name
):
string
public
function
__toString
()
{
return
sprintf
(
'
export type %s = %s'
,
$name
,
$this
->
getUsage
(
));
return
sprintf
(
'
%s(#%x)'
,
FQCN
::
baseName
(
get_class
(
$this
)),
spl_object_hash
(
$this
));
}
}
src/Models/
Operations/TransformedParameter
.php
→
src/Models/
Types/Alias
.php
View file @
59a0bce5
...
...
@@ -17,22 +17,39 @@
* <https://www.gnu.org/licenses/>.
*/
namespace
Irstea\NgModelGeneratorBundle\Models\
Operation
s
;
namespace
Irstea\NgModelGeneratorBundle\Models\
Type
s
;
use
Irstea\NgModelGeneratorBundle\Models\
Types\AnonymousObject
;
use
Irstea\NgModelGeneratorBundle\Models\
Types\Type
;
use
Irstea\NgModelGeneratorBundle\Models\
Declaration
;
use
Irstea\NgModelGeneratorBundle\Models\
NamedTrait
;
/**
* Class
TransformedParameter
.
* Class
Alias
.
*/
final
class
TransformedParameter
ext
en
d
s
Parameter
final
class
Alias
extends
AbstractType
implem
en
t
s
Declaration
{
use
NamedTrait
;
/** @var Type */
private
$target
;
/**
* Alias constructor.
*
* @param string $name
* @param Type $target
*/
public
function
__construct
(
string
$name
,
Type
$target
)
{
$this
->
name
=
$name
;
$this
->
target
=
$target
;
}
/**
* {@inheritdoc}
*/
public
function
__construct
(
string
$name
,
Type
$type
,
bool
$optional
=
false
)
public
function
getDeclaration
():
string
{
parent
::
__construct
(
$name
,
$type
,
$optional
);
return
sprintf
(
'export type %s = %s;'
,
$this
->
name
,
$this
->
target
->
getUsage
()
);
}
/**
...
...
@@ -40,24 +57,14 @@ final class TransformedParameter extends Parameter
*/
public
function
getUsage
():
string
{
$components
=
[];
/** @var AnonymousObject $type */
$type
=
$this
->
getType
();
$paramName
=
$this
->
getName
();
foreach
(
$type
->
getProperties
()
as
$property
)
{
$propertyName
=
$property
->
getEscapedName
();
$rhs
=
$propertyName
!==
$property
->
getName
()
?
"${paramName}[${propertyName}]"
:
"${paramName}.${propertyName}"
;
if
(
$property
->
getType
()
->
getUsage
()
!==
'string'
)
{
$rhs
=
"''+${rhs}"
;
}
$components
[]
=
"${propertyName}: ${rhs}"
;
}
return
$this
->
name
;
}
return
sprintf
(
'%s: {%s}'
,
$this
->
getName
(),
implode
(
', '
,
$components
));
/**
* {@inheritdoc}
*/
public
function
getIterator
()
{
yield
$this
->
target
;
}
}
src/Models/Types/AnonymousObject.php
View file @
59a0bce5
...
...
@@ -25,18 +25,20 @@ namespace Irstea\NgModelGeneratorBundle\Models\Types;
class
AnonymousObject
extends
AbstractType
implements
Object
{
/**
* @var
array<string,
Property
>
* @var Property
[]
*/
private
$properties
=
[];
/**
* Resource constructor.
*
* @param
array<string,
Property
>
$properties
* @param Property
[]
$properties
*/
public
function
__construct
(
array
$properties
=
[])
{
$this
->
properties
=
array_values
(
$properties
);
foreach
(
$properties
as
$property
)
{
$this
->
properties
[
$property
->
getName
()]
=
$property
;
}
}
/**
...
...
@@ -58,15 +60,15 @@ class AnonymousObject extends AbstractType implements Object
/**
* {@inheritdoc}
*/
final
public
function
getDeclaration
(
string
$name
):
string
final
public
function
getDeclaration
():
string
{
return
trim
(
$this
->
getDeclarationHeader
(
$name
)
.
' '
.
$this
->
getDeclarationBody
(
true
));
return
trim
(
$this
->
getDeclarationHeader
()
.
' '
.
$this
->
getDeclarationBody
(
true
));
}
/**
* @return string
*/
protected
function
getDeclarationHeader
(
string
$name
):
string
protected
function
getDeclarationHeader
():
string
{
return
''
;
}
...
...
src/Models/Types/ObjectClass.php
View file @
59a0bce5
...
...
@@ -19,11 +19,16 @@
namespace
Irstea\NgModelGeneratorBundle\Models\Types
;
use
Irstea\NgModelGeneratorBundle\Models\Declaration
;
use
Irstea\NgModelGeneratorBundle\Models\NamedTrait
;
/**
* Class ObjectClass.
*/
class
ObjectClass
extends
AnonymousObject
class
ObjectClass
extends
AnonymousObject
implements
Declaration
{
use
NamedTrait
;
public
const
KIND_CLASS
=
'class'
;
public
const
KIND_INTERFACE
=
'interface'
;
...
...
@@ -37,22 +42,32 @@ class ObjectClass extends AnonymousObject
* ObjectClass constructor.
*
* @param string $kind
* @param string $name
* @param array $parents
* @param array $properties
*/
public
function
__construct
(
string
$kind
,
array
$parents
=
[],
array
$properties
=
[])
public
function
__construct
(
string
$kind
,
string
$name
,
array
$parents
=
[],
array
$properties
=
[])
{
parent
::
__construct
(
$properties
);
$this
->
name
=
$name
;
$this
->
kind
=
$kind
;
$this
->
parents
=
$parents
;
}
/**
* @return string
*/
public
function
getUsage
():
string
{
return
$this
->
name
;
}
/**
* {@inheritdoc}
*/
protected
function
getDeclarationHeader
(
string
$name
):
string
protected
function
getDeclarationHeader
():
string
{
return
implode
(
' '
,
[
'export'
,
$this
->
kind
,
$name
,
$this
->
getInheritanceDeclaration
()]);
return
implode
(
' '
,
[
'export'
,
$this
->
kind
,
$
this
->
name
,
$this
->
getInheritanceDeclaration
()]);
}
/**
...
...
src/Models/Types/Reference.php
View file @
59a0bce5
...
...
@@ -22,7 +22,7 @@ namespace Irstea\NgModelGeneratorBundle\Models\Types;
/**
* Class Ref.
*/
final
class
Reference
extends
AbstractType
class
Reference
extends
AbstractType
{
/** @var Type */
private
$target
;
...
...
@@ -80,4 +80,12 @@ final class Reference extends AbstractType
{
yield
$this
->
target
;
}
/**
* {@inheritdoc}
*/
public
function
__toString
()
{
return
'&'
.
$this
->
target
;
}
}
src/Models/Types/Repository.php
View file @
59a0bce5
...
...
@@ -19,6 +19,7 @@
namespace
Irstea\NgModelGeneratorBundle\Models\Types
;
use
Irstea\NgModelGeneratorBundle\FQCN
;
use
Irstea\NgModelGeneratorBundle\Models\Operations\Operation
;
/**
...
...
@@ -44,7 +45,7 @@ final class Repository extends ObjectClass
*/
public
function
__construct
(
string
$resourceName
,
array
$operations
)
{
parent
::
__construct
(
self
::
KIND_CLASS
,
[],
[]);
parent
::
__construct
(
self
::
KIND_CLASS
,
FQCN
::
baseName
(
$resourceName
)
.
'Repository'
,
[],
[]);
$this
->
resourceName
=
$resourceName
;
$this
->
operations
=
$operations
;
}
...
...
@@ -75,9 +76,9 @@ final class Repository extends ObjectClass
/**
* {@inheritdoc}
*/
protected
function
getDeclarationHeader
(
string
$name
):
string
protected
function
getDeclarationHeader
():
string
{
return
"@Inject()
\n
"
.
parent
::
getDeclarationHeader
(
$name
);
return
"@Inject()
\n
"
.
parent
::
getDeclarationHeader
();
}
/**
...
...
src/Models/Types/Representation.php
View file @
59a0bce5
...
...
@@ -31,12 +31,13 @@ final class Representation extends ObjectClass
* Representation constructor.
*
* @param string $resourceClass
* @param string $name
* @param array $parents
* @param array $properties
*/
public
function
__construct
(
string
$resourceClass
,
array
$parents
=
[],
array
$properties
=
[])
public
function
__construct
(
string
$resourceClass
,
string
$name
,
array
$parents
=
[],
array
$properties
=
[])
{
parent
::
__construct
(
self
::
KIND_INTERFACE
,
$parents
,
$properties
);
parent
::
__construct
(
self
::
KIND_INTERFACE
,
$name
,
$parents
,
$properties
);
$this
->
resourceClass
=
$resourceClass
;
}
...
...
src/Models/Types/Type.php
View file @
59a0bce5
...
...
@@ -29,13 +29,6 @@ interface Type extends \IteratorAggregate
*/
public
function
getUsage
():
string
;
/**
* @param string $name
*
* @return string
*/
public
function
getDeclaration
(
string
$name
):
string
;
/**
* @return Type
*/
...
...
src/OperationMapper.php
View file @
59a0bce5
...
...
@@ -124,8 +124,8 @@ final class OperationMapper
$qpName
=
$this
->
operation
->
getResource
()
->
getShortName
()
.
ucfirst
(
$name
)
.
'Params'
;
$queryParameters
=
$this
->
typeFactory
->
getOrCreate
(
$qpName
,
function
()
use
(
$queryParameters
):
Type
{
return
new
ObjectClass
(
ObjectClass
::
KIND_INTERFACE
,
[],
$queryParameters
);
function
()
use
(
$queryParameters
,
$qpName
):
Type
{
return
new
ObjectClass
(
ObjectClass
::
KIND_INTERFACE
,
$qpName
,
[],
$queryParameters
);
}
);
}
...
...
src/ResourceTypeFactory.php
View file @
59a0bce5
...
...
@@ -98,10 +98,12 @@ final class ResourceTypeFactory implements TypeFactoryInterface
}
if
(
$this
->
metadataFactory
->
isResource
(
$name
))
{
$reprName
=
$this
->
getRepresentationName
(
$name
);
return
$this
->
typeFactory
->
getOrCreate
(
$
this
->
getRepresentationName
(
$name
)
,
function
()
use
(
$name
):
Type
{
return
$this
->
mapRepresentation
(
$name
);
$
reprName
,
function
()
use
(
$name
,
$reprName
):
Type
{
return
$this
->
mapRepresentation
(
$name
,
$reprName
);
}
);
}
...
...
@@ -143,7 +145,7 @@ final class ResourceTypeFactory implements TypeFactoryInterface
*
* @return Type
*/
private
function
mapRepresentation
(
string
$resourceClass
):
Type
private
function
mapRepresentation
(
string
$resourceClass
,
string
$name
):
Type
{
$resourceMeta
=
$this
->
metadataFactory
->
getResourceMetadata
(
$resourceClass
);
...
...
@@ -161,7 +163,7 @@ final class ResourceTypeFactory implements TypeFactoryInterface
);
}
return
new
Representation
(
$resourceClass
,
[],
$properties
);
return
new
Representation
(
$resourceClass
,
$name
,
[],
$properties
);
}
/**
...
...
src/Serializer.php
View file @
59a0bce5
...
...
@@ -20,7 +20,12 @@
namespace
Irstea\NgModelGeneratorBundle
;
use
ApiPlatform\Core\Documentation\Documentation
;
use
Irstea\NgModelGeneratorBundle\Iterators\RecursorIterator
;
use
Irstea\NgModelGeneratorBundle\Iterators\UniqueFilter
;
use
Irstea\NgModelGeneratorBundle\Models\Declaration
;
use
Irstea\NgModelGeneratorBundle\Models\Metadata\MetadataFactoryInterface
;
use
Irstea\NgModelGeneratorBundle\Models\Types\Alias
;
use
Irstea\NgModelGeneratorBundle\Models\Types\Reference
;
use
Irstea\NgModelGeneratorBundle\Models\Types\Repository
;
use
Irstea\NgModelGeneratorBundle\Models\Types\Representation
;
use
Irstea\NgModelGeneratorBundle\Models\Types\Type
;
...
...
@@ -70,13 +75,32 @@ final class Serializer implements NormalizerInterface, EncoderInterface
}
$typeFactory
=
$this
->
createTypeFactory
();
$this
->
extractRepositories
(
$doc
,
$typeFactory
);
$repos
=
$this
->
extractRepositories
(
$doc
,
$typeFactory
);
/** @var array<string,TypeDeclaration> $declarations */
$resources
=
[];
$iriType
=
$typeFactory
->
get
(
'IRI'
);
foreach
(
$typeFactory
as
$ref
)
{
if
(
!
(
$ref
instanceof
Reference
))
{
continue
;
}
$repr
=
$ref
->
dereference
();
if
(
!
(
$repr
instanceof
Representation
))
{
continue
;
}
if
(
!
$repr
->
hasNonIdentifierProperty
())
{
$ref
->
setTarget
(
$iriType
);
}
}
$declarations
=
[];
$repoClasses
=
[];
$resources
=
[];
foreach
(
$typeFactory
->
all
()
as
$name
=>
$type
)
{
foreach
(
$this
->
recursivelyIterateOnce
(
$repos
)
as
$type
)
{
if
(
!
(
$type
instanceof
Declaration
))
{
continue
;
}
$name
=
$type
->
getName
();
$declarations
[
$name
]
=
$type
;
if
(
$type
instanceof
Representation
)
{
$resources
[]
=
$name
;
}
...
...
@@ -85,22 +109,20 @@ final class Serializer implements NormalizerInterface, EncoderInterface
}
}
$data
=
[
return
[
'title'
=>
$doc
->
getTitle
(),
'version'
=>
$doc
->
getVersion
(),
'description'
=>
$doc
->
getDescription
()
?:
''
,
'declarations'
=>
$
typeFactory
->
all
()
,
'declarations'
=>
$
declarations
,
'repositories'
=>
$repoClasses
,
'resources'
=>
$resources
,
];
return
$data
;
}
/**
* @return TypeFactoryInterface
*/
private
function
createTypeFactory
():
TypeFactory
Interface
private
function
createTypeFactory
():
TypeFactory
{
$factory
=
new
TypeFactory
();
...
...
@@ -108,9 +130,14 @@ final class Serializer implements NormalizerInterface, EncoderInterface
$factory
->
addBuiltin
(
$builtin
);
}
$factory
->
getOrCreate
(
'UUID'
,
[
$factory
,
'get'
],
'string'
);
$factory
->
getOrCreate
(
'IRI'
,
[
$factory
,
'get'
],
'string'
);
$factory
->
getOrCreate
(
'DateTime'
,
[
$factory
,
'get'
],
'string'
);
foreach
([
'UUID'
,
'IRI'
,
'DateTime'
]
as
$name
)
{
$factory
->
getOrCreate
(
$name
,
function
()
use
(
$name
,
$factory
)
{
return
new
Alias
(
$name
,
$factory
->
get
(
'string'
));
}
);
}
foreach
([
PHPType
::
BUILTIN_TYPE_ARRAY
=>
'Array'
,
...
...
@@ -143,8 +170,10 @@ final class Serializer implements NormalizerInterface, EncoderInterface
foreach
(
$doc
->
getResourceNameCollection
()
as
$className
)
{
$resourceMeta
=
$this
->
metadataFactory
->
getResourceMetadata
(
$className
);
$repos
[]
=
$typeFactory
->
getOrCreate
(
$resourceMeta
->
getShortName
()
.
'Repository'
,
$repoName
=
$resourceMeta
->
getShortName
()
.
'Repository'
;
$repos
[
$repoName
]
=
$typeFactory
->
getOrCreate
(
$repoName
,
function
()
use
(
$resourceMeta
,
$typeFactory
):
Type
{
$operations
=
[];
...
...
@@ -158,9 +187,37 @@ final class Serializer implements NormalizerInterface, EncoderInterface
);
}
ksort
(
$repos
);
return
$repos
;
}
/**
* @param \Iterator|\IteratorAggregate|array $traversable
*
* @return \Iterator
*/
private
function
recursivelyIterateOnce
(
$traversable
):
\
Iterator
{
if
(
\
is_array
(
$traversable
))
{
$inner
=
new
\
ArrayIterator
(
$traversable
);
}
elseif
(
$traversable
instanceof
\
IteratorAggregate
)
{
$inner
=
$traversable
->
getIterator
();
}
elseif
(
$traversable
instanceof
\
Iterator
)
{
$inner
=
$traversable
;
}
else
{
throw
new
\
InvalidArgumentException
(
'expected a traversable value'
);
}
return
new
\
RecursiveIteratorIterator
(
new
\
RecursiveCallbackFilterIterator
(
new
RecursorIterator
(
$inner
),
new
UniqueFilter
()
),
\
RecursiveIteratorIterator
::
CHILD_FIRST
);
}
/**
* {@inheritdoc}
*/
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment