I know there are rules available that fire when a NotImplementedException is left in the code (which I can understand for a release build) (see this answer, or this question), but I would like to have the opposite: have Code Analysis ignore methods that throw a NotImplementedException, as they are known to be unfinished.
Background:
When I develop a block of code, I'd like to test what I have so far, before I'm completely done. I also want CA to be on, so I can correct errors early (like: didn't dispose of resources properly). But as I'm stil developing that code, there are still some stubs that I know will not be used by my test. The body of such a stub usually consists of no more than a throw new NotImplementedException();.
When I build the code, CA complains that the method could be 'static' and that parameters are unused. I know I can suppress the CA-errors, but that means I will have to remember to take those suppressions out when those methods are built and it's an extra build (one to get the messages so I can suppress them and one to really run the code).
My question:
Is there a way to have CA ignore methods that end in a NotImplementedException along (at least) one of the code paths? It would be extra nice if that could be set to only work in debug mode, so you can get warnings about that exception in a release build.
For the record, I'm using VS2010.
No. There is no such option in Code Analysis.
What you could do is write a custom rule which flags the throwing of a NotImplementedException and then process the Code Analysis outcome and remove any entry with the same target method as the NotImplemented custom rule. This rule should be pretty simple to implement. It would probably suffice to search for any Constructor call on the NotImplementedException class.
But this will only work if you run Code Analysis from the commandline and then post-process the xml file.
You could also mark the method using the GeneratedCodeAttribute, as these will be ignored by default.
Related
For a blog, I put together an inline tag that pulls header information from a specified webpage. It works, but I need to add caching, so that I'm not making redundant network calls.
I'd like a tighter debugging cycle than restarting the server and waiting for a rebuild, but running the plugin as Ruby code reports uninitialized constant Liquid (NameError). That makes sense, since it isn't required, and wouldn't run, since the plugin is just a class definition.
So, I tried creating some scaffolding to run the code, or what I thought would be scaffolding, anyway.
require 'liquid'
require_relative '../_plugins/header.rb'
ht = HeaderInlineTag.new
ht.initialize 'header', 'some path'
puts ht.render()
This produces...
_test/header.rb:4:in `<main>': private method `new' called for HeaderInlineTag:Class (NoMethodError)
Considering the possibility that initialize() might be run to create objects, I combined the first two lines of code, but that didn't work, either. Same error, different function name. The plugin doesn't mark anything as private, and declaring the methods public doesn't change anything.
What more is needed to test the plugin without carrying around the entire blog?
The solution was beyond my Ruby knowledge, but mostly straightforward, once I connected the pieces of information floating around.
First, this existing answer is about a specific issue dealing with Rails, but incidentally shows how to deal with private new methods: Call them through send, as in HeaderInlineTag.send :new.
Then, this indirect call to .new() now (of course) calls .initialize(), meaning that it needs the three parameters that are required by any plugin. Two parameters are for the testing itself, so they're easy. The third is a parse context. Documentation on writing Jekyll plugins is never clear on what the parse context actually is, since it gets sent automatically as part of the build process. However, some research and testing turns up Liquid::ParseContext as the culprit.
Finally, .render() also takes the ParseContext value.
Therefore, the the test scaffold should look something like this.
require 'liquid'
require_relative '../_plugins/header.rb'
context = Liquid::ParseContext.new
ht = HeaderInlineTag.send :new, 'header', 'some path...', context
puts ht.render context
I can call this from my blog's root folder with ruby _test/header.rb, and it prints the plugin's output. I can now update this script to pull the parameters from the command line or a CSV file, depending on the tests required.
One way of doing seemed to be to use the java.lang.Compiler
I tried to use the java.lang.Compiler inside Eclipse anddid not understand the Object any parameters for the methods of that class? And putting in a class did not seem to work either.
Compiler.command(any) // what is meant by any? What are valid objects to put there?
Compiler.compileClass(clazz) // Nothing happens when I out a class in there?
Compiler.compileClasses(string) // hm?
How to can I print a hello message with a Compiler inside Eclipse...?
Reading the documentation is a very important skill you need to learn.
Whenever you come across a class or a method that you don't know the functionality of, simply look at the documentation first.
Here is the docs for java.lang.Compiler: https://docs.oracle.com/javase/7/docs/api/java/lang/Compiler.html
This is the first sentence of the document:
The Compiler class is provided to support Java-to-native-code compilers and related services. By design, the Compiler class does nothing; it serves as a placeholder for a JIT compiler implementation.
So, the answer to your question is, it does nothing. According to the documentation, it does nothing. It is used to start up the Java compiler when the JVM starts. You are not meant to use this.
I know that it is nonsense (or there is no chance) for variables that its value is unknowable until the runtime.
Let's assume that you have a method like this:
public void Foo (BarEnum barVal)
{
//...
if(barVal == BarEnum.UnappropriateForFooMethod)
throw new BlaBlaException("Invalid barVal for Foo method ->" + barVal);
//...
}
This method will already throw an exception for unappropriate parameter. But I intend to warn developer that before run code and get an exception. Main idea is that. It is not important that if she/he do not care about warnings or turned off the warning messages, her/him code will get an exception anyway.
I guess that it is possible with built-in attributes. Like Obsolete. But I could not find anything...
If there is no attribute for this purpose, I am open to suggestions for custom solutions.
From .NET Framework 4 and later there's something called Code Contracts (on GitHub). Never tried it, but looks like what you seek.
There's also Roslyn. Also haven't work with it, but probably does at least something that you want. Being a super-tool, it is probably a bit unwieldy and verbose for your needs.
One workaround to this problem, without using external tools, is to thoroughly review the code.
Having written my Delphi Prism program enough to compile and run on Window and Linux (mono) without compilation errors, I am finding out that my constructors and load events are firing at different order than I expected. I thought, files get executed in the order that they are listed in the project file like in Delphi .dpr file. Speaking of .dpr file, is there a similar file for Delphi Prism that I am not looking into. I looked into program.pas file and properties. I didn't see anything there to give me a hint or clue.
How do you make sure that the project files get executed in right order in Delphi Prism?
Delphi Prism compiles in the order the files are defined in the project. However, there should not be anything that depends on the order of the files as there are no initialization sections.
As for your other question. Program.pas by default contains the entry point, it's a method called "Main", you could see this as the main begin/end.
.NET does not know about the order your classes are listed in your program file. It just sees classes.
Under normal circumstances you could think of this rule:
Static (class) constructors are executed immediately before the instance .ctor or another static (class) method is called on this class for the first time
While this is not true every time (they could be called earlier, but not later), this is a good approximation which works out most of the time.
So to ensure a certain order for static class initialization, I rely on the following:
I have one static class that has an Initialize() method. This method is the first thing I call in the Main() method of my program. In this method I call Initialize-Methods on other classes in the required order. This makes sure, that the initialization code is executed.
I create class libraries, some which are used by others around the world, and now that I'm starting to use Visual Studio 2010 I'm wondering how good idea it is for me to switch to using code contracts, instead of regular old-style if-statements.
ie. instead of this:
if (fileName == null)
throw new ArgumentNullException("fileName");
use this:
Contract.Requires(fileName != null);
The reason I'm asking is that I know that the static checker is not available to me, so I'm a bit nervous about some assumptions that I make, that the compiler cannot verify. This might lead to the class library not compiling for someone that downloads it, when they have the static checker. This, coupled with the fact that I cannot even reproduce the problem, would make it tiresome to fix, and I would gather that it doesn't speak volumes to the quality of my class library if it seemingly doesn't even compile out of the box.
So I have a few questions:
Is the static checker on by default if you have access to it? Or is there a setting I need to switch on in the class library (and since I don't have the static checker, I won't)
Are my fears unwarranted? Is the above scenario a real problem?
Any advice would be welcome.
Edit: Let me clarify what I mean.
Let's say I have the following method in a class:
public void LogToFile(string fileName, string message)
{
Contracts.Requires(fileName != null);
// log to the file here
}
and then I have this code:
public void Log(string message)
{
var targetProvider = IoC.Resolve<IFileLogTargetProvider>();
var fileName = targetProvider.GetTargetFileName();
LogToFile(fileName, message);
}
Now, here, IoC kicks in, resolves some "random" class, that provides me with a filename. Let's say that for this library, there is no possible way that I can get back a class that won't give me a non-null filename, however, due to the nature of the IoC call, the static analysis is unable to verify this, and thus might assume that a possible value could be null.
Hence, the static analysis might conclude that there is a risk of the LogToFile method being called with a null argument, and thus fail to build.
I understand that I can add assumptions to the code, saying that the compiler should take it as given that the fileName I get back from that method will never be null, but if I don't have the static analyzer (VS2010 Professional), the above code would compile for me, and thus I might leave this as a sleeping bug for someone with Ultimate to find. In other words, there would be no compile-time warning that there might be a problem here, so I might release the library as-is.
So is this a real scenario and problem?
When both your LogToFile and Log methods are part of your library, it is possible that your Log method will not compile, once you turn on the static checker. This of course will also happen when you supply code to others that compile your code using the static checker. However, as far as I know, your client's static checker will not validate the internals of the assembly you ship. It will statically check their own code against the public API of your assembly. So as long as you just ship the DLL, you'd be okay.
Of course there is a change of shipping a library that has a very annoying API for users that actually have the static checker enabled, so I think it is advisable to only ship your library with the contract definitions, if you tested the usability of the API both with and without the static checker.
Please be warned about changing the existing if (cond) throw ex calls to Contracts.Requires(cond) calls for public API calls that you have already shipped in a previous release. Note that the Requires method throws a different exception (a RequiresViolationException if I recall correctly) than what you'd normally throw (a ArgumentException). In that situation, use the Contract.Requires overload. This way your API interface stays unchanged.
First, the static checker is really (as I understand it) only available in the ultimate/academic editions - so unless everyone in your organization uses it they may not be warned if they are potentially violating an invariant.
Second, while the static analysis is impressive it cannot always find all paths that may lead to violation of the invariant. However, the good news here is that the Requires contract is retained at runtime - it is processed in an IL-transformation step - so the check exists at both compile time and runtime. In this way it is equivalent (but superior) to a regular if() check.
You can read more about the runtime rewriting that code contract compilation performs here, you can also read the detailed manual here.
EDIT: Based on what I can glean from the manual, I suspect the situation you describe is indeed possible. However, I thought that these would be warninings rather than compilation errors - and you can suppress them using System.Diagnostics.CodeAnalysis.SuppressMessage(). Consumers of your code who have the static verifier can also mark specific cases to be ignored - but that could certainly be inconvenient if there are a lot of them. I will try to find some time later today to put together a definitive test of your scenario (I don't have access to the static verifier at the moment).
There's an excellent blog here that is almost exclusively dedicated to code contracts which (if you haven't yet seen) may have some content that interests you.
No; the static analyzer will never prevent compilation from succeeding (unless it crashes!).
The static analyzer will warn you about unproven pre-/post-conditions, but doesn't stop compilation.