Reputation: 31813
In phpstorm, you can generate a setter method for class members by alt + insert > setters > picking the variables to make setter methods for.
But, even when phpstorm knows the type/class of the variable, it doesn't insert a type hint into the parameter list.
How to make phpstorm generate setters with type hints, but only for type hintable types?
Example class
class CodeGenerationTest {
/* @var \DateTimeInterface */
private $date;
/* @var int */
private $num;
}
The desired generated setters should be:
/**
* @param DateTimeInterface $date
*/
public function setDate(DateTimeInterface $date)
{
$this->date = $date;
}
/**
* @param int $num
*/
public function setNum($num)
{
$this->num = $num;
}
setNum
is correct, but setDate
gets generated missing the type hint on the parameter:
/**
* @param DateTimeInterface $date
*/
public function setDate($date)
{
$this->date = $date;
}
Upvotes: 7
Views: 4341
Reputation: 80
I found @Pier's solution so useful that I updated his template to generate setters with both type hinting AND optional type casting. Hope this helps someone else.
Given:
class CodeGenerationTest
{
/**
* @var \DateTime
*/
private $date;
/**
* @var int
*/
private $id;
/**
* @var string|null
*/
private $notes;
}
Will generate:
/**
* @param \DateTime $date
*/
public function setDate(\DateTime $date)
{
$this->date = $date;
}
/**
* @param int $id
*/
public function setId($id)
{
$this->id = (int)$id;
}
/**
* @param null|string $notes
*/
public function setNotes($notes)
{
$this->notes = is_null($notes) ? null : (string)$notes;
}
Here's the code template to copy/paste into PHPStorm under:
Settings > Editor > File and Code Templates > Code > PHP Setter Method
#set($typeHintText = "$TYPE_HINT ")
## First we check against a blacklist of primitive and other common types used in documentation.
#set($nonTypeHintableTypes = ["", "string", "int", "integer", "mixed", "number", "void", "object", "real", "double", "float", "resource", "null", "bool", "boolean"])
#foreach($nonTypeHintableType in $nonTypeHintableTypes)
#if ($nonTypeHintableType == $TYPE_HINT)
#set($typeHintText = "")
#end
#end
## Make sure the type hint actually looks like a legal php class name(permitting namespaces too) for future proofing reasons.
## This is important because PSR-5 is coming soon, and will allow documentation of types with syntax like SplStack<int>
#if (!$TYPE_HINT.matches('^((\\)?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]+)+$'))
#set($typeHintText = "")
#end
## Next, we check if this is using the array syntax like "MyClass[]", and type hint it as a plain array
#if ($TYPE_HINT.endsWith("[]"))
#set($typeHintText = "array ")
#end
## Set this or self
#set($thisOrSelf = "$this->")
#if (${STATIC} == "static")
#set($thisOrSelf = "self::$")
#end
## Type cast incoming variable that can also be null, using the ternary operator
#set($ternaryCast = "")
#if ($TYPE_HINT.contains('null|') || $TYPE_HINT.contains('|null'))
#set($ternaryCast = "is_null($${PARAM_NAME}) ? null : ")
#end
## Type cast incoming variable
#set($cast = " ")
#if ($TYPE_HINT.contains('string'))
#set($cast = "(string) ")
#elseif ($TYPE_HINT.contains('object'))
#set($cast = "(object) ")
#elseif ($TYPE_HINT.contains('int'))
#set($cast = "(int) ")
#elseif ($TYPE_HINT.contains('bool'))
#set($cast = "(bool) ")
#elseif ($TYPE_HINT.contains('float') || $TYPE_HINT.contains('double') || $TYPE_HINT.contains('real'))
#set($cast = "(float) ")
#end
/**
* @param ${TYPE_HINT} $${PARAM_NAME}
*/
public ${STATIC} function set${NAME}($typeHintText$${PARAM_NAME})
{
$thisOrSelf${FIELD_NAME} = $ternaryCast$cast$${PARAM_NAME};
}
Upvotes: 4
Reputation: 5235
You need to change the template of your PHP Setter Method in PhpStorm to specify the type hint.
Open PhpStorm's Preferences and "File and Code Templates" menu, under the "Code" tab there's an option called "PHP Setter Method". Modify it to look like this:
#set($typeHintText = "$TYPE_HINT ")
## First we check against a blacklist of primitive and other common types used in documentation.
#set($nonTypeHintableTypes = ["", "string", "int", "mixed", "number", "void", "object", "real", "double", "float", "resource", "null", "bool", "boolean"])
#foreach($nonTypeHintableType in $nonTypeHintableTypes)
#if ($nonTypeHintableType == $TYPE_HINT)
#set($typeHintText = "")
#end
#end
## Make sure the type hint actually looks like a legal php class name(permitting namespaces too) for future proofing reasons.
## This is important because PSR-5 is coming soon, and will allow documentation of types with syntax like SplStack<int>
#if (!$TYPE_HINT.matches('^((\\)?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]+)+$'))
#set($typeHintText = "")
#end
## Next, we check if this is using the array syntax like "MyClass[]", and type hint it as a plain array
#if ($TYPE_HINT.endsWith("[]"))
#set($typeHintText = "array ")
#end
/**
* @param ${TYPE_HINT} $${PARAM_NAME}
*/
public ${STATIC} function set${NAME}($typeHintText$${PARAM_NAME})
{
#if (${STATIC} == "static")
self::$${FIELD_NAME} = $${PARAM_NAME};
#else
$this->${FIELD_NAME} = $${PARAM_NAME};
#end
}
Actually, since the php primitive list is actually short, it's possible to detect if it's a primitive type or not.
So:
class CodeGenerationTest {
/**
* @var DateTimeInterface
*/
private $date;
/**
* @var int
*/
private $num;
}
Would actually generates this:
/**
* @var \DateTimeInterface $date
*/
public function setDate(\DateTimeInterface $date)
{
$this->date = $date;
}
/**
* @var int $num
*/
public function setNum($num)
{
$this->num = $num;
}
You can find help about templates variables here: https://www.jetbrains.com/phpstorm/webhelp/file-template-variables.html
Upvotes: 21