Skip to content

Conversation

tiesmaster
Copy link
Contributor

@tiesmaster tiesmaster commented Apr 16, 2017

As discussed a PR to fix #19 for me. This recognises params object[] parameters in a call to the logger, and takes that into account.

A couple things to note:

  • I put in an unit test for specifically reproducing this scenario. I first tried to reproduce it on the Serilog logger, however, I found out that it doesn't fail there, since the params object[] also starts with "propertyValue" (so it actually works correctly for Serilog!). This way I was able to reproduce it for me.

  • I thought there was an easy check, or extension method for checking on params object[] parameters, but I couldn't find it. I did find this SO answer for verifying the type, but I'm not 100% sure if this is the right approach. We can also just go with parameter.IsParams && parameter.Type.Kind == SymbolKind.ArrayType, or even just parameter.IsParams.

Copy link
Owner

@Suchiman Suchiman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think going with just parameter.IsParams would be fine. params requires an array type (currently, i think i've seen a proposal to allow IEnumerable as well) but the point is, that params allows a variable amount of parameters to be supplied so i don't think we should enforce a specific type, maybe someone wants to require params string[] values for some reason.

{
int id = 1;
IMyLogger log;
log.Error(""The id is {Id}"", id);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

log is being used uninitialized, should be at least null initialized

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I'll fix that.

var location = argument.GetLocation().SourceSpan;
arguments.Add(new SourceArgument { StartIndex = location.Start, Length = location.Length });
}
else if (parameter.IsParams && IsObjectArray(parameter))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bodies seem identical to me, should just be an || condition?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll fix this, if we don't go with the less strict approach (which would fix that anyhow).

@Suchiman
Copy link
Owner

Further thinking about the issue, my original intent behind this part of the code was to prevent confusing message template arguments with any other argument.

Unfortunately, the MessageTemplateFormatMethodAttribute only specifies the template, not the arguments, so i went loosely with the convention (propertyValue) found in the serilog codebase.

An alternative approach would be to use anything following the messageTemplate argument or to require the propertyValue pattern.

For example, if you would be to implement new methods that prevent the array allocation in case the LogLevel isn't enabled (which is an optimization, serilog does) and you would be using ..., T1 value1, T2 value2), it would break again, since it expects propertyValue*

@nblumhardt
Copy link
Contributor

Not sure if this helps, but when a message template is used, at least in all of the current libraries, it'd be fair to assume that any arguments to the right of it are either a params object[] or a sequence of positional values, regardless of their argument names or types. Those are the only kinds of methods the analysis can really help with, anyway.

In Serilog, and hopefully elsewhere, "special" arguments like Exception or Level are always to the left of the message template.

@tiesmaster
Copy link
Contributor Author

When I was working on the issue, I was already in doubt if a strict approach makes sense. Also hearing Nicholas' feedback, I'm quite certain that going with "everything after the messageTemplate" is the best approach.

@Suchiman Do you agree? Shall I'll update the PR with that?

@Suchiman
Copy link
Owner

@tiesmaster Yes, that's fine with me

fixes compiler error on analyzer input test code.
by treating all parameters after the template message parameter as arguments for the template, which is the most widely used approach people use for method signatures with message templates.
@tiesmaster
Copy link
Contributor Author

@Suchiman I've updated the PR, as discussed. Can you have another look at it?

@Suchiman
Copy link
Owner

Looking good!
Thank you for your Contribution

@Suchiman Suchiman merged commit 1568eaa into Suchiman:master Apr 17, 2017
@tiesmaster tiesmaster deleted the issue19 branch April 17, 2017 22:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Serilog003 gives false positive on my custom abstraction
3 participants