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
Fix type name resolution and implement short form properties in COM collector. #4189
Conversation
…ollection changes." This reverts commit 290e7e2.
Codecov Report
@@ Coverage Diff @@
## next #4189 +/- ##
==========================================
- Coverage 52.46% 52.24% -0.23%
==========================================
Files 967 967
Lines 33269 33411 +142
==========================================
- Hits 17454 17453 -1
- Misses 15815 15958 +143
|
case VarEnum.VT_SAFEARRAY: | ||
case VarEnum.VT_CARRAY: | ||
case VarEnum.VT_ARRAY: | ||
tdesc = (TYPEDESC)Marshal.PtrToStructure(desc.lpValue, typeof(TYPEDESC)); |
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 not use Marshal.PtrToStructure<>
instead of non-generic form and avoid the cast?
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.
Copy paste. :-) These are all over the place, and I think it was because RD used to target 4.5. One of these days I'll find them all clean them up, but this at least keeps the usage fairly consistent.
Debug.Assert(length == 1); | ||
|
||
_properties.Add(new ComField(info, names[0], property, index, DeclarationType.Property)); | ||
info.ReleaseVarDesc(varDescPtr); |
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.
if an exception is thrown before we get here, we'd have leaked a pointer, no? Maybe put in a try
/finally
? (or look at Max's DisposalActionContainer
class for encapsulating dispose pattern on non-disposable objects.
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.
@bclothier Good catch. Do we have a preference between try
/ finally
and a set of wrapped IntPtr
s that implement IDisposable
? I personally find using
blocks easier to read, but can go either way on it.
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.
NVM, using
also makes it clearer that the intent is for errors to be caught further down the stack.
@@ -23,6 +24,8 @@ public class ComModule : ComType, IComTypeWithMembers, IComTypeWithFields | |||
private readonly List<ComField> _fields = new List<ComField>(); | |||
public IEnumerable<ComField> Fields => _fields; | |||
|
|||
public IEnumerable<ComField> Properties => Enumerable.Empty<ComField>(); |
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.
This feels wrong. Expression is OK for read-only properties but for writable properties, any writes would get lost, I think. Should be just a ordinary auto-property with Enumerable.Empty
assigned at construction, I think.
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.
Properties
is read-only. The inheritance and interface structure in this namespace could probably use some work eventually, but in this case I put it on the IComTypeWithMembers
interface because at this point I don't have any evidence that these are prohibited on Modules other than never having seen any. If I can conclusively determine from the MIDL spec that they'll never be there, I'll probably rearrange this.
continue; | ||
} | ||
|
||
if (item.IsReferenceType) |
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 about the unusual case where one has implemented all three forms of properties? Not sure if the long forms will get called into this method but if it does, then that if/else probably need to be rethought.
If the method is meant to deal only with the short form in where we can't specify the 3 types, then probably need a comment to call out the assumption here.
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.
This is impossible. The short form declaration is basically the same as a public field, so in it's native form there isn't a set of accessors - only a read-only flag. The way they are used by the consumer is language specific. This may require more testing as to how the VB compiler handles them, but I can't make that determination until I find one that is actually a reference type.
WIP'd the PR to address potentially leaked pointers. |
…clothier). Addresses possible pointer leaks.
Addressed potential leaky pointers, no longer WIP. Props to @MDoerner - the |
I know this is already merged but there is one more consideration... From the specs, we see that:
It might be that the.NET implementation will throw exception in such cases but I would rather not assume. Therefore, before entering the |
@bclothier - This line specifies the interface contract:
If no such member exists (and
In that case, it returns |
Closes #3326
Partially addresses #4096
IMPORTANT: This PR does not update the serialized declarations used by the unit tests. At some point these apparently became stale, so 34 tests are failing with the new declarations. I will PR the new declarations when #4182 is resolved.
@future: If you make any changes that effect the behavior of the COM collection, you HAVE TO update the serialized declarations files for the unit tests. If you don't, it basically invalidates the tests and potentially masks bugs.