Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
assert-function-signature
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Jan Kuchař
assert-function-signature
Commits
3343ecf9
Commit
3343ecf9
authored
8 years ago
by
Jan Kuchař
Browse files
Options
Downloads
Patches
Plain Diff
assertion errors are now errors not exceptions
parent
6520cf00
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/exceptions.php
+29
-10
29 additions, 10 deletions
src/exceptions.php
src/functions.php
+23
-18
23 additions, 18 deletions
src/functions.php
with
52 additions
and
28 deletions
src/exceptions.php
+
29
−
10
View file @
3343ecf9
...
@@ -3,35 +3,54 @@ namespace Grifart\AssertFunction;
...
@@ -3,35 +3,54 @@ namespace Grifart\AssertFunction;
use
Throwable
;
use
Throwable
;
final
class
AssertFunctionException
extends
\LogicException
{
final
class
AssertFunctionError
extends
\AssertionError
{
const
PATH_DEPTH
=
3
;
/** @internal use named constructors instead */
/** @internal use named constructors instead */
public
function
__construct
(
$message
,
\Throwable
$previous
=
NULL
)
public
function
__construct
(
\ReflectionFunction
$reflection
,
string
$message
,
\Throwable
$previous
=
NULL
)
{
{
parent
::
__construct
(
$message
,
0
,
$previous
);
parent
::
__construct
(
self
::
location
(
$reflection
)
.
' '
.
$message
,
0
,
$previous
);
}
}
private
static
function
location
(
\ReflectionFunction
$reflection
)
:
string
private
static
function
location
(
\ReflectionFunction
$reflection
)
:
string
{
{
return
$reflection
->
getFileName
()
.
':'
.
$reflection
->
getStartLine
()
.
'-'
.
$reflection
->
getEndLine
()
.
' '
;
$startLine
=
(
string
)
$reflection
->
getStartLine
();
$endLine
=
(
string
)
$reflection
->
getEndLine
();
$linePosition
=
(
$startLine
===
$endLine
)
?
$startLine
:
(
$startLine
.
'-'
.
$endLine
);
return
self
::
shortenPath
(
$reflection
->
getFileName
())
.
':'
.
$linePosition
;
}
}
public
static
function
cannotStartReflection
(
\ReflectionException
$exception
)
:
self
public
static
function
wrongNumberOrArguments
(
\ReflectionFunction
$reflection
,
int
$numberOfParameters
,
int
$actualCount
)
:
self
{
{
return
new
self
(
'Cannot start reflection for given function.'
,
0
,
$exception
);
return
new
self
(
$reflection
,
"Given wrong number of parameters. Expected
$numberOfParameters
,
$actualCount
given."
);
}
}
public
static
function
wrongNumberOrArguments
(
\ReflectionFunction
$reflection
,
int
$numberOfParameters
,
in
t
$
actualCount
)
:
self
public
static
function
missingReturnType
(
\ReflectionFunction
$reflection
,
str
in
g
$
type
)
:
self
{
{
return
new
self
(
self
::
location
(
$reflection
)
.
"Given wrong number of parameters. Expected
$numberOfParameters
,
$actualCount
given
."
);
return
new
self
(
$reflection
,
"Function is required to have return type of type
$type
."
);
}
}
p
ublic
static
function
missingReturnType
(
\ReflectionFunction
$reflection
,
string
$type
)
:
self
p
rivate
static
function
shortenPath
(
string
$path
):
string
{
{
return
new
self
(
self
::
location
(
$reflection
)
.
"Function is required to have return type of type
$type
."
);
$pathArr
=
explode
(
DIRECTORY_SEPARATOR
,
$path
);
$pathNumParts
=
count
(
$pathArr
);
$pathParts
=
array_filter
(
$pathArr
,
function
(
$val
,
$idx
)
use
(
$pathNumParts
)
{
// only last x parts
return
$idx
>=
$pathNumParts
-
self
::
PATH_DEPTH
;
},
ARRAY_FILTER_USE_BOTH
);
return
implode
(
'/'
,
$pathParts
);
// normalized shortened readable path
}
}
};
};
...
...
This diff is collapsed.
Click to expand it.
src/functions.php
+
23
−
18
View file @
3343ecf9
...
@@ -5,7 +5,7 @@
...
@@ -5,7 +5,7 @@
// todo: use only assert( ... ) instead of exceptions; to be compatible without configuration with PHP env
// todo: use only assert( ... ) instead of exceptions; to be compatible without configuration with PHP env
// todo: [performance] separate code itself into autoloaded class
// todo: [performance] separate code itself into autoloaded class
// todo: better assertion messages
// todo: better assertion messages
+ throw AssertFunctionError
// todo: covariance and contra-variance
// todo: covariance and contra-variance
namespace
Grifart\AssertFunction
;
namespace
Grifart\AssertFunction
;
...
@@ -22,18 +22,21 @@ function optional(string $classType): string
...
@@ -22,18 +22,21 @@ function optional(string $classType): string
function
assertFunction
(
callable
$function
,
array
$parameters
,
?string
$expectedReturnType
):
void
function
assertFunction
(
callable
$function
,
array
$parameters
,
?string
$expectedReturnType
):
void
{
{
try
{
// todo: call assert(__impl());
$reflection
=
new
\ReflectionFunction
(
$function
);
$reflection
=
new
\ReflectionFunction
(
$function
);
}
catch
(
\ReflectionException
$exception
)
{
throw
AssertFunctionException
::
cannotStartReflection
(
$exception
);
}
// PARAMETERS CHECK:
//
NUMBER
PARAMETERS CHECK:
$numberOfParameters
=
$reflection
->
getNumberOfParameters
();
$numberOfParameters
=
$reflection
->
getNumberOfParameters
();
assert
(
$numberOfParameters
===
count
(
$parameters
),
AssertFunctionError
::
wrongNumberOrArguments
(
$reflection
,
count
(
$parameters
),
$numberOfParameters
)
);
if
(
$numberOfParameters
!==
count
(
$parameters
))
{
if
(
$numberOfParameters
!==
count
(
$parameters
))
{
throw
AssertFunctionException
::
wrongNumberOrArguments
(
$reflection
,
count
(
$parameters
),
$numberOfParameters
)
;
return
;
}
}
// PARAMETER TYPES CHECK:
$i
=
0
;
$i
=
0
;
/** @var string[] $parameters */
/** @var string[] $parameters */
foreach
(
$parameters
AS
$parameter
)
{
foreach
(
$parameters
AS
$parameter
)
{
...
@@ -48,26 +51,28 @@ function assertFunction(callable $function, array $parameters, ?string $expected
...
@@ -48,26 +51,28 @@ function assertFunction(callable $function, array $parameters, ?string $expected
// RETURN TYPE:
// RETURN TYPE:
if
(
$expectedReturnType
!==
NULL
)
{
if
(
$expectedReturnType
!==
NULL
)
{
assert
(
$reflection
->
hasReturnType
(),
AssertFunctionError
::
missingReturnType
(
$reflection
,
$expectedReturnType
)
);
if
(
!
$reflection
->
hasReturnType
())
{
if
(
$reflection
->
hasReturnType
())
{
throw
AssertFunctionException
::
missingReturnType
(
$reflection
,
$expectedReturnType
);
list
(
$_returnType
,
$_optional
)
=
__parseType
(
$expectedReturnType
);
}
$returnTypeReflection
=
$reflection
->
getReturnType
();
list
(
$_returnType
,
$_optional
)
=
__parseType
(
$expectedReturnType
);
assert
(
$_optional
===
$returnTypeReflection
->
allowsNull
());
$returnTypeReflection
=
$reflection
->
getReturnType
();
assert
(
$_returnType
===
(
string
)
$reflection
->
getReturnType
());
}
assert
(
$_optional
===
$returnTypeReflection
->
allowsNull
());
assert
(
$_returnType
===
(
string
)
$reflection
->
getReturnType
());
}
}
}
}
function
__parseType
(
string
$type
):
array
function
__parseType
(
string
$type
):
array
{
{
$cleanType
=
$type
;
$cleanType
=
$type
;
// e.g. ?Namespace\Class
$optional
=
FALSE
;
$optional
=
FALSE
;
if
(
$type
[
0
]
===
'?'
)
{
if
(
$type
[
0
]
===
'?'
)
{
$optional
=
TRUE
;
$optional
=
TRUE
;
$cleanType
=
substr
(
$type
,
1
);
// without leading
?
$cleanType
=
substr
(
$type
,
1
);
// without leading
'?'
}
}
return
[
$cleanType
,
$optional
];
return
[
$cleanType
,
$optional
];
}
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment