Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Could Roslyn compile await keyword?

While working with latest version of roslyn-ctp 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:

  • error CS1001: Identifier expected
  • error CS1003: Syntax error, ',' expected
  • error CS0246: The type or namespace name 'await' could not be found (are you missing a using directive or an assembly reference?)

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 roslyn and async 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

like image 947
Akim Avatar asked Mar 09 '13 16:03

Akim


1 Answers

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.

like image 170
Kevin Pilch Avatar answered Sep 25 '22 02:09

Kevin Pilch