-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Status bits rationalization .... #917
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Starting build on |
|
Build failed on slc6/gcc62. Failing tests: |
|
Build failed on mac1012/native. Failing tests: |
|
Build failed on ubuntu14/native. Failing tests: |
|
Build failed on centos7/gcc49. Failing tests: |
|
Build failed on slc6/gcc49. Failing tests: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only tiny comments - plus I don't think this really addresses the problem but any alternative is too expensive... LGTM after addressing the test failure.
| enum EStatusBits { | ||
| kClassSaved = BIT(12), | ||
| kIgnoreTObjectStreamer = BIT(15), | ||
| kUnloaded = BIT(16), // The library containing the dictionary for this class was |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As you're touching this anyway, can you use pre-member doxygen doc like so:
/// The library containing the dictionary for this class was
/// loaded and has been unloaded from memory.
kUnloaded = BIT(16),
This makes it easier to read and write precise documentation and enables doxygen to actually pick it up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The annoying part is that (visually at the very least), unless there is a empy line above the comment, I never 'know' whether the comment applies to the one before or after.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But we're paid by lines of code, so adding empty lines is a wonderful thing! ;-)
| kStartWithTObject = BIT(20), // see comments for IsStartingWithTObject() | ||
| kWarned = BIT(21), | ||
| kHasNameMapNode = BIT(22), | ||
| kHasCustomStreamerMember = BIT(23) // The class has a Streamer method and it is implemented by the user or an older (not StreamerInfo based) automatic streamer. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above
| kWarn = BIT(14) | ||
| }; | ||
|
|
||
| enum EStatusBitsOldValues { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you document why you have this?
| kWarn = BIT(14) | ||
| }; | ||
|
|
||
| enum EStatusBitsOldValues { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto.
| #include "TStatusBitsChecker.h" | ||
|
|
||
| #include "TClass.h" | ||
| #include "TBaseClass.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The order is "almost-alphabetical" ;-)
core/meta/src/TStatusBitsChecker.cxx
Outdated
|
|
||
| void TStatusBitsChecker::Registry::RegisterBits(TClass &classRef /* = false */) | ||
| { | ||
| TEnum *eStatusBits = (TEnum*)classRef.GetListOfEnums()->FindObject("EStatusBits"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the name is different (as in many examples in ROOT before your patch)?
Isn't the relevant criterium that SetBit() is called on such an enum constant? That would mean we need an external tool looking at invocations...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't the relevant criterium that SetBit() is called on such an enum constant? That would
mean we need an external tool looking at invocations...
Yes and it would technically have to parse the entire world's sources to find out. Doing so with the ROOT source would be a good start though :) .... Anyway, this way is 'much' cheaper (for me) to write (it would also have to deal with indirect setting and combinations SetBit(aliasOne | aliasTwo))
As importantly, having this enum clearly name helps with documentation ... (i.e if one was to write the parsing tool, it could complain that a bit is not listed in EStatusBits)
Lastly writing the EStatusBitsDupExceptions or equivalent would still be necessary in some cases ...
core/meta/src/TStatusBitsChecker.cxx
Outdated
| if (eStatusBits) { | ||
|
|
||
| for(auto c : *eStatusBits->GetConstants()) { | ||
| TEnumConstant *constant = dynamic_cast<TEnumConstant*>(c); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Coverity will be unhappy with you :-) What if the dyn_cast fails?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can't :) the 'original' version of the code was
TEnumConstant *constant = (TEnumConstant*)(c);
core/meta/src/TStatusBitsChecker.cxx
Outdated
|
|
||
| } | ||
|
|
||
| // Return false if there is any unexpected duplicates BIT constant in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why isn't this a proper doxygen comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does doxygen do with this lame comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
humm ... actually what is our current strategy ... the official documentation is in the header files. Should we leave the source file completely undocumented?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ROOT's function doc is in the sources.
core/meta/src/TStatusBitsChecker.cxx
Outdated
| return Registry().Check(classRef,verbose); | ||
| } | ||
|
|
||
| // Return false if there is any unexpected duplicates BIT constant in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doxygen?
core/meta/src/TStatusBitsChecker.cxx
Outdated
| { | ||
| bool result = true; | ||
|
|
||
| // start from begining |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
speling.
|
Could you add a gtest for this new feature? |
|
Starting build on |
|
Starting build on |
|
Build failed on ubuntu14/native. Failing tests: |
|
Build failed on mac1012/native. Failing tests: |
|
Build failed on slc6/gcc49. Failing tests: |
|
Build failed on centos7/gcc49. Failing tests: |
|
Build failed on slc6/gcc62. Failing tests: |
This allows for automatic checking overlaps in a given class hierarchy.
The value conflicted with TBranch::kBranchObject.
The value conflicted with TLeaf::kNewValue.
It was conflicting with TApplication::kDefaultApplication. This are used transiently so no backward compatibility issues
…hough they should have been)
It was conflicting with TObject::kCanDelete. Even-though it is persistent information, it is only ever used when first creating the branch and thus changing the value should have not practical down-side.
…reamerInfo This specially named Enum will allow to annotate the EStatusBits enum to list the bit that are intentionally/knowingly duplicated other bits in the clas hierarchy
TStatusBitsChecker::Check and TStatusBitsChecker::CheckAllClasses will
determine if the set of "status bit" declared in the class and its
base classes presents any overlap. The status bit are declared in
a given class by declaring an enum type named EStatusBits.
If some of the duplication is intentional, those duplication can
be registered in an enum type named EStatusBitsDupExceptions.
~~~ {.cpp}
// TStreamerElement status bits
enum EStatusBits {
kHasRange = BIT(6),
kCache = BIT(9),
kRepeat = BIT(10),
kRead = BIT(11),
kWrite = BIT(12),
kDoNotDelete = BIT(13),
kWholeObject = BIT(14)
};
enum class EStatusBitsDupExceptions {
// This bit duplicates TObject::kInvalidObject. As the semantic of kDoNotDelete is a persistent,
// we can not change its value without breaking forward compatibility.
// Furthermore, TObject::kInvalidObject and its semantic is not (and should not be)
// used in TStreamerElement
kDoNotDelete = TStreamerElement::kDoNotDelete,
// This bit duplicates TObject::kCannotPick. As the semantic of kHasRange is a persistent,
// we can not change its value without breaking forward compatibility.
// Furthermore, TObject::kCannotPick and its semantic is not (and should not be)
// used in TStreamerElement
kHasRange = TStreamerElement::kHasRange
};
~~~ {.cpp}
Without the EStatusBitsDupExceptions enum you would see
~~~ {.cpp}
TStatusBitsChecker::Check("TStreamerElement");
Error in <TStatusBitsChecker>: In TStreamerElement class hierarchy, there are duplicates bits:
Error in <TStatusBitsChecker>: Bit 6 used in TStreamerElement as kHasRange
Error in <TStatusBitsChecker>: Bit 6 used in TObject as kCannotPick
Error in <TStatusBitsChecker>: Bit 13 used in TStreamerElement as kDoNotDelete
Error in <TStatusBitsChecker>: Bit 13 used in TObject as kInvalidObject
~~~ {.cpp}
frexp ultimately give the same information (what power of 2 is this number) but is 3 times faster than the pair (log2, nearbyint).
…ubmerger. Error in <TStatusBitsChecker>: In TProofPlayer class hierarchy, there are duplicates bits: Error in <TStatusBitsChecker>: Bit 16 used in TProofPlayer as kIsProcessing Error in <TStatusBitsChecker>: Bit 16 used in TVirtualProofPlayer as kIsSubmerger Error in <TStatusBitsChecker>: In TProofServ class hierarchy, there are duplicates bits: Error in <TStatusBitsChecker>: Bit 16 used in TProofServ as kHighMemory Error in <TStatusBitsChecker>: Bit 16 used in TApplication as kDefaultApplication
|
Starting build on |
|
Starting build on |
|
Build failed on centos7/gcc49. Failing tests: |
|
Build failed on ubuntu14/native. Failing tests: |
|
Build failed on mac1012/native. Failing tests: |
|
Build failed on slc6/gcc62. Failing tests: |
|
Build failed on slc6/gcc49. Failing tests: |
This introduces TStatusBitsChecker which allows to check whether there is 'Status bits' overlap in a given class hierarchy.
Expectedly, there are several overlaps ....
This merge request also annotate (by properly naming the enum type as EStatusBits) as needed and resolves the reported errors in core, io/io, tree/tree and hist/hist.
Some overlaps can not be resolve to preserve forward compatibility and after analysis of which bit is overlapping should be 'harmless' and thus are marked to be ignored by the checker tools (by adding a enum type named EStatusBitsDupExceptions).
Usage example: