iOS Xamarin Roslyn

The Roslyn Report: Writing Diagnostic Analyzers for Xamarin - Part 2

A diagnostic for Xamarin

In the last post we left of with Roslyn installed, with Xamarin.iOS.dll copied to our machine and a bare analyzer project created. In this post I will show how to write a first Monotouch analyzer.

A iOS/Monotouch problem to analyse

As Adam points out in his blog, a UIView should not size itself, but only its children views and controls. So the following code should generate a warning:

For an explanation see Adams Blog: "Violation 1".

Create a test case

First we create a test case in our project. The Microsoft template propses to insert the testcode in a string. In my opinion it is much easier to add the code as a normal file, exclude it from compilation and load it as string into the unit test. That would look as following:

Notice the change in the Build action to "Content" and "Copy if newer". It brings the file to the Output dir, so it is loadable rom the Unit test. The real benefit is the working Roslyn code window in the lower area. It shows the syntax tree for the current statement - an IdentifierName in a SimpleMemberAccessExpression.

Make this code snippet Roslyn compileable

If we try to run an analyzer on this code fragment, Roslyn would complain, because it can not resolve UIKit. The assembly is missing. To fix this we have to add a reference to Xamarin.iOS.dll. This can be done in the DiagnosticVerifier:

The unit test for this code should now run and default implementation will complain about the lowercase identifiers.

The real analyzer

The task is now to write an analyzer, which finds "Frame" statements and checks them if they belong directly to the current UIView type.

First we wire up the method AnalyzeIdentifier to SimpleAssignmentExpression in the Initialize method. Remember the Roslyn code window? That should be the nearest point for further investigations.

Next we make a syntax check for "Frame" on the descendant nodes. If we find a "Frame" we check if there is anything but a "base" or "this" statement in the left part of the assignement. If that would be the case, the assignement would be to a "Frame" of a child view (which is perfectly fine).

Now we start a semantic analysis. With the property symbol from the AST we simple run up the tree to find the enclosing type (class) of the current statement. If this type has "UIView" as its base class we have a violation of our rule! Why? We now know that its s direct assignement to the property "Frame" of the current class and thats the class is a "UIView".

That's it! We now can detect defaults to our rule. The code to detect syntactical or semantical situations seems pretty easy when you read it. But honestly it can be darn hard to write. The Roslyn syntax windows is a great help and some practice doesn't hurt either. Bit it's great fun!

Happy coding!

The Roslyn Report: Writing Diagnostic Analyzers for Xamarin - Part 1

The Task:

One of the most important thing when developing iOS and Xamarin are the UIView and the UIViewController with their numereous events. All the wiring of logic and UI and also the layouting happens here. Even when you use Frameworks like MVVM or XIBs you are dependant to the flow of LoadView and ViewWillDisappear. Adam Kemp has an excellent blog describing what to do on which stage of the iOS Layout process:

But how can one controll the code to obey the rules Adam described in his blog? Enter Roslyn - the new Microsoft compiler engine with the possibility to write own code diagnosis routines! See the github page for additional doku and the MSDN site for a reference.

The Setup:

What do we need to get Roslyn going? The easiest way is to use the current Azure Visual Studio 2015 VM. Additionaly we need:

After the setup you should have a running VS2015 with this new project template:

When you create a project you get a solution with the following structure:

  • Analyzer (Portable): The analyzer
  • Analyzer.Test: Unit tests for the analyzer
  • Analyzer.Vsix: A Visual Studio installer for the analyzer.

A diagnostic for Xamarin

Because Roslyn analyses code fragments with partial compilation the Xamarin.iOS.dll from C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\Xamarin.iOS\v1.0\ is needed to compile and diagnose Xamarin code fragments. Copy it over from your development environment to the Azure VM. I would suggest to copy it to the same folder again. Then reference it from the Unit Test project to get it into build output directory and make it loadable by Roslyn.

In the next entry I will show how to write a Roslyn code analysis ...