- [CanBeNull] public object Test() { return null; }
- public void UseTest() {
+ [CanBeNull] object Test() => null;
+
+ void UseTest() {
var p = Test();
var s = p.ToString(); // Warning: Possible 'System.NullReferenceException'
}
@@ -19,24 +20,39 @@
- [NotNull] public object Foo() {
+ [NotNull] object Foo() {
return null; // Warning: Possible 'null' assignment
}
[StringFormatMethod("message")]
- public void ShowError(string message, params object[] args) { /* do something */ }
- public void Foo() {
+ void ShowError(string message, params object[] args) { /* do something */ }
+
+ void Foo() {
ShowError("Failed: {0}"); // Warning: Non-existing argument in format string
}
- public void Foo(string param) {
+ void Foo(string param) {
if (param == null)
throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol
}
@@ -62,8 +84,8 @@
Indicates that the method is contained in a type that implements
- interface
- and this method is used to notify that some property value changed
+ System.ComponentModel.INotifyPropertyChanged interface and this method
+ is used to notify that some property value changed.
The method should be non-static and conform to one of the supported signatures:
@@ -76,12 +98,14 @@
- internal class Foo : INotifyPropertyChanged {
+ public class Foo : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
+
[NotifyPropertyChangedInvocator]
protected virtual void NotifyChanged(string propertyName) { ... }
- private string _name;
+ string _name;
+
public string Name {
get { return _name; }
set { _name = value; NotifyChanged("LastName"); /* Warning */ }
@@ -99,7 +123,7 @@
- Describes dependency between method input and output
+ Describes dependency between method input and output.
Function Definition Table syntax:
@@ -111,15 +135,16 @@
- Value ::= true | false | null | notnull | canbenull
If method has single input parameter, it's name could be omitted.
- Using halt (or void /nothing , which is the same)
- for method output means that the methos doesn't return normally.
- canbenull annotation is only applicable for output parameters.
- You can use multiple [ContractAnnotation] for each FDT row,
- or use single attribute with rows separated by semicolon.
+ Using halt (or void /nothing , which is the same) for method output
+ means that the methods doesn't return normally (throws or terminates the process).
+ Value canbenull is only applicable for output parameters.
+ You can use multiple [ContractAnnotation] for each FDT row, or use single attribute
+ with rows separated by semicolon. There is no notion of order rows, all rows are checked
+ for applicability and applied per each program state tracked by R# analysis.
- [ContractAnnotation("=> halt")]
+ [ContractAnnotation("=> halt")]
public void TerminationMethod()
@@ -127,28 +152,29 @@
public void Assert(bool condition, string text) // regular assertion method
- [ContractAnnotation("s:null => true")]
+ [ContractAnnotation("s:null => true")]
public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty()
- // A method that returns null if the parameter is null, and not null if the parameter is not null
- [ContractAnnotation("null => null; notnull => notnull")]
+ // A method that returns null if the parameter is null,
+ // and not null if the parameter is not null
+ [ContractAnnotation("null => null; notnull => notnull")]
public object Transform(object data)
- [ContractAnnotation("s:null=>false; =>true,result:notnull; =>false, result:null")]
+ [ContractAnnotation("=> true, result: notnull; => false, result: null")]
public bool TryParse(string s, out Person result)
- Indicates that marked element should be localized or not
+ Indicates that marked element should be localized or not.
[LocalizationRequiredAttribute(true)]
- internal class Foo {
- private string str = "my string"; // Warning: Localizable string
+ class Foo {
+ string str = "my string"; // Warning: Localizable string
}
@@ -162,8 +188,9 @@
[CannotApplyEqualityOperator]
class NoEquality { }
+
class UsesNoEquality {
- public void Test() {
+ void Test() {
var ca1 = new NoEquality();
var ca2 = new NoEquality();
if (ca1 != null) { // OK
@@ -180,30 +207,29 @@
[BaseTypeRequired(typeof(IComponent)] // Specify requirement
- internal class ComponentAttribute : Attribute { }
+ class ComponentAttribute : Attribute { }
+
[Component] // ComponentAttribute requires implementing IComponent interface
- internal class MyComponent : IComponent { }
+ class MyComponent : IComponent { }
- [Pure] private int Multiply(int x, int y) { return x * y; }
- public void Foo() {
- const int a = 2, b = 2;
- Multiply(a, b); // Waring: Return value of pure method is not used
+ [Pure] int Multiply(int x, int y) => x * y;
+
+ void M() {
+ Multiply(123, 42); // Waring: Return value of pure method is not used
+ }
+
+ class Foo {
+ [ProvidesContext] IBarService _barService = ...;
+
+ void ProcessNode(INode node) {
+ DoSomething(node, node.GetGlobalServices().Bar);
+ // ^ Warning: use value of '_barService' field
+ }
}
+ [SourceTemplate]
+ public static void forEach<T>(this IEnumerable<T> xs) {
+ foreach (var x in xs) {
+ //$ $END$
+ }
+ }
+
+
+ [SourceTemplate, Macro(Target = "item", Expression = "suggestVariableName()")]
+ public static void forEach<T>(this IEnumerable<T> collection) {
+ foreach (var item in collection) {
+ //$ $END$
+ }
+ }
+
+ Applying the attribute on a template method parameter:
+
+ [SourceTemplate]
+ public static void something(this Entity x, [Macro(Expression = "guid()", Editable = -1)] string newguid) {
+ /*$ var $x$Id = "$newguid$" + x.ToString();
+ x.DoSomething($x$Id); */
+ }
+
+
[ActionName("Foo")]
@@ -361,9 +489,124 @@
Razor attribute. Indicates that a parameter or a method is a Razor section.
Use this attribute for custom wrappers similar to
- System.Web.WebPages.WebPageBase.RenderSection(String)
+ System.Web.WebPages.WebPageBase.RenderSection(String) .
+ ${appsetting:item=mysetting:default=mydefault} - produces "mydefault" if no appsetting
+
+
- [CanBeNull] public object Test() { return null; }
- public void UseTest() {
- var p = Test();
- var s = p.ToString(); // Warning: Possible 'System.NullReferenceException'
- }
-
- [NotNull] public object Foo() {
- return null; // Warning: Possible 'null' assignment
- }
-
- [StringFormatMethod("message")]
- public void ShowError(string message, params object[] args) { /* do something */ }
- public void Foo() {
- ShowError("Failed: {0}"); // Warning: Non-existing argument in format string
- }
-
- public void Foo(string param) {
- if (param == null)
- throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol
- }
-
- internal class Foo : INotifyPropertyChanged {
- public event PropertyChangedEventHandler PropertyChanged;
- [NotifyPropertyChangedInvocator]
- protected virtual void NotifyChanged(string propertyName) { ... }
-
- private string _name;
- public string Name {
- get { return _name; }
- set { _name = value; NotifyChanged("LastName"); /* Warning */ }
- }
- }
-
- Examples of generated notifications:
- Function Definition Table syntax:
-
- [ContractAnnotation("=> halt")]
- public void TerminationMethod()
-
- [ContractAnnotation("halt <= condition: false")]
- public void Assert(bool condition, string text) // regular assertion method
-
- [ContractAnnotation("s:null => true")]
- public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty()
-
- // A method that returns null if the parameter is null, and not null if the parameter is not null
- [ContractAnnotation("null => null; notnull => notnull")]
- public object Transform(object data)
-
- [ContractAnnotation("s:null=>false; =>true,result:notnull; =>false, result:null")]
- public bool TryParse(string s, out Person result)
-
- [LocalizationRequiredAttribute(true)]
- internal class Foo {
- private string str = "my string"; // Warning: Localizable string
- }
-
- [CannotApplyEqualityOperator]
- class NoEquality { }
- class UsesNoEquality {
- public void Test() {
- var ca1 = new NoEquality();
- var ca2 = new NoEquality();
- if (ca1 != null) { // OK
- bool condition = ca1 == ca2; // Warning
- }
- }
- }
-
- [BaseTypeRequired(typeof(IComponent)] // Specify requirement
- internal class ComponentAttribute : Attribute { }
- [Component] // ComponentAttribute requires implementing IComponent interface
- internal class MyComponent : IComponent { }
-
- [Pure] private int Multiply(int x, int y) { return x * y; }
- public void Foo() {
- const int a = 2, b = 2;
- Multiply(a, b); // Waring: Return value of pure method is not used
- }
-
- [ActionName("Foo")]
- public ActionResult Login(string returnUrl) {
- ViewBag.ReturnUrl = Url.Action("Foo"); // OK
- return RedirectToAction("Bar"); // Error: Cannot resolve action
- }
-
- protected override Task WriteAsyncTask(LogEventInfo logEvent, CancellationToken token)
- {
- return CustomWriteAsync(logEvent, token);
- }
-
- private async Task CustomWriteAsync(LogEventInfo logEvent, CancellationToken token)
- {
- await MyLogMethodAsync(logEvent, token).ConfigureAwait(false);
- }
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- - NOTE: If your receiver application is ever likely to be off-line, don't use TCP protocol - or you'll get TCP timeouts and your application will crawl. - Either switch to UDP transport or use AsyncWrapper target - so that your application threads will not be blocked by the timing-out connection attempts. -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${basedir}/${level}.log
- All
- Caution: Enabling this option can considerably slow down your file
- logging in multi-process scenarios. If only one process is going to
- be writing to the file, consider setting
- To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- - Mail target works best when used with BufferingWrapper target - which lets you send multiple log messages in single mail -
-- To set up the buffered mail target in the configuration file, - use the following syntax: -
-
- - To set up the buffered mail target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- - To print the results, use any application that's able to receive messages over - TCP or UDP. NetCat is - a simple but very powerful command-line tool that can be used for that. This image - demonstrates the NetCat tool receiving log messages from Network target. -
-
- - NOTE: If your receiver application is ever likely to be off-line, don't use TCP protocol - or you'll get TCP timeouts and your application will be very slow. - Either switch to UDP transport or use AsyncWrapper target - so that your application threads will not be blocked by the timing-out connection attempts. -
-- There are two specialized versions of the Network target: Chainsaw - and NLogViewer which write to instances of Chainsaw log4j viewer - or NLogViewer application respectively. -
-${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- - NOTE: If your receiver application is ever likely to be off-line, don't use TCP protocol - or you'll get TCP timeouts and your application will crawl. - Either switch to UDP transport or use AsyncWrapper target - so that your application threads will not be blocked by the timing-out connection attempts. -
-${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
-
- <system.net>
- <defaultProxy enabled = "true" useDefaultCredentials = "true" >
- <proxy usesystemdefault = "True" />
- </defaultProxy>
- </system.net>
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- The example web service that works with this example is shown below
-
- - Asynchronous target wrapper allows the logger code to execute more quickly, by queueing - messages and processing them in a separate thread. You should wrap targets - that spend a non-trivial amount of time in their Write() method with asynchronous - target to speed up logging. -
-- Because asynchronous logging is quite a common scenario, NLog supports a - shorthand notation for wrapping all targets with AsyncWrapper. Just add async="true" to - the <targets/> element in the configuration file. -
-
-
- ... your targets go here ...
-
- ]]>
- - To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- This example causes the messages to be written to server1, - and if it fails, messages go to server2.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes the messages not contains the string '1' to be ignored.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- - This example works like this. If there are no Warn,Error or Fatal messages in the buffer - only Info messages are written to the file, but if there are any warnings or errors, - the output includes detailed trace (levels >= Debug). You can plug in a different type - of buffering wrapper (such as ASPNetBufferingWrapper) to achieve different - functionality. -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes the messages to be written to either file1.txt or file2.txt - chosen randomly on a per-message basis. -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes each log message to be repeated 3 times.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes each write attempt to be repeated 3 times, - sleeping 1 second between attempts if first one fails.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes the messages to be written to either file1.txt or file2.txt. - Each odd message is written to file2.txt, each even message goes to file1.txt. -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes the messages to be written to both file1.txt or file2.txt -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
-
- [CanBeNull] public object Test() { return null; }
- public void UseTest() {
- var p = Test();
- var s = p.ToString(); // Warning: Possible 'System.NullReferenceException'
- }
-
- [NotNull] public object Foo() {
- return null; // Warning: Possible 'null' assignment
- }
-
- [StringFormatMethod("message")]
- public void ShowError(string message, params object[] args) { /* do something */ }
- public void Foo() {
- ShowError("Failed: {0}"); // Warning: Non-existing argument in format string
- }
-
- public void Foo(string param) {
- if (param == null)
- throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol
- }
-
- internal class Foo : INotifyPropertyChanged {
- public event PropertyChangedEventHandler PropertyChanged;
- [NotifyPropertyChangedInvocator]
- protected virtual void NotifyChanged(string propertyName) { ... }
-
- private string _name;
- public string Name {
- get { return _name; }
- set { _name = value; NotifyChanged("LastName"); /* Warning */ }
- }
- }
-
- Examples of generated notifications:
- Function Definition Table syntax:
-
- [ContractAnnotation("=> halt")]
- public void TerminationMethod()
-
- [ContractAnnotation("halt <= condition: false")]
- public void Assert(bool condition, string text) // regular assertion method
-
- [ContractAnnotation("s:null => true")]
- public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty()
-
- // A method that returns null if the parameter is null, and not null if the parameter is not null
- [ContractAnnotation("null => null; notnull => notnull")]
- public object Transform(object data)
-
- [ContractAnnotation("s:null=>false; =>true,result:notnull; =>false, result:null")]
- public bool TryParse(string s, out Person result)
-
- [LocalizationRequiredAttribute(true)]
- internal class Foo {
- private string str = "my string"; // Warning: Localizable string
- }
-
- [CannotApplyEqualityOperator]
- class NoEquality { }
- class UsesNoEquality {
- public void Test() {
- var ca1 = new NoEquality();
- var ca2 = new NoEquality();
- if (ca1 != null) { // OK
- bool condition = ca1 == ca2; // Warning
- }
- }
- }
-
- [BaseTypeRequired(typeof(IComponent)] // Specify requirement
- internal class ComponentAttribute : Attribute { }
- [Component] // ComponentAttribute requires implementing IComponent interface
- internal class MyComponent : IComponent { }
-
- [Pure] private int Multiply(int x, int y) { return x * y; }
- public void Foo() {
- const int a = 2, b = 2;
- Multiply(a, b); // Waring: Return value of pure method is not used
- }
-
- [ActionName("Foo")]
- public ActionResult Login(string returnUrl) {
- ViewBag.ReturnUrl = Url.Action("Foo"); // OK
- return RedirectToAction("Bar"); // Error: Cannot resolve action
- }
-
- protected override Task WriteAsyncTask(LogEventInfo logEvent, CancellationToken token)
- {
- return CustomWriteAsync(logEvent, token);
- }
-
- private async Task CustomWriteAsync(LogEventInfo logEvent, CancellationToken token)
- {
- await MyLogMethodAsync(logEvent, token).ConfigureAwait(false);
- }
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- - NOTE: If your receiver application is ever likely to be off-line, don't use TCP protocol - or you'll get TCP timeouts and your application will crawl. - Either switch to UDP transport or use AsyncWrapper target - so that your application threads will not be blocked by the timing-out connection attempts. -
-
-
-
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${basedir}/${level}.log
- All
- Caution: Enabling this option can considerably slow down your file
- logging in multi-process scenarios. If only one process is going to
- be writing to the file, consider setting
- To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- - To print the results, use any application that's able to receive messages over - TCP or UDP. NetCat is - a simple but very powerful command-line tool that can be used for that. This image - demonstrates the NetCat tool receiving log messages from Network target. -
-
- - NOTE: If your receiver application is ever likely to be off-line, don't use TCP protocol - or you'll get TCP timeouts and your application will be very slow. - Either switch to UDP transport or use AsyncWrapper target - so that your application threads will not be blocked by the timing-out connection attempts. -
-- There are two specialized versions of the Network target: Chainsaw - and NLogViewer which write to instances of Chainsaw log4j viewer - or NLogViewer application respectively. -
-${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- - NOTE: If your receiver application is ever likely to be off-line, don't use TCP protocol - or you'll get TCP timeouts and your application will crawl. - Either switch to UDP transport or use AsyncWrapper target - so that your application threads will not be blocked by the timing-out connection attempts. -
-${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
-
- <system.net>
- <defaultProxy enabled = "true" useDefaultCredentials = "true" >
- <proxy usesystemdefault = "True" />
- </defaultProxy>
- </system.net>
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- The example web service that works with this example is shown below
-
- - Asynchronous target wrapper allows the logger code to execute more quickly, by queueing - messages and processing them in a separate thread. You should wrap targets - that spend a non-trivial amount of time in their Write() method with asynchronous - target to speed up logging. -
-- Because asynchronous logging is quite a common scenario, NLog supports a - shorthand notation for wrapping all targets with AsyncWrapper. Just add async="true" to - the <targets/> element in the configuration file. -
-
-
- ... your targets go here ...
-
- ]]>
- - To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- This example causes the messages to be written to server1, - and if it fails, messages go to server2.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes the messages not contains the string '1' to be ignored.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- - This example works like this. If there are no Warn,Error or Fatal messages in the buffer - only Info messages are written to the file, but if there are any warnings or errors, - the output includes detailed trace (levels >= Debug). You can plug in a different type - of buffering wrapper (such as ASPNetBufferingWrapper) to achieve different - functionality. -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes the messages to be written to either file1.txt or file2.txt - chosen randomly on a per-message basis. -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes each log message to be repeated 3 times.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes each write attempt to be repeated 3 times, - sleeping 1 second between attempts if first one fails.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes the messages to be written to either file1.txt or file2.txt. - Each odd message is written to file2.txt, each even message goes to file1.txt. -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes the messages to be written to both file1.txt or file2.txt -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
-
- [CanBeNull] public object Test() { return null; }
- public void UseTest() {
- var p = Test();
- var s = p.ToString(); // Warning: Possible 'System.NullReferenceException'
- }
-
- [NotNull] public object Foo() {
- return null; // Warning: Possible 'null' assignment
- }
-
- [StringFormatMethod("message")]
- public void ShowError(string message, params object[] args) { /* do something */ }
- public void Foo() {
- ShowError("Failed: {0}"); // Warning: Non-existing argument in format string
- }
-
- public void Foo(string param) {
- if (param == null)
- throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol
- }
-
- internal class Foo : INotifyPropertyChanged {
- public event PropertyChangedEventHandler PropertyChanged;
- [NotifyPropertyChangedInvocator]
- protected virtual void NotifyChanged(string propertyName) { ... }
-
- private string _name;
- public string Name {
- get { return _name; }
- set { _name = value; NotifyChanged("LastName"); /* Warning */ }
- }
- }
-
- Examples of generated notifications:
- Function Definition Table syntax:
-
- [ContractAnnotation("=> halt")]
- public void TerminationMethod()
-
- [ContractAnnotation("halt <= condition: false")]
- public void Assert(bool condition, string text) // regular assertion method
-
- [ContractAnnotation("s:null => true")]
- public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty()
-
- // A method that returns null if the parameter is null, and not null if the parameter is not null
- [ContractAnnotation("null => null; notnull => notnull")]
- public object Transform(object data)
-
- [ContractAnnotation("s:null=>false; =>true,result:notnull; =>false, result:null")]
- public bool TryParse(string s, out Person result)
-
- [LocalizationRequiredAttribute(true)]
- internal class Foo {
- private string str = "my string"; // Warning: Localizable string
- }
-
- [CannotApplyEqualityOperator]
- class NoEquality { }
- class UsesNoEquality {
- public void Test() {
- var ca1 = new NoEquality();
- var ca2 = new NoEquality();
- if (ca1 != null) { // OK
- bool condition = ca1 == ca2; // Warning
- }
- }
- }
-
- [BaseTypeRequired(typeof(IComponent)] // Specify requirement
- internal class ComponentAttribute : Attribute { }
- [Component] // ComponentAttribute requires implementing IComponent interface
- internal class MyComponent : IComponent { }
-
- [Pure] private int Multiply(int x, int y) { return x * y; }
- public void Foo() {
- const int a = 2, b = 2;
- Multiply(a, b); // Waring: Return value of pure method is not used
- }
-
- [ActionName("Foo")]
- public ActionResult Login(string returnUrl) {
- ViewBag.ReturnUrl = Url.Action("Foo"); // OK
- return RedirectToAction("Bar"); // Error: Cannot resolve action
- }
-
- protected override Task WriteAsyncTask(LogEventInfo logEvent, CancellationToken token)
- {
- return CustomWriteAsync(logEvent, token);
- }
-
- private async Task CustomWriteAsync(LogEventInfo logEvent, CancellationToken token)
- {
- await MyLogMethodAsync(logEvent, token).ConfigureAwait(false);
- }
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- - NOTE: If your receiver application is ever likely to be off-line, don't use TCP protocol - or you'll get TCP timeouts and your application will crawl. - Either switch to UDP transport or use AsyncWrapper target - so that your application threads will not be blocked by the timing-out connection attempts. -
-${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- | Condition | -Foreground Color | -Background Color | -
|---|---|---|
| level == LogLevel.Fatal | -Red | -NoChange | -
| level == LogLevel.Error | -Yellow | -NoChange | -
| level == LogLevel.Warn | -Magenta | -NoChange | -
| level == LogLevel.Info | -White | -NoChange | -
| level == LogLevel.Debug | -Gray | -NoChange | -
| level == LogLevel.Trace | -DarkGray | -NoChange | -
- To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
-
-
-
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${basedir}/${level}.log
- All
- Caution: Enabling this option can considerably slow down your file
- logging in multi-process scenarios. If only one process is going to
- be writing to the file, consider setting
- To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- - To print the results, use any application that's able to receive messages over - TCP or UDP. NetCat is - a simple but very powerful command-line tool that can be used for that. This image - demonstrates the NetCat tool receiving log messages from Network target. -
-
- - NOTE: If your receiver application is ever likely to be off-line, don't use TCP protocol - or you'll get TCP timeouts and your application will be very slow. - Either switch to UDP transport or use AsyncWrapper target - so that your application threads will not be blocked by the timing-out connection attempts. -
-- There are two specialized versions of the Network target: Chainsaw - and NLogViewer which write to instances of Chainsaw log4j viewer - or NLogViewer application respectively. -
-${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- - NOTE: If your receiver application is ever likely to be off-line, don't use TCP protocol - or you'll get TCP timeouts and your application will crawl. - Either switch to UDP transport or use AsyncWrapper target - so that your application threads will not be blocked by the timing-out connection attempts. -
-${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
-
- <system.net>
- <defaultProxy enabled = "true" useDefaultCredentials = "true" >
- <proxy usesystemdefault = "True" />
- </defaultProxy>
- </system.net>
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- The example web service that works with this example is shown below
-
- - Asynchronous target wrapper allows the logger code to execute more quickly, by queueing - messages and processing them in a separate thread. You should wrap targets - that spend a non-trivial amount of time in their Write() method with asynchronous - target to speed up logging. -
-- Because asynchronous logging is quite a common scenario, NLog supports a - shorthand notation for wrapping all targets with AsyncWrapper. Just add async="true" to - the <targets/> element in the configuration file. -
-
-
- ... your targets go here ...
-
- ]]>
- - To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- This example causes the messages to be written to server1, - and if it fails, messages go to server2.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes the messages not contains the string '1' to be ignored.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- - This example works like this. If there are no Warn,Error or Fatal messages in the buffer - only Info messages are written to the file, but if there are any warnings or errors, - the output includes detailed trace (levels >= Debug). You can plug in a different type - of buffering wrapper (such as ASPNetBufferingWrapper) to achieve different - functionality. -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes the messages to be written to either file1.txt or file2.txt - chosen randomly on a per-message basis. -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes each log message to be repeated 3 times.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes each write attempt to be repeated 3 times, - sleeping 1 second between attempts if first one fails.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes the messages to be written to either file1.txt or file2.txt. - Each odd message is written to file2.txt, each even message goes to file1.txt. -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes the messages to be written to both file1.txt or file2.txt -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
-
- [CanBeNull] public object Test() { return null; }
- public void UseTest() {
- var p = Test();
- var s = p.ToString(); // Warning: Possible 'System.NullReferenceException'
- }
-
- [NotNull] public object Foo() {
- return null; // Warning: Possible 'null' assignment
- }
-
- [StringFormatMethod("message")]
- public void ShowError(string message, params object[] args) { /* do something */ }
- public void Foo() {
- ShowError("Failed: {0}"); // Warning: Non-existing argument in format string
- }
-
- public void Foo(string param) {
- if (param == null)
- throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol
- }
-
- internal class Foo : INotifyPropertyChanged {
- public event PropertyChangedEventHandler PropertyChanged;
- [NotifyPropertyChangedInvocator]
- protected virtual void NotifyChanged(string propertyName) { ... }
-
- private string _name;
- public string Name {
- get { return _name; }
- set { _name = value; NotifyChanged("LastName"); /* Warning */ }
- }
- }
-
- Examples of generated notifications:
- Function Definition Table syntax:
-
- [ContractAnnotation("=> halt")]
- public void TerminationMethod()
-
- [ContractAnnotation("halt <= condition: false")]
- public void Assert(bool condition, string text) // regular assertion method
-
- [ContractAnnotation("s:null => true")]
- public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty()
-
- // A method that returns null if the parameter is null, and not null if the parameter is not null
- [ContractAnnotation("null => null; notnull => notnull")]
- public object Transform(object data)
-
- [ContractAnnotation("s:null=>false; =>true,result:notnull; =>false, result:null")]
- public bool TryParse(string s, out Person result)
-
- [LocalizationRequiredAttribute(true)]
- internal class Foo {
- private string str = "my string"; // Warning: Localizable string
- }
-
- [CannotApplyEqualityOperator]
- class NoEquality { }
- class UsesNoEquality {
- public void Test() {
- var ca1 = new NoEquality();
- var ca2 = new NoEquality();
- if (ca1 != null) { // OK
- bool condition = ca1 == ca2; // Warning
- }
- }
- }
-
- [BaseTypeRequired(typeof(IComponent)] // Specify requirement
- internal class ComponentAttribute : Attribute { }
- [Component] // ComponentAttribute requires implementing IComponent interface
- internal class MyComponent : IComponent { }
-
- [Pure] private int Multiply(int x, int y) { return x * y; }
- public void Foo() {
- const int a = 2, b = 2;
- Multiply(a, b); // Waring: Return value of pure method is not used
- }
-
- [ActionName("Foo")]
- public ActionResult Login(string returnUrl) {
- ViewBag.ReturnUrl = Url.Action("Foo"); // OK
- return RedirectToAction("Bar"); // Error: Cannot resolve action
- }
-
- protected override Task WriteAsyncTask(LogEventInfo logEvent, CancellationToken token)
- {
- return CustomWriteAsync(logEvent, token);
- }
-
- private async Task CustomWriteAsync(LogEventInfo logEvent, CancellationToken token)
- {
- await MyLogMethodAsync(logEvent, token).ConfigureAwait(false);
- }
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- - NOTE: If your receiver application is ever likely to be off-line, don't use TCP protocol - or you'll get TCP timeouts and your application will crawl. - Either switch to UDP transport or use AsyncWrapper target - so that your application threads will not be blocked by the timing-out connection attempts. -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${basedir}/${level}.log
- All
- Caution: Enabling this option can considerably slow down your file
- logging in multi-process scenarios. If only one process is going to
- be writing to the file, consider setting
- To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- - Mail target works best when used with BufferingWrapper target - which lets you send multiple log messages in single mail -
-- To set up the buffered mail target in the configuration file, - use the following syntax: -
-
- - To set up the buffered mail target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- - To print the results, use any application that's able to receive messages over - TCP or UDP. NetCat is - a simple but very powerful command-line tool that can be used for that. This image - demonstrates the NetCat tool receiving log messages from Network target. -
-
- - NOTE: If your receiver application is ever likely to be off-line, don't use TCP protocol - or you'll get TCP timeouts and your application will be very slow. - Either switch to UDP transport or use AsyncWrapper target - so that your application threads will not be blocked by the timing-out connection attempts. -
-- There are two specialized versions of the Network target: Chainsaw - and NLogViewer which write to instances of Chainsaw log4j viewer - or NLogViewer application respectively. -
-${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- - NOTE: If your receiver application is ever likely to be off-line, don't use TCP protocol - or you'll get TCP timeouts and your application will crawl. - Either switch to UDP transport or use AsyncWrapper target - so that your application threads will not be blocked by the timing-out connection attempts. -
-${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
-
- <system.net>
- <defaultProxy enabled = "true" useDefaultCredentials = "true" >
- <proxy usesystemdefault = "True" />
- </defaultProxy>
- </system.net>
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- The example web service that works with this example is shown below
-
- - Asynchronous target wrapper allows the logger code to execute more quickly, by queueing - messages and processing them in a separate thread. You should wrap targets - that spend a non-trivial amount of time in their Write() method with asynchronous - target to speed up logging. -
-- Because asynchronous logging is quite a common scenario, NLog supports a - shorthand notation for wrapping all targets with AsyncWrapper. Just add async="true" to - the <targets/> element in the configuration file. -
-
-
- ... your targets go here ...
-
- ]]>
- - To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- This example causes the messages to be written to server1, - and if it fails, messages go to server2.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes the messages not contains the string '1' to be ignored.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- - This example works like this. If there are no Warn,Error or Fatal messages in the buffer - only Info messages are written to the file, but if there are any warnings or errors, - the output includes detailed trace (levels >= Debug). You can plug in a different type - of buffering wrapper (such as ASPNetBufferingWrapper) to achieve different - functionality. -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes the messages to be written to either file1.txt or file2.txt - chosen randomly on a per-message basis. -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes each log message to be repeated 3 times.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes each write attempt to be repeated 3 times, - sleeping 1 second between attempts if first one fails.
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes the messages to be written to either file1.txt or file2.txt. - Each odd message is written to file2.txt, each even message goes to file1.txt. -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
- This example causes the messages to be written to both file1.txt or file2.txt -
-- To set up the target in the configuration file, - use the following syntax: -
-
- - The above examples assume just one target and a single rule. See below for - a programmatic configuration that's equivalent to the above config file: -
-
-
- [CanBeNull] public object Test() { return null; }
- public void UseTest() {
+ [CanBeNull] object Test() => null;
+
+ void UseTest() {
var p = Test();
var s = p.ToString(); // Warning: Possible 'System.NullReferenceException'
}
@@ -19,24 +20,39 @@
- [NotNull] public object Foo() {
+ [NotNull] object Foo() {
return null; // Warning: Possible 'null' assignment
}
[StringFormatMethod("message")]
- public void ShowError(string message, params object[] args) { /* do something */ }
- public void Foo() {
+ void ShowError(string message, params object[] args) { /* do something */ }
+
+ void Foo() {
ShowError("Failed: {0}"); // Warning: Non-existing argument in format string
}
- public void Foo(string param) {
+ void Foo(string param) {
if (param == null)
throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol
}
@@ -62,8 +84,8 @@
Indicates that the method is contained in a type that implements
- interface
- and this method is used to notify that some property value changed
+ System.ComponentModel.INotifyPropertyChanged interface and this method
+ is used to notify that some property value changed.
The method should be non-static and conform to one of the supported signatures:
@@ -76,12 +98,14 @@
- internal class Foo : INotifyPropertyChanged {
+ public class Foo : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
+
[NotifyPropertyChangedInvocator]
protected virtual void NotifyChanged(string propertyName) { ... }
- private string _name;
+ string _name;
+
public string Name {
get { return _name; }
set { _name = value; NotifyChanged("LastName"); /* Warning */ }
@@ -99,7 +123,7 @@
- Describes dependency between method input and output
+ Describes dependency between method input and output.
Function Definition Table syntax:
@@ -111,15 +135,16 @@
- Value ::= true | false | null | notnull | canbenull
If method has single input parameter, it's name could be omitted.
- Using halt (or void /nothing , which is the same)
- for method output means that the methos doesn't return normally.
- canbenull annotation is only applicable for output parameters.
- You can use multiple [ContractAnnotation] for each FDT row,
- or use single attribute with rows separated by semicolon.
+ Using halt (or void /nothing , which is the same) for method output
+ means that the methods doesn't return normally (throws or terminates the process).
+ Value canbenull is only applicable for output parameters.
+ You can use multiple [ContractAnnotation] for each FDT row, or use single attribute
+ with rows separated by semicolon. There is no notion of order rows, all rows are checked
+ for applicability and applied per each program state tracked by R# analysis.
- [ContractAnnotation("=> halt")]
+ [ContractAnnotation("=> halt")]
public void TerminationMethod()
@@ -127,28 +152,29 @@
public void Assert(bool condition, string text) // regular assertion method
- [ContractAnnotation("s:null => true")]
+ [ContractAnnotation("s:null => true")]
public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty()
- // A method that returns null if the parameter is null, and not null if the parameter is not null
- [ContractAnnotation("null => null; notnull => notnull")]
+ // A method that returns null if the parameter is null,
+ // and not null if the parameter is not null
+ [ContractAnnotation("null => null; notnull => notnull")]
public object Transform(object data)
- [ContractAnnotation("s:null=>false; =>true,result:notnull; =>false, result:null")]
+ [ContractAnnotation("=> true, result: notnull; => false, result: null")]
public bool TryParse(string s, out Person result)
- Indicates that marked element should be localized or not
+ Indicates that marked element should be localized or not.
[LocalizationRequiredAttribute(true)]
- internal class Foo {
- private string str = "my string"; // Warning: Localizable string
+ class Foo {
+ string str = "my string"; // Warning: Localizable string
}
@@ -162,8 +188,9 @@
[CannotApplyEqualityOperator]
class NoEquality { }
+
class UsesNoEquality {
- public void Test() {
+ void Test() {
var ca1 = new NoEquality();
var ca2 = new NoEquality();
if (ca1 != null) { // OK
@@ -180,30 +207,29 @@
[BaseTypeRequired(typeof(IComponent)] // Specify requirement
- internal class ComponentAttribute : Attribute { }
+ class ComponentAttribute : Attribute { }
+
[Component] // ComponentAttribute requires implementing IComponent interface
- internal class MyComponent : IComponent { }
+ class MyComponent : IComponent { }
- [Pure] private int Multiply(int x, int y) { return x * y; }
- public void Foo() {
- const int a = 2, b = 2;
- Multiply(a, b); // Waring: Return value of pure method is not used
+ [Pure] int Multiply(int x, int y) => x * y;
+
+ void M() {
+ Multiply(123, 42); // Waring: Return value of pure method is not used
+ }
+
+ class Foo {
+ [ProvidesContext] IBarService _barService = ...;
+
+ void ProcessNode(INode node) {
+ DoSomething(node, node.GetGlobalServices().Bar);
+ // ^ Warning: use value of '_barService' field
+ }
}
+ [SourceTemplate]
+ public static void forEach<T>(this IEnumerable<T> xs) {
+ foreach (var x in xs) {
+ //$ $END$
+ }
+ }
+
+
+ [SourceTemplate, Macro(Target = "item", Expression = "suggestVariableName()")]
+ public static void forEach<T>(this IEnumerable<T> collection) {
+ foreach (var item in collection) {
+ //$ $END$
+ }
+ }
+
+ Applying the attribute on a template method parameter:
+
+ [SourceTemplate]
+ public static void something(this Entity x, [Macro(Expression = "guid()", Editable = -1)] string newguid) {
+ /*$ var $x$Id = "$newguid$" + x.ToString();
+ x.DoSomething($x$Id); */
+ }
+
+
[ActionName("Foo")]
@@ -361,9 +489,124 @@
Razor attribute. Indicates that a parameter or a method is a Razor section.
Use this attribute for custom wrappers similar to
- System.Web.WebPages.WebPageBase.RenderSection(String)
+ System.Web.WebPages.WebPageBase.RenderSection(String) .
-
-
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
-
- [CanBeNull] public object Test() { return null; }
- public void UseTest() {
+ [CanBeNull] object Test() => null;
+
+ void UseTest() {
var p = Test();
var s = p.ToString(); // Warning: Possible 'System.NullReferenceException'
}
@@ -19,24 +20,39 @@
- [NotNull] public object Foo() {
+ [NotNull] object Foo() {
return null; // Warning: Possible 'null' assignment
}
[StringFormatMethod("message")]
- public void ShowError(string message, params object[] args) { /* do something */ }
- public void Foo() {
+ void ShowError(string message, params object[] args) { /* do something */ }
+
+ void Foo() {
ShowError("Failed: {0}"); // Warning: Non-existing argument in format string
}
- public void Foo(string param) {
+ void Foo(string param) {
if (param == null)
throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol
}
@@ -62,8 +84,8 @@
Indicates that the method is contained in a type that implements
- interface
- and this method is used to notify that some property value changed
+ System.ComponentModel.INotifyPropertyChanged interface and this method
+ is used to notify that some property value changed.
The method should be non-static and conform to one of the supported signatures:
@@ -76,12 +98,14 @@
- internal class Foo : INotifyPropertyChanged {
+ public class Foo : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
+
[NotifyPropertyChangedInvocator]
protected virtual void NotifyChanged(string propertyName) { ... }
- private string _name;
+ string _name;
+
public string Name {
get { return _name; }
set { _name = value; NotifyChanged("LastName"); /* Warning */ }
@@ -99,7 +123,7 @@
- Describes dependency between method input and output
+ Describes dependency between method input and output.
Function Definition Table syntax:
@@ -111,15 +135,16 @@
- Value ::= true | false | null | notnull | canbenull
If method has single input parameter, it's name could be omitted.
- Using halt (or void /nothing , which is the same)
- for method output means that the methos doesn't return normally.
- canbenull annotation is only applicable for output parameters.
- You can use multiple [ContractAnnotation] for each FDT row,
- or use single attribute with rows separated by semicolon.
+ Using halt (or void /nothing , which is the same) for method output
+ means that the methods doesn't return normally (throws or terminates the process).
+ Value canbenull is only applicable for output parameters.
+ You can use multiple [ContractAnnotation] for each FDT row, or use single attribute
+ with rows separated by semicolon. There is no notion of order rows, all rows are checked
+ for applicability and applied per each program state tracked by R# analysis.
- [ContractAnnotation("=> halt")]
+ [ContractAnnotation("=> halt")]
public void TerminationMethod()
@@ -127,28 +152,29 @@
public void Assert(bool condition, string text) // regular assertion method
- [ContractAnnotation("s:null => true")]
+ [ContractAnnotation("s:null => true")]
public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty()
- // A method that returns null if the parameter is null, and not null if the parameter is not null
- [ContractAnnotation("null => null; notnull => notnull")]
+ // A method that returns null if the parameter is null,
+ // and not null if the parameter is not null
+ [ContractAnnotation("null => null; notnull => notnull")]
public object Transform(object data)
- [ContractAnnotation("s:null=>false; =>true,result:notnull; =>false, result:null")]
+ [ContractAnnotation("=> true, result: notnull; => false, result: null")]
public bool TryParse(string s, out Person result)
- Indicates that marked element should be localized or not
+ Indicates that marked element should be localized or not.
[LocalizationRequiredAttribute(true)]
- internal class Foo {
- private string str = "my string"; // Warning: Localizable string
+ class Foo {
+ string str = "my string"; // Warning: Localizable string
}
@@ -162,8 +188,9 @@
[CannotApplyEqualityOperator]
class NoEquality { }
+
class UsesNoEquality {
- public void Test() {
+ void Test() {
var ca1 = new NoEquality();
var ca2 = new NoEquality();
if (ca1 != null) { // OK
@@ -180,30 +207,29 @@
[BaseTypeRequired(typeof(IComponent)] // Specify requirement
- internal class ComponentAttribute : Attribute { }
+ class ComponentAttribute : Attribute { }
+
[Component] // ComponentAttribute requires implementing IComponent interface
- internal class MyComponent : IComponent { }
+ class MyComponent : IComponent { }
- [Pure] private int Multiply(int x, int y) { return x * y; }
- public void Foo() {
- const int a = 2, b = 2;
- Multiply(a, b); // Waring: Return value of pure method is not used
+ [Pure] int Multiply(int x, int y) => x * y;
+
+ void M() {
+ Multiply(123, 42); // Waring: Return value of pure method is not used
+ }
+
+ class Foo {
+ [ProvidesContext] IBarService _barService = ...;
+
+ void ProcessNode(INode node) {
+ DoSomething(node, node.GetGlobalServices().Bar);
+ // ^ Warning: use value of '_barService' field
+ }
}
+ [SourceTemplate]
+ public static void forEach<T>(this IEnumerable<T> xs) {
+ foreach (var x in xs) {
+ //$ $END$
+ }
+ }
+
+
+ [SourceTemplate, Macro(Target = "item", Expression = "suggestVariableName()")]
+ public static void forEach<T>(this IEnumerable<T> collection) {
+ foreach (var item in collection) {
+ //$ $END$
+ }
+ }
+
+ Applying the attribute on a template method parameter:
+
+ [SourceTemplate]
+ public static void something(this Entity x, [Macro(Expression = "guid()", Editable = -1)] string newguid) {
+ /*$ var $x$Id = "$newguid$" + x.ToString();
+ x.DoSomething($x$Id); */
+ }
+
+
[ActionName("Foo")]
@@ -361,9 +489,124 @@
Razor attribute. Indicates that a parameter or a method is a Razor section.
Use this attribute for custom wrappers similar to
- System.Web.WebPages.WebPageBase.RenderSection(String)
+ System.Web.WebPages.WebPageBase.RenderSection(String) .
+ ${appsetting:item=mysetting:default=mydefault} - produces "mydefault" if no appsetting
+
+
- protected override Task WriteAsyncTask(LogEventInfo logEvent, CancellationToken token)
- {
- return CustomWriteAsync(logEvent, token);
- }
-
- private async Task CustomWriteAsync(LogEventInfo logEvent, CancellationToken token)
- {
- await MyLogMethodAsync(logEvent, token).ConfigureAwait(false);
- }
-
+ [CanBeNull] object Test() => null;
+
+ void UseTest() {
+ var p = Test();
+ var s = p.ToString(); // Warning: Possible 'System.NullReferenceException'
+ }
+
+ [NotNull] object Foo() {
+ return null; // Warning: Possible 'null' assignment
+ }
+
+ [StringFormatMethod("message")]
+ void ShowError(string message, params object[] args) { /* do something */ }
+
+ void Foo() {
+ ShowError("Failed: {0}"); // Warning: Non-existing argument in format string
+ }
+
+ void Foo(string param) {
+ if (param == null)
+ throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol
+ }
+
+ public class Foo : INotifyPropertyChanged {
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ [NotifyPropertyChangedInvocator]
+ protected virtual void NotifyChanged(string propertyName) { ... }
+
+ string _name;
+
+ public string Name {
+ get { return _name; }
+ set { _name = value; NotifyChanged("LastName"); /* Warning */ }
+ }
+ }
+
+ Examples of generated notifications:
+ Function Definition Table syntax:
+
+ [ContractAnnotation("=> halt")]
+ public void TerminationMethod()
+
+ [ContractAnnotation("halt <= condition: false")]
+ public void Assert(bool condition, string text) // regular assertion method
+
+ [ContractAnnotation("s:null => true")]
+ public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty()
+
+ // A method that returns null if the parameter is null,
+ // and not null if the parameter is not null
+ [ContractAnnotation("null => null; notnull => notnull")]
+ public object Transform(object data)
+
+ [ContractAnnotation("=> true, result: notnull; => false, result: null")]
+ public bool TryParse(string s, out Person result)
+
+ [LocalizationRequiredAttribute(true)]
+ class Foo {
+ string str = "my string"; // Warning: Localizable string
+ }
+
+ [CannotApplyEqualityOperator]
+ class NoEquality { }
+
+ class UsesNoEquality {
+ void Test() {
+ var ca1 = new NoEquality();
+ var ca2 = new NoEquality();
+ if (ca1 != null) { // OK
+ bool condition = ca1 == ca2; // Warning
+ }
+ }
+ }
+
+ [BaseTypeRequired(typeof(IComponent)] // Specify requirement
+ class ComponentAttribute : Attribute { }
+
+ [Component] // ComponentAttribute requires implementing IComponent interface
+ class MyComponent : IComponent { }
+
+ [Pure] int Multiply(int x, int y) => x * y;
+
+ void M() {
+ Multiply(123, 42); // Waring: Return value of pure method is not used
+ }
+
+ class Foo {
+ [ProvidesContext] IBarService _barService = ...;
+
+ void ProcessNode(INode node) {
+ DoSomething(node, node.GetGlobalServices().Bar);
+ // ^ Warning: use value of '_barService' field
+ }
+ }
+
+ [SourceTemplate]
+ public static void forEach<T>(this IEnumerable<T> xs) {
+ foreach (var x in xs) {
+ //$ $END$
+ }
+ }
+
+
+ [SourceTemplate, Macro(Target = "item", Expression = "suggestVariableName()")]
+ public static void forEach<T>(this IEnumerable<T> collection) {
+ foreach (var item in collection) {
+ //$ $END$
+ }
+ }
+
+ Applying the attribute on a template method parameter:
+
+ [SourceTemplate]
+ public static void something(this Entity x, [Macro(Expression = "guid()", Editable = -1)] string newguid) {
+ /*$ var $x$Id = "$newguid$" + x.ToString();
+ x.DoSomething($x$Id); */
+ }
+
+
+ [ActionName("Foo")]
+ public ActionResult Login(string returnUrl) {
+ ViewBag.ReturnUrl = Url.Action("Foo"); // OK
+ return RedirectToAction("Bar"); // Error: Cannot resolve action
+ }
+
+ ${appsetting:item=mysetting:default=mydefault} - produces "mydefault" if no appsetting
+
+
+ protected override Task WriteAsyncTask(LogEventInfo logEvent, CancellationToken token)
+ {
+ return CustomWriteAsync(logEvent, token);
+ }
+
+ private async Task CustomWriteAsync(LogEventInfo logEvent, CancellationToken token)
+ {
+ await MyLogMethodAsync(logEvent, token).ConfigureAwait(false);
+ }
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ + NOTE: If your receiver application is ever likely to be off-line, don't use TCP protocol + or you'll get TCP timeouts and your application will crawl. + Either switch to UDP transport or use AsyncWrapper target + so that your application threads will not be blocked by the timing-out connection attempts. +
+${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ | Condition | +Foreground Color | +Background Color | +
|---|---|---|
| level == LogLevel.Fatal | +Red | +NoChange | +
| level == LogLevel.Error | +Yellow | +NoChange | +
| level == LogLevel.Warn | +Magenta | +NoChange | +
| level == LogLevel.Info | +White | +NoChange | +
| level == LogLevel.Debug | +Gray | +NoChange | +
| level == LogLevel.Trace | +DarkGray | +NoChange | +
+ To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+
+
+
+
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${basedir}/${level}.log
+ All
+ Caution: Enabling this option can considerably slow down your file
+ logging in multi-process scenarios. If only one process is going to
+ be writing to the file, consider setting
+ To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ + Mail target works best when used with BufferingWrapper target + which lets you send multiple log messages in single mail +
++ To set up the buffered mail target in the configuration file, + use the following syntax: +
+
+ + To set up the buffered mail target programmatically use code like this: +
+
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ + To print the results, use any application that's able to receive messages over + TCP or UDP. NetCat is + a simple but very powerful command-line tool that can be used for that. This image + demonstrates the NetCat tool receiving log messages from Network target. +
+
+ + NOTE: If your receiver application is ever likely to be off-line, don't use TCP protocol + or you'll get TCP timeouts and your application will be very slow. + Either switch to UDP transport or use AsyncWrapper target + so that your application threads will not be blocked by the timing-out connection attempts. +
++ There are two specialized versions of the Network target: Chainsaw + and NLogViewer which write to instances of Chainsaw log4j viewer + or NLogViewer application respectively. +
+${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ + NOTE: If your receiver application is ever likely to be off-line, don't use TCP protocol + or you'll get TCP timeouts and your application will crawl. + Either switch to UDP transport or use AsyncWrapper target + so that your application threads will not be blocked by the timing-out connection attempts. +
+${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+
+ <system.net>
+ <defaultProxy enabled = "true" useDefaultCredentials = "true" >
+ <proxy usesystemdefault = "True" />
+ </defaultProxy>
+ </system.net>
+
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ The example web service that works with this example is shown below
+
+ + Asynchronous target wrapper allows the logger code to execute more quickly, by queueing + messages and processing them in a separate thread. You should wrap targets + that spend a non-trivial amount of time in their Write() method with asynchronous + target to speed up logging. +
++ Because asynchronous logging is quite a common scenario, NLog supports a + shorthand notation for wrapping all targets with AsyncWrapper. Just add async="true" to + the <targets/> element in the configuration file. +
+
+
+ ... your targets go here ...
+
+ ]]>
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + The above examples assume just one target and a single rule. See below for + a programmatic configuration that's equivalent to the above config file: +
+
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + The above examples assume just one target and a single rule. See below for + a programmatic configuration that's equivalent to the above config file: +
+
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ This example causes the messages to be written to server1, + and if it fails, messages go to server2.
++ To set up the target in the configuration file, + use the following syntax: +
+
+ + The above examples assume just one target and a single rule. See below for + a programmatic configuration that's equivalent to the above config file: +
+
+ This example causes the messages not contains the string '1' to be ignored.
++ To set up the target in the configuration file, + use the following syntax: +
+
+ + The above examples assume just one target and a single rule. See below for + a programmatic configuration that's equivalent to the above config file: +
+
+ + This example works like this. If there are no Warn,Error or Fatal messages in the buffer + only Info messages are written to the file, but if there are any warnings or errors, + the output includes detailed trace (levels >= Debug). You can plug in a different type + of buffering wrapper (such as ASPNetBufferingWrapper) to achieve different + functionality. +
++ To set up the target in the configuration file, + use the following syntax: +
+
+ + The above examples assume just one target and a single rule. See below for + a programmatic configuration that's equivalent to the above config file: +
+
+ This example causes the messages to be written to either file1.txt or file2.txt + chosen randomly on a per-message basis. +
++ To set up the target in the configuration file, + use the following syntax: +
+
+ + The above examples assume just one target and a single rule. See below for + a programmatic configuration that's equivalent to the above config file: +
+
+ This example causes each log message to be repeated 3 times.
++ To set up the target in the configuration file, + use the following syntax: +
+
+ + The above examples assume just one target and a single rule. See below for + a programmatic configuration that's equivalent to the above config file: +
+
+ This example causes each write attempt to be repeated 3 times, + sleeping 1 second between attempts if first one fails.
++ To set up the target in the configuration file, + use the following syntax: +
+
+ + The above examples assume just one target and a single rule. See below for + a programmatic configuration that's equivalent to the above config file: +
+
+ This example causes the messages to be written to either file1.txt or file2.txt. + Each odd message is written to file2.txt, each even message goes to file1.txt. +
++ To set up the target in the configuration file, + use the following syntax: +
+
+ + The above examples assume just one target and a single rule. See below for + a programmatic configuration that's equivalent to the above config file: +
+
+ This example causes the messages to be written to both file1.txt or file2.txt +
++ To set up the target in the configuration file, + use the following syntax: +
+
+ + The above examples assume just one target and a single rule. See below for + a programmatic configuration that's equivalent to the above config file: +
+
+
+ [CanBeNull] object Test() => null;
+
+ void UseTest() {
+ var p = Test();
+ var s = p.ToString(); // Warning: Possible 'System.NullReferenceException'
+ }
+
+ [NotNull] object Foo() {
+ return null; // Warning: Possible 'null' assignment
+ }
+
+ [StringFormatMethod("message")]
+ void ShowError(string message, params object[] args) { /* do something */ }
+
+ void Foo() {
+ ShowError("Failed: {0}"); // Warning: Non-existing argument in format string
+ }
+
+ void Foo(string param) {
+ if (param == null)
+ throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol
+ }
+
+ public class Foo : INotifyPropertyChanged {
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ [NotifyPropertyChangedInvocator]
+ protected virtual void NotifyChanged(string propertyName) { ... }
+
+ string _name;
+
+ public string Name {
+ get { return _name; }
+ set { _name = value; NotifyChanged("LastName"); /* Warning */ }
+ }
+ }
+
+ Examples of generated notifications:
+ Function Definition Table syntax:
+
+ [ContractAnnotation("=> halt")]
+ public void TerminationMethod()
+
+ [ContractAnnotation("halt <= condition: false")]
+ public void Assert(bool condition, string text) // regular assertion method
+
+ [ContractAnnotation("s:null => true")]
+ public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty()
+
+ // A method that returns null if the parameter is null,
+ // and not null if the parameter is not null
+ [ContractAnnotation("null => null; notnull => notnull")]
+ public object Transform(object data)
+
+ [ContractAnnotation("=> true, result: notnull; => false, result: null")]
+ public bool TryParse(string s, out Person result)
+
+ [LocalizationRequiredAttribute(true)]
+ class Foo {
+ string str = "my string"; // Warning: Localizable string
+ }
+
+ [CannotApplyEqualityOperator]
+ class NoEquality { }
+
+ class UsesNoEquality {
+ void Test() {
+ var ca1 = new NoEquality();
+ var ca2 = new NoEquality();
+ if (ca1 != null) { // OK
+ bool condition = ca1 == ca2; // Warning
+ }
+ }
+ }
+
+ [BaseTypeRequired(typeof(IComponent)] // Specify requirement
+ class ComponentAttribute : Attribute { }
+
+ [Component] // ComponentAttribute requires implementing IComponent interface
+ class MyComponent : IComponent { }
+
+ [Pure] int Multiply(int x, int y) => x * y;
+
+ void M() {
+ Multiply(123, 42); // Waring: Return value of pure method is not used
+ }
+
+ class Foo {
+ [ProvidesContext] IBarService _barService = ...;
+
+ void ProcessNode(INode node) {
+ DoSomething(node, node.GetGlobalServices().Bar);
+ // ^ Warning: use value of '_barService' field
+ }
+ }
+
+ [SourceTemplate]
+ public static void forEach<T>(this IEnumerable<T> xs) {
+ foreach (var x in xs) {
+ //$ $END$
+ }
+ }
+
+
+ [SourceTemplate, Macro(Target = "item", Expression = "suggestVariableName()")]
+ public static void forEach<T>(this IEnumerable<T> collection) {
+ foreach (var item in collection) {
+ //$ $END$
+ }
+ }
+
+ Applying the attribute on a template method parameter:
+
+ [SourceTemplate]
+ public static void something(this Entity x, [Macro(Expression = "guid()", Editable = -1)] string newguid) {
+ /*$ var $x$Id = "$newguid$" + x.ToString();
+ x.DoSomething($x$Id); */
+ }
+
+
+ [ActionName("Foo")]
+ public ActionResult Login(string returnUrl) {
+ ViewBag.ReturnUrl = Url.Action("Foo"); // OK
+ return RedirectToAction("Bar"); // Error: Cannot resolve action
+ }
+
+ ${appsetting:item=mysetting:default=mydefault} - produces "mydefault" if no appsetting
+
+
+ protected override Task WriteAsyncTask(LogEventInfo logEvent, CancellationToken token)
+ {
+ return CustomWriteAsync(logEvent, token);
+ }
+
+ private async Task CustomWriteAsync(LogEventInfo logEvent, CancellationToken token)
+ {
+ await MyLogMethodAsync(logEvent, token).ConfigureAwait(false);
+ }
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ + NOTE: If your receiver application is ever likely to be off-line, don't use TCP protocol + or you'll get TCP timeouts and your application will crawl. + Either switch to UDP transport or use AsyncWrapper target + so that your application threads will not be blocked by the timing-out connection attempts. +
+${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ | Condition | +Foreground Color | +Background Color | +
|---|---|---|
| level == LogLevel.Fatal | +Red | +NoChange | +
| level == LogLevel.Error | +Yellow | +NoChange | +
| level == LogLevel.Warn | +Magenta | +NoChange | +
| level == LogLevel.Info | +White | +NoChange | +
| level == LogLevel.Debug | +Gray | +NoChange | +
| level == LogLevel.Trace | +DarkGray | +NoChange | +
+ To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+
+
+
+
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${basedir}/${level}.log
+ All
+ Caution: Enabling this option can considerably slow down your file
+ logging in multi-process scenarios. If only one process is going to
+ be writing to the file, consider setting
+ To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ + Mail target works best when used with BufferingWrapper target + which lets you send multiple log messages in single mail +
++ To set up the buffered mail target in the configuration file, + use the following syntax: +
+
+ + To set up the buffered mail target programmatically use code like this: +
+
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ + To print the results, use any application that's able to receive messages over + TCP or UDP. NetCat is + a simple but very powerful command-line tool that can be used for that. This image + demonstrates the NetCat tool receiving log messages from Network target. +
+
+ + NOTE: If your receiver application is ever likely to be off-line, don't use TCP protocol + or you'll get TCP timeouts and your application will be very slow. + Either switch to UDP transport or use AsyncWrapper target + so that your application threads will not be blocked by the timing-out connection attempts. +
++ There are two specialized versions of the Network target: Chainsaw + and NLogViewer which write to instances of Chainsaw log4j viewer + or NLogViewer application respectively. +
+${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ + NOTE: If your receiver application is ever likely to be off-line, don't use TCP protocol + or you'll get TCP timeouts and your application will crawl. + Either switch to UDP transport or use AsyncWrapper target + so that your application threads will not be blocked by the timing-out connection attempts. +
+${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+
+ <system.net>
+ <defaultProxy enabled = "true" useDefaultCredentials = "true" >
+ <proxy usesystemdefault = "True" />
+ </defaultProxy>
+ </system.net>
+
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + This assumes just one target and a single rule. More configuration + options are described here. +
++ To set up the log target programmatically use code like this: +
+
+ The example web service that works with this example is shown below
+
+ + Asynchronous target wrapper allows the logger code to execute more quickly, by queueing + messages and processing them in a separate thread. You should wrap targets + that spend a non-trivial amount of time in their Write() method with asynchronous + target to speed up logging. +
++ Because asynchronous logging is quite a common scenario, NLog supports a + shorthand notation for wrapping all targets with AsyncWrapper. Just add async="true" to + the <targets/> element in the configuration file. +
+
+
+ ... your targets go here ...
+
+ ]]>
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + The above examples assume just one target and a single rule. See below for + a programmatic configuration that's equivalent to the above config file: +
+
+ + To set up the target in the configuration file, + use the following syntax: +
+
+ + The above examples assume just one target and a single rule. See below for + a programmatic configuration that's equivalent to the above config file: +
+
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ ${longdate}|${level:uppercase=true}|${logger}|${message}
+ This example causes the messages to be written to server1, + and if it fails, messages go to server2.
++ To set up the target in the configuration file, + use the following syntax: +
+
+ + The above examples assume just one target and a single rule. See below for + a programmatic configuration that's equivalent to the above config file: +
+
+ This example causes the messages not contains the string '1' to be ignored.
++ To set up the target in the configuration file, + use the following syntax: +
+
+ + The above examples assume just one target and a single rule. See below for + a programmatic configuration that's equivalent to the above config file: +
+
+ + This example works like this. If there are no Warn,Error or Fatal messages in the buffer + only Info messages are written to the file, but if there are any warnings or errors, + the output includes detailed trace (levels >= Debug). You can plug in a different type + of buffering wrapper (such as ASPNetBufferingWrapper) to achieve different + functionality. +
++ To set up the target in the configuration file, + use the following syntax: +
+
+ + The above examples assume just one target and a single rule. See below for + a programmatic configuration that's equivalent to the above config file: +
+
+ This example causes the messages to be written to either file1.txt or file2.txt + chosen randomly on a per-message basis. +
++ To set up the target in the configuration file, + use the following syntax: +
+
+ + The above examples assume just one target and a single rule. See below for + a programmatic configuration that's equivalent to the above config file: +
+
+ This example causes each log message to be repeated 3 times.
++ To set up the target in the configuration file, + use the following syntax: +
+
+ + The above examples assume just one target and a single rule. See below for + a programmatic configuration that's equivalent to the above config file: +
+
+ This example causes each write attempt to be repeated 3 times, + sleeping 1 second between attempts if first one fails.
++ To set up the target in the configuration file, + use the following syntax: +
+
+ + The above examples assume just one target and a single rule. See below for + a programmatic configuration that's equivalent to the above config file: +
+
+ This example causes the messages to be written to either file1.txt or file2.txt. + Each odd message is written to file2.txt, each even message goes to file1.txt. +
++ To set up the target in the configuration file, + use the following syntax: +
+
+ + The above examples assume just one target and a single rule. See below for + a programmatic configuration that's equivalent to the above config file: +
+
+ This example causes the messages to be written to both file1.txt or file2.txt +
++ To set up the target in the configuration file, + use the following syntax: +
+
+ + The above examples assume just one target and a single rule. See below for + a programmatic configuration that's equivalent to the above config file: +
+
+
- [CanBeNull] public object Test() { return null; }
- public void UseTest() {
+ [CanBeNull] object Test() => null;
+
+ void UseTest() {
var p = Test();
var s = p.ToString(); // Warning: Possible 'System.NullReferenceException'
}
@@ -19,24 +20,39 @@
- [NotNull] public object Foo() {
+ [NotNull] object Foo() {
return null; // Warning: Possible 'null' assignment
}
[StringFormatMethod("message")]
- public void ShowError(string message, params object[] args) { /* do something */ }
- public void Foo() {
+ void ShowError(string message, params object[] args) { /* do something */ }
+
+ void Foo() {
ShowError("Failed: {0}"); // Warning: Non-existing argument in format string
}
- public void Foo(string param) {
+ void Foo(string param) {
if (param == null)
throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol
}
@@ -62,8 +84,8 @@
Indicates that the method is contained in a type that implements
- interface
- and this method is used to notify that some property value changed
+ System.ComponentModel.INotifyPropertyChanged interface and this method
+ is used to notify that some property value changed.
The method should be non-static and conform to one of the supported signatures:
@@ -76,12 +98,14 @@
- internal class Foo : INotifyPropertyChanged {
+ public class Foo : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
+
[NotifyPropertyChangedInvocator]
protected virtual void NotifyChanged(string propertyName) { ... }
- private string _name;
+ string _name;
+
public string Name {
get { return _name; }
set { _name = value; NotifyChanged("LastName"); /* Warning */ }
@@ -99,7 +123,7 @@
- Describes dependency between method input and output
+ Describes dependency between method input and output.
Function Definition Table syntax:
@@ -111,15 +135,16 @@
- Value ::= true | false | null | notnull | canbenull
If method has single input parameter, it's name could be omitted.
- Using halt (or void /nothing , which is the same)
- for method output means that the methos doesn't return normally.
- canbenull annotation is only applicable for output parameters.
- You can use multiple [ContractAnnotation] for each FDT row,
- or use single attribute with rows separated by semicolon.
+ Using halt (or void /nothing , which is the same) for method output
+ means that the methods doesn't return normally (throws or terminates the process).
+ Value canbenull is only applicable for output parameters.
+ You can use multiple [ContractAnnotation] for each FDT row, or use single attribute
+ with rows separated by semicolon. There is no notion of order rows, all rows are checked
+ for applicability and applied per each program state tracked by R# analysis.
- [ContractAnnotation("=> halt")]
+ [ContractAnnotation("=> halt")]
public void TerminationMethod()
@@ -127,28 +152,29 @@
public void Assert(bool condition, string text) // regular assertion method
- [ContractAnnotation("s:null => true")]
+ [ContractAnnotation("s:null => true")]
public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty()
- // A method that returns null if the parameter is null, and not null if the parameter is not null
- [ContractAnnotation("null => null; notnull => notnull")]
+ // A method that returns null if the parameter is null,
+ // and not null if the parameter is not null
+ [ContractAnnotation("null => null; notnull => notnull")]
public object Transform(object data)
- [ContractAnnotation("s:null=>false; =>true,result:notnull; =>false, result:null")]
+ [ContractAnnotation("=> true, result: notnull; => false, result: null")]
public bool TryParse(string s, out Person result)
- Indicates that marked element should be localized or not
+ Indicates that marked element should be localized or not.
[LocalizationRequiredAttribute(true)]
- internal class Foo {
- private string str = "my string"; // Warning: Localizable string
+ class Foo {
+ string str = "my string"; // Warning: Localizable string
}
@@ -162,8 +188,9 @@
[CannotApplyEqualityOperator]
class NoEquality { }
+
class UsesNoEquality {
- public void Test() {
+ void Test() {
var ca1 = new NoEquality();
var ca2 = new NoEquality();
if (ca1 != null) { // OK
@@ -180,30 +207,29 @@
[BaseTypeRequired(typeof(IComponent)] // Specify requirement
- internal class ComponentAttribute : Attribute { }
+ class ComponentAttribute : Attribute { }
+
[Component] // ComponentAttribute requires implementing IComponent interface
- internal class MyComponent : IComponent { }
+ class MyComponent : IComponent { }
- [Pure] private int Multiply(int x, int y) { return x * y; }
- public void Foo() {
- const int a = 2, b = 2;
- Multiply(a, b); // Waring: Return value of pure method is not used
+ [Pure] int Multiply(int x, int y) => x * y;
+
+ void M() {
+ Multiply(123, 42); // Waring: Return value of pure method is not used
+ }
+
+ class Foo {
+ [ProvidesContext] IBarService _barService = ...;
+
+ void ProcessNode(INode node) {
+ DoSomething(node, node.GetGlobalServices().Bar);
+ // ^ Warning: use value of '_barService' field
+ }
}
+ [SourceTemplate]
+ public static void forEach<T>(this IEnumerable<T> xs) {
+ foreach (var x in xs) {
+ //$ $END$
+ }
+ }
+
+
+ [SourceTemplate, Macro(Target = "item", Expression = "suggestVariableName()")]
+ public static void forEach<T>(this IEnumerable<T> collection) {
+ foreach (var item in collection) {
+ //$ $END$
+ }
+ }
+
+ Applying the attribute on a template method parameter:
+
+ [SourceTemplate]
+ public static void something(this Entity x, [Macro(Expression = "guid()", Editable = -1)] string newguid) {
+ /*$ var $x$Id = "$newguid$" + x.ToString();
+ x.DoSomething($x$Id); */
+ }
+
+
[ActionName("Foo")]
@@ -361,9 +489,124 @@
Razor attribute. Indicates that a parameter or a method is a Razor section.
Use this attribute for custom wrappers similar to
- System.Web.WebPages.WebPageBase.RenderSection(String)
+ System.Web.WebPages.WebPageBase.RenderSection(String) .
${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- | Condition | -Foreground Color | -Background Color | -
|---|---|---|
| level == LogLevel.Fatal | -Red | -NoChange | -
| level == LogLevel.Error | -Yellow | -NoChange | -
| level == LogLevel.Warn | -Magenta | -NoChange | -
| level == LogLevel.Info | -White | -NoChange | -
| level == LogLevel.Debug | -Gray | -NoChange | -
| level == LogLevel.Trace | -DarkGray | -NoChange | -
- To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- - Mail target works best when used with BufferingWrapper target - which lets you send multiple log messages in single mail -
-- To set up the buffered mail target in the configuration file, - use the following syntax: -
-
- - To set up the buffered mail target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
-
- [CanBeNull] public object Test() { return null; }
- public void UseTest() {
+ [CanBeNull] object Test() => null;
+
+ void UseTest() {
var p = Test();
var s = p.ToString(); // Warning: Possible 'System.NullReferenceException'
}
@@ -19,24 +20,39 @@
- [NotNull] public object Foo() {
+ [NotNull] object Foo() {
return null; // Warning: Possible 'null' assignment
}
[StringFormatMethod("message")]
- public void ShowError(string message, params object[] args) { /* do something */ }
- public void Foo() {
+ void ShowError(string message, params object[] args) { /* do something */ }
+
+ void Foo() {
ShowError("Failed: {0}"); // Warning: Non-existing argument in format string
}
- public void Foo(string param) {
+ void Foo(string param) {
if (param == null)
throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol
}
@@ -62,8 +84,8 @@
Indicates that the method is contained in a type that implements
- interface
- and this method is used to notify that some property value changed
+ System.ComponentModel.INotifyPropertyChanged interface and this method
+ is used to notify that some property value changed.
The method should be non-static and conform to one of the supported signatures:
@@ -76,12 +98,14 @@
- internal class Foo : INotifyPropertyChanged {
+ public class Foo : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
+
[NotifyPropertyChangedInvocator]
protected virtual void NotifyChanged(string propertyName) { ... }
- private string _name;
+ string _name;
+
public string Name {
get { return _name; }
set { _name = value; NotifyChanged("LastName"); /* Warning */ }
@@ -99,7 +123,7 @@
- Describes dependency between method input and output
+ Describes dependency between method input and output.
Function Definition Table syntax:
@@ -111,15 +135,16 @@
- Value ::= true | false | null | notnull | canbenull
If method has single input parameter, it's name could be omitted.
- Using halt (or void /nothing , which is the same)
- for method output means that the methos doesn't return normally.
- canbenull annotation is only applicable for output parameters.
- You can use multiple [ContractAnnotation] for each FDT row,
- or use single attribute with rows separated by semicolon.
+ Using halt (or void /nothing , which is the same) for method output
+ means that the methods doesn't return normally (throws or terminates the process).
+ Value canbenull is only applicable for output parameters.
+ You can use multiple [ContractAnnotation] for each FDT row, or use single attribute
+ with rows separated by semicolon. There is no notion of order rows, all rows are checked
+ for applicability and applied per each program state tracked by R# analysis.
- [ContractAnnotation("=> halt")]
+ [ContractAnnotation("=> halt")]
public void TerminationMethod()
@@ -127,28 +152,29 @@
public void Assert(bool condition, string text) // regular assertion method
- [ContractAnnotation("s:null => true")]
+ [ContractAnnotation("s:null => true")]
public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty()
- // A method that returns null if the parameter is null, and not null if the parameter is not null
- [ContractAnnotation("null => null; notnull => notnull")]
+ // A method that returns null if the parameter is null,
+ // and not null if the parameter is not null
+ [ContractAnnotation("null => null; notnull => notnull")]
public object Transform(object data)
- [ContractAnnotation("s:null=>false; =>true,result:notnull; =>false, result:null")]
+ [ContractAnnotation("=> true, result: notnull; => false, result: null")]
public bool TryParse(string s, out Person result)
- Indicates that marked element should be localized or not
+ Indicates that marked element should be localized or not.
[LocalizationRequiredAttribute(true)]
- internal class Foo {
- private string str = "my string"; // Warning: Localizable string
+ class Foo {
+ string str = "my string"; // Warning: Localizable string
}
@@ -162,8 +188,9 @@
[CannotApplyEqualityOperator]
class NoEquality { }
+
class UsesNoEquality {
- public void Test() {
+ void Test() {
var ca1 = new NoEquality();
var ca2 = new NoEquality();
if (ca1 != null) { // OK
@@ -180,30 +207,29 @@
[BaseTypeRequired(typeof(IComponent)] // Specify requirement
- internal class ComponentAttribute : Attribute { }
+ class ComponentAttribute : Attribute { }
+
[Component] // ComponentAttribute requires implementing IComponent interface
- internal class MyComponent : IComponent { }
+ class MyComponent : IComponent { }
- [Pure] private int Multiply(int x, int y) { return x * y; }
- public void Foo() {
- const int a = 2, b = 2;
- Multiply(a, b); // Waring: Return value of pure method is not used
+ [Pure] int Multiply(int x, int y) => x * y;
+
+ void M() {
+ Multiply(123, 42); // Waring: Return value of pure method is not used
+ }
+
+ class Foo {
+ [ProvidesContext] IBarService _barService = ...;
+
+ void ProcessNode(INode node) {
+ DoSomething(node, node.GetGlobalServices().Bar);
+ // ^ Warning: use value of '_barService' field
+ }
}
+ [SourceTemplate]
+ public static void forEach<T>(this IEnumerable<T> xs) {
+ foreach (var x in xs) {
+ //$ $END$
+ }
+ }
+
+
+ [SourceTemplate, Macro(Target = "item", Expression = "suggestVariableName()")]
+ public static void forEach<T>(this IEnumerable<T> collection) {
+ foreach (var item in collection) {
+ //$ $END$
+ }
+ }
+
+ Applying the attribute on a template method parameter:
+
+ [SourceTemplate]
+ public static void something(this Entity x, [Macro(Expression = "guid()", Editable = -1)] string newguid) {
+ /*$ var $x$Id = "$newguid$" + x.ToString();
+ x.DoSomething($x$Id); */
+ }
+
+
[ActionName("Foo")]
@@ -361,9 +489,124 @@
Razor attribute. Indicates that a parameter or a method is a Razor section.
Use this attribute for custom wrappers similar to
- System.Web.WebPages.WebPageBase.RenderSection(String)
+ System.Web.WebPages.WebPageBase.RenderSection(String) .
- To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
- - Mail target works best when used with BufferingWrapper target - which lets you send multiple log messages in single mail -
-- To set up the buffered mail target in the configuration file, - use the following syntax: -
-
- - To set up the buffered mail target programmatically use code like this: -
-
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- ${longdate}|${level:uppercase=true}|${logger}|${message}
- - To set up the target in the configuration file, - use the following syntax: -
-
- - This assumes just one target and a single rule. More configuration - options are described here. -
-- To set up the log target programmatically use code like this: -
-
-
- [CanBeNull] public object Test() { return null; }
- public void UseTest() {
+ [CanBeNull] object Test() => null;
+
+ void UseTest() {
var p = Test();
var s = p.ToString(); // Warning: Possible 'System.NullReferenceException'
}
@@ -19,24 +20,39 @@
- [NotNull] public object Foo() {
+ [NotNull] object Foo() {
return null; // Warning: Possible 'null' assignment
}
[StringFormatMethod("message")]
- public void ShowError(string message, params object[] args) { /* do something */ }
- public void Foo() {
+ void ShowError(string message, params object[] args) { /* do something */ }
+
+ void Foo() {
ShowError("Failed: {0}"); // Warning: Non-existing argument in format string
}
- public void Foo(string param) {
+ void Foo(string param) {
if (param == null)
throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol
}
@@ -62,8 +84,8 @@
Indicates that the method is contained in a type that implements
- interface
- and this method is used to notify that some property value changed
+ System.ComponentModel.INotifyPropertyChanged interface and this method
+ is used to notify that some property value changed.
The method should be non-static and conform to one of the supported signatures:
@@ -76,12 +98,14 @@
- internal class Foo : INotifyPropertyChanged {
+ public class Foo : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
+
[NotifyPropertyChangedInvocator]
protected virtual void NotifyChanged(string propertyName) { ... }
- private string _name;
+ string _name;
+
public string Name {
get { return _name; }
set { _name = value; NotifyChanged("LastName"); /* Warning */ }
@@ -99,7 +123,7 @@
- Describes dependency between method input and output
+ Describes dependency between method input and output.
Function Definition Table syntax:
@@ -111,15 +135,16 @@
- Value ::= true | false | null | notnull | canbenull
If method has single input parameter, it's name could be omitted.
- Using halt (or void /nothing , which is the same)
- for method output means that the methos doesn't return normally.
- canbenull annotation is only applicable for output parameters.
- You can use multiple [ContractAnnotation] for each FDT row,
- or use single attribute with rows separated by semicolon.
+ Using halt (or void /nothing , which is the same) for method output
+ means that the methods doesn't return normally (throws or terminates the process).
+ Value canbenull is only applicable for output parameters.
+ You can use multiple [ContractAnnotation] for each FDT row, or use single attribute
+ with rows separated by semicolon. There is no notion of order rows, all rows are checked
+ for applicability and applied per each program state tracked by R# analysis.
- [ContractAnnotation("=> halt")]
+ [ContractAnnotation("=> halt")]
public void TerminationMethod()
@@ -127,28 +152,29 @@
public void Assert(bool condition, string text) // regular assertion method
- [ContractAnnotation("s:null => true")]
+ [ContractAnnotation("s:null => true")]
public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty()
- // A method that returns null if the parameter is null, and not null if the parameter is not null
- [ContractAnnotation("null => null; notnull => notnull")]
+ // A method that returns null if the parameter is null,
+ // and not null if the parameter is not null
+ [ContractAnnotation("null => null; notnull => notnull")]
public object Transform(object data)
- [ContractAnnotation("s:null=>false; =>true,result:notnull; =>false, result:null")]
+ [ContractAnnotation("=> true, result: notnull; => false, result: null")]
public bool TryParse(string s, out Person result)
- Indicates that marked element should be localized or not
+ Indicates that marked element should be localized or not.
[LocalizationRequiredAttribute(true)]
- internal class Foo {
- private string str = "my string"; // Warning: Localizable string
+ class Foo {
+ string str = "my string"; // Warning: Localizable string
}
@@ -162,8 +188,9 @@
[CannotApplyEqualityOperator]
class NoEquality { }
+
class UsesNoEquality {
- public void Test() {
+ void Test() {
var ca1 = new NoEquality();
var ca2 = new NoEquality();
if (ca1 != null) { // OK
@@ -180,30 +207,29 @@
[BaseTypeRequired(typeof(IComponent)] // Specify requirement
- internal class ComponentAttribute : Attribute { }
+ class ComponentAttribute : Attribute { }
+
[Component] // ComponentAttribute requires implementing IComponent interface
- internal class MyComponent : IComponent { }
+ class MyComponent : IComponent { }
- [Pure] private int Multiply(int x, int y) { return x * y; }
- public void Foo() {
- const int a = 2, b = 2;
- Multiply(a, b); // Waring: Return value of pure method is not used
+ [Pure] int Multiply(int x, int y) => x * y;
+
+ void M() {
+ Multiply(123, 42); // Waring: Return value of pure method is not used
+ }
+
+ class Foo {
+ [ProvidesContext] IBarService _barService = ...;
+
+ void ProcessNode(INode node) {
+ DoSomething(node, node.GetGlobalServices().Bar);
+ // ^ Warning: use value of '_barService' field
+ }
}
+ [SourceTemplate]
+ public static void forEach<T>(this IEnumerable<T> xs) {
+ foreach (var x in xs) {
+ //$ $END$
+ }
+ }
+
+
+ [SourceTemplate, Macro(Target = "item", Expression = "suggestVariableName()")]
+ public static void forEach<T>(this IEnumerable<T> collection) {
+ foreach (var item in collection) {
+ //$ $END$
+ }
+ }
+
+ Applying the attribute on a template method parameter:
+
+ [SourceTemplate]
+ public static void something(this Entity x, [Macro(Expression = "guid()", Editable = -1)] string newguid) {
+ /*$ var $x$Id = "$newguid$" + x.ToString();
+ x.DoSomething($x$Id); */
+ }
+
+
[ActionName("Foo")]
@@ -361,9 +489,124 @@
Razor attribute. Indicates that a parameter or a method is a Razor section.
Use this attribute for custom wrappers similar to
- System.Web.WebPages.WebPageBase.RenderSection(String)
+ System.Web.WebPages.WebPageBase.RenderSection(String) .