Akim
Akim

Reputation: 8679

Could Roslyn compile await keyword?

While working with latest version of I have found that it does not support dynamic keyword while compiling and script execution, i.e. you will get an compiling error error CS8000: This language feature ('dynamic') is not yet implemented in Roslyn. Here is a short code snippet:

var engine = new ScriptEngine();
var script = @"dynamic someVariable = 0;";
// you an error CS8000: This language feature ('dynamic') is not yet implemented in Roslyn
engine.CreateSession().Execute(script);

While working with await keyword…

In contrast, while working with await keyword at compilation or script, I usually got some random compilation error like one of followings:

Sample of scripting

var engine = new ScriptEngine();

new[]
{
    "System", "System.Threading", "System.Threading.Tasks",
} .ToList().ForEach(@namespace => engine.ImportNamespace(@namespace));

var script = @"await Task.Run(() => System.Console.WriteLine(""Universal [async] answer is '42'""));";

engine.CreateSession().Execute(script);

Sample of compilation

// compilation sample
const string codeSnippet = @"namespace DemoNamespace
    {
        using System;
        using System.Threading;
        using System.Threading.Tasks;

        public class Printer
        {
            public async void Answer() 
            {
                var answer = 42;
                var task = Task.Run(() => System.Console.WriteLine(string.Format(""Universal [async] answer is '{0}'"", answer)));
                await task; // not working
                task.Wait(); // working as expected
            }
        }
     }";

var syntaxTree = SyntaxTree.ParseText(codeSnippet,
     options: new ParseOptions(languageVersion: LanguageVersion.CSharp5));

var references = new []
{
    MetadataReference.CreateAssemblyReference(typeof(Console).Assembly.FullName),
    MetadataReference.CreateAssemblyReference(typeof(System.Threading.Tasks.Task).Assembly.FullName),
};

var compilation = Compilation.Create(
                        outputName: "Demo", 
                        options: new CompilationOptions(OutputKind.DynamicallyLinkedLibrary),
                        syntaxTrees: new[] { syntaxTree },
                        references: references);

if(compilation.GetDiagnostics().Any())
{
    compilation.GetDiagnostics().Select(diagnostic => diagnostic).Dump();
    throw new Exception("Compilation failed");
}

Assembly compiledAssembly;
using (var stream = new MemoryStream())
{
    EmitResult compileResult = compilation.Emit(stream);
    compiledAssembly = Assembly.Load(stream.GetBuffer());
}

dynamic instance = Activator.CreateInstance(compiledAssembly.GetTypes().First());
instance.Answer();

Q: Am I missing something or it is not implemented yet?

I have tried different configuration with LanguageVersion.CSharp5 and without. Both Google and Stackoverflow searches are full of marketing hype for both and keywords and almost useless. Microsoft "Roslyn" CTP forum also has no answer for this.

ps: as far as I know async keyword has introduced for readability both by humans and compilers while await does all magic

Upvotes: 8

Views: 1832

Answers (2)

svick
svick

Reputation: 244868

Actually, the Roslyn forum does have the answer. If you look at the post Known Limitations and Unimplemented Language Features, you'll notice that it contains “Async” among the not yet implemented features in C#.

That list is about the June CTP, but since the list of changes between the June CTP and the December CTP doesn't list async, it means it's simply not implemented yet.

I think the reason for the difference in error message is that Roslyn does understand dynamic (but doesn't implement it yet). On the other hand, it doesn't understand async-await, so it gives you generic compilation errors.

Upvotes: 5

Kevin Pilch
Kevin Pilch

Reputation: 11615

await support is not implemented in the current Roslyn CTP (although it is now implemented in internal builds).

The reason for the difference in error reporting is that we first built the Roslyn parser so that it could handle the entire C# 4 language, and then filled in semantics for features one at a time. Since await is a C# 5 feature, it is not even recognized by the parser, and there is no place to recognize its use and provide a good error.

Upvotes: 9

Related Questions