I have a number of files in PhpStorm that have one warning in them and I went that green tick! They are all from using BLOB which of course makes sense as load() is not a function set out in my project. Its a base php function from OCI-Lob.
Line of code is:
$zip->addFromString($result['FILE_NAME'], $result['FILE_BLOB']->load());
I have tried adding #var and #method comments (maybe not correctly) in various combinations such as:
/** #var $result['FILE_BLOB'] load */
I do not want to turn off this check project wide of course as its very useful everywhere else. I just want to suppress it for just this line or even better point it in the right direction somehow. It is annoying to have lots of yellow blocks instead of ticks. Maybe I am just fussy about this as the program is obviously unaffected. Does anyone know of any solution or workaround?
You could reference the blob in a separate variable and then put a hint on that variable:
/** #var OCI_Lob $fileBlob */
$fileBlob = $result['FILE_BLOB'];
$zip->addFromString($result['FILE_NAME'], $fileBlob->load());
Since $result['FILE_BLOB'] is an object it will be assigned by reference, so this should not cause a significant increase of your script's memory usage.
An other option would be to hint the whole results array as an array of OCI_Lob objects. Not pretty, but it will probably solve your code inspection issues as well:
/** #var OCI_Lob[] $result */
$zip->addFromString($result['FILE_NAME'], $result['FILE_BLOB']->load());
As far as I know it's not possible (yet) to hint specific array keys in PHPDoc comments, so this is the best I can come up with at the moment.
Related
I'm trying to follow Zend coding standard for comments blocks for functions and I've stuck during PHP Function Doc Commentcustomization.
This is my current code look
/**
${PARAM_DOC}
#if(${PARAM_DOC})
*
#end
* #return ${TYPE_HINT}
${THROWS_DOC}
*/
The assumption for this is that it should add an asterisk only if ${PARAM_DOC} is not nullable, but this code doesn't work. It always adds an asterisk. The documentation of PhpStorm Variables doesn't contain any useful informations for my problem so I hope that somebody here can help me.
My PhpStorm version is 2019.3 EAP.
As the build-in PhpStorm for ${PARAM_DOC} description says
Parameters' doc comment.
Generated as a number of lines '* #param type name". If there are no parameters, evaluates to an empty content.
And Apache Velocity docs says
When VTL references a variable, such as $foo, the variable can get its value from either a set directive in the template, or from the Java code.
After that I understood that I'm making one important mistake. PhpStorm is based on Java and an empty String cant be automatically casted to Boolean beacuse ${PARAM_DOC} is just a Java String.
So solution for that turned out to be
#if (${PARAM_DOC} != "")
*
#end
Obvious but not quiet.
So if I have a function and in the PHPDoc I specify it'll return a SqsProcessResult object, then I call a function to create a new one of those objects but that function's PHPDoc say return type of Object (as it's a generic factory function) PhpStorm throws up an orange warning.
Can I annotate or otherwise tell PhpStorm the return type will be SqsProcessResult?
Yes, you can .. but due to the nature of the issue it may not be cleanest/elegant solution (at least that's what others may say).
Few options:
#1. Just suppress this inspection for that line.
Place caret in the highlighted area and press Alt + Enter (or get the same menu via "light bulb" icon)
Find the most suitable entry .. and press Arrow Right key (or mouse click on the tiny triangle icon) to expand submenu
Once there -- choose Suppress for statement option -- a new inline PHPDoc comment will be added just above tat line that instructs PhpStorm to ignore that specific Inspection in the next line.
Will be something like this:
/** #noinspection PhpIncompatibleReturnTypeInspection */
return \Yii::createObject(...);
Pros: no warning from IDE side
Cons: extra PHPDoc comment to satisfy IDE (which is needed considering the circumstances)
#2. Use some intermediate variable that you can type hint in place.
Add something like this instead of that existing single line:
/** #var SqsProcessResult $res */
$res = \Yii::createObject(...);
return $res;
Pros: no suppression comment
Cons: extra variable (and still extra PHPDoc comment) for basically no reason
This one mainly can be used in longer methods where such variable (generic Object) will be created in the beginning/middle of the function body and then used later.
#3. Play with .metadata functionality and provide resolution logic for actual \Yii::createObject() (so IDE chooses the right class based on input parameter).
https://confluence.jetbrains.com/display/PhpStorm/PhpStorm+Advanced+Metadata
This is how quite a few tools working: IDE helper for Laravel, Symfony helpers, DI Container helpers etc
In my code I use Registry pattern like that:
$data = Registry::get('classA')->methodOfClassA($param1, param2);
Registry class stores instances of some classes in internal array, so in any place of my code I can call class methods for handy functions like in line above.
But, the problem is that PHP-storm does not autocomplete when I type:
Registry::get('classA')->
And, that is worse, it does not go to declaration of the method "methodOfClassA" when I hover mouse cursor holding mac-button (analogue of control-button on windows)
I suppose, that IDE AI is not so good to recognise cases like that, but maybe there is some tricks to do that in a hard way? hardcoding classes+method names in some file and so on...
At least, I want it to understand to go to method declaration when I click method name...
Any advices?
http://confluence.jetbrains.com/display/PhpStorm/PhpStorm+Advanced+Metadata
This link describes it all -- it is already used by multiple projects/frameworks/code-generation helpers, like Magento, for example (some other can be found mentioned in the comments of the actual ticket).
For other situations you may want to check out DynamicReturnTypePlugin plugin (Settings | Plugins | Browse repositories...) -- have not tried myself and therefore cannot comment how good/fast/laggy it is.
You can always indicate the variable type in two steps:
/** #var $foo MyClass */
$foo = $this->get('MyClass');
$foo->bar(); // autocomplete works
I have to decide whether to put a variable within a constructor or outside, but I keep getting the feeling that I am missing information, I have looked at other posts on stack overflow, but all mentioned it was a matter of preference, yet I found two difference that I feel might be important:
-If I decide to put the variables within a constructor, then I must have an object parameter for any function that wish to alter the variables, even if the code is internal to the class.
-Subclassing would cause the variables to not appear, something that causes problems when the class and any subclasses must have the variables in order to operate properly.
I may be wrong on all of these points, but at 4am, I would rather be told I am wrong than commit a mistake due to pride. If this has been answered somewhere else and I missed it, I am sorry, and if you could post the link, I would be grateful.
actions inside the constructor are interpreted, all others are precompiled so they work faster
Like www0z0k already said, the declarations outside the constructor are merly interpreted, so declaring them outside can be a performance bost under some circumstances.
-If I decide to put the variables within a constructor, then I must have an object parameter for any function that wish to alter the variables, even if the code is internal to the class.
This is correct.
-Subclassing would cause the variables to not appear, something that causes problems when the class and any subclasses must have the variables in order to operate properly.
You should think about what you want to archive. Most times you should rather choose a good software design then to think about performance. This subclassing problem that you mentioned can also protect some variables from being changed.
Greetings,
iuiz
-Subclassing would cause the variables to not appear, something that causes
problems when the class and any
subclasses must have the variables in
order to operate properly.
If I understood you correctly you're looking for protected fields (or properties).
-If I decide to put the variables within a constructor, then I must have
an object parameter for any function
that wish to alter the variables, even
if the code is internal to the class.
Sry, I don't get that...
#Performance: with all that said about interpreted constructors you could add a simple init(...) function within your constructor which does all you would do in the constructor - but without being interpreted.
public function ConstructorOfClass(arg1:int, arg2:*)
{
init(arg1, arg2);
}
private function init(arg1:int, arg2:*):void
{
// do whatever you want here
}
Do you often see in API documentation (as in 'javadoc of public functions' for example) the description of "value limits" as well as the classic documentation ?
Note: I am not talking about comments within the code
By "value limits", I mean:
does a parameter can support a null value (or an empty String, or...) ?
does a 'return value' can be null or is guaranteed to never be null (or can be "empty", or...) ?
Sample:
What I often see (without having access to source code) is:
/**
* Get all readers name for this current Report. <br />
* <b>Warning</b>The Report must have been published first.
* #param aReaderNameRegexp filter in order to return only reader matching the regexp
* #return array of reader names
*/
String[] getReaderNames(final String aReaderNameRegexp);
What I like to see would be:
/**
* Get all readers name for this current Report. <br />
* <b>Warning</b>The Report must have been published first.
* #param aReaderNameRegexp filter in order to return only reader matching the regexp
* (can be null or empty)
* #return array of reader names
* (null if Report has not yet been published,
* empty array if no reader match criteria,
* reader names array matching regexp, or all readers if regexp is null or empty)
*/
String[] getReaderNames(final String aReaderNameRegexp);
My point is:
When I use a library with a getReaderNames() function in it, I often do not even need to read the API documentation to guess what it does. But I need to be sure how to use it.
My only concern when I want to use this function is: what should I expect in term of parameters and return values ? That is all I need to know to safely setup my parameters and safely test the return value, yet I almost never see that kind of information in API documentation...
Edit:
This can influence the usage or not for checked or unchecked exceptions.
What do you think ? value limits and API, do they belong together or not ?
I think they can belong together but don't necessarily have to belong together. In your scenario, it seems like it makes sense that the limits are documented in such a way that they appear in the generated API documentation and intellisense (if the language/IDE support it).
I think it does depend on the language as well. For example, Ada has a native data type that is a "restricted integer", where you define an integer variable and explicitly indicate that it will only (and always) be within a certain numeric range. In that case, the datatype itself indicates the restriction. It should still be visible and discoverable through the API documentation and intellisense, but wouldn't be something that a developer has to specify in the comments.
However, languages like Java and C# don't have this type of restricted integer, so the developer would have to specify it in the comments if it were information that should become part of the public documentation.
I think those kinds of boundary conditions most definitely belong in the API. However, I would (and often do) go a step further and indicate WHAT those null values mean. Either I indicate it will throw an exception, or I explain what the expected results are when the boundary value is passed in.
It's hard to remember to always do this, but it's a good thing for users of your class. It's also difficult to maintain it if the contract the method presents changes (like null values are changed to no be allowed)... you have to be diligent also to update the docs when you change the semantics of the method.
Question 1
Do you often see in API documentation (as in 'javadoc of public functions' for example) the description of "value limits" as well as the classic documentation?
Almost never.
Question 2
My only concern when I want to use this function is: what should I expect in term of parameters and return values ? That is all I need to know to safely setup my parameters and safely test the return value, yet I almost never see that kind of information in API documentation...
If I used a function not properly I would expect a RuntimeException thrown by the method or a RuntimeException in another (sometimes very far) part of the program.
Comments like #param aReaderNameRegexp filter in order to ... (can be null or empty) seems to me a way to implement Design by Contract in a human-being language inside Javadoc.
Using Javadoc to enforce Design by Contract was used by iContract, now resurrected into JcontractS, that let you specify invariants, preconditions, postconditions, in more formalized way compared to the human-being language.
Question 3
This can influence the usage or not for checked or unchecked exceptions.
What do you think ? value limits and API, do they belong together or not ?
Java language doesn't have a Design by Contract feature, so you might be tempted to use Execption but I agree with you about the fact that you have to be aware about When to choose checked and unchecked exceptions. Probably you might use unchecked IllegalArgumentException, IllegalStateException, or you might use unit testing, but the major problem is how to communicate to other programmers that such code is about Design By Contract and should be considered as a contract before changing it too lightly.
I think they do, and have always placed comments in the header files (c++) arcordingly.
In addition to valid input/output/return comments, I also note which exceptions are likly to be thrown by the function (since I often want to use the return value for...well returning a value, I prefer exceptions over error codes)
//File:
// Should be a path to the teexture file to load, if it is not a full path (eg "c:\example.png") it will attempt to find the file usign the paths provided by the DataSearchPath list
//Return: The pointer to a Texture instance is returned, in the event of an error, an exception is thrown. When you are finished with the texture you chould call the Free() method.
//Exceptions:
//except::FileNotFound
//except::InvalidFile
//except::InvalidParams
//except::CreationFailed
Texture *GetTexture(const std::string &File);
#Fire Lancer: Right! I forgot about exception, but I would like to see them mentioned, especially the unchecked 'runtime' exception that this public method could throw
#Mike Stone:
you have to be diligent also to update the docs when you change the semantics of the method.
Mmmm I sure hope that the public API documentation is at the very least updated whenever a change -- that affects the contract of the function -- takes place. If not, those API documentations could be drop altogether.
To add food to yours thoughts (and go with #Scott Dorman), I just stumble upon the future of java7 annotations
What does that means ? That certain 'boundary conditions', rather than being in the documentation, should be better off in the API itself, and automatically used, at compilation time, with appropriate 'assert' generated code.
That way, if a '#CheckForNull' is in the API, the writer of the function might get away with not even documenting it! And if the semantic change, its API will reflect that change (like 'no more #CheckForNull' for instance)
That kind of approach suggests that documentation, for 'boundary conditions', is an extra bonus rather than a mandatory practice.
However, that does not cover the special values of the return object of a function. For that, a complete documentation is still needed.