Valid parent syntax of labmda expression

Topics: C# Language Design
Nov 15, 2014 at 3:38 PM
Edited Nov 15, 2014 at 4:44 PM
Hi everybody.
I'm writing "yet another" c#-to-javascript translator with translation-time type inference. So I'm struggling with delegates and labda expressions translation now. I need to infer type of lambda expression arguments. Well, I tried to find a kind of common algorithm and didnt get luck this way. So I'm going simply to analyze in which cases lambda expressions could arrive and then apply different methods of type inference. Talking in roslyn terminology I need to make a list of all possible "parent" Syntaxes which could contain lambda expression as child node. Coming up immediately:
  • ReturnStatementSyntax (lambda colud be returned from method)
  • ArgumentSyntax (lambda could be passed as argument)
  • InitializerExpressionSyntax (multiple lambdas could be passed for array creation. not sure)
  • EqualsValueClauseSyntax (local variable could be initialized by lambda expression)
and.. Any more? Please help. Seems that I'm stuck with it :)
Thanks in advance!

Image
Coordinator
Nov 19, 2014 at 4:14 AM
Hi Pavel,

There are several approaches one could use to infer the type of lambda expressions and their parameters.

First:
  1. Pass the lambda expression into the SemanticModel.GetTypeInfo method and you'll get a TypeInfo object back.
  2. The TypeInfo object has a ConvertedType property which is the ITypeSymbol for the delegate type of the lambda.
  3. From that type symbol look for its "Invoke" method with the GetMembers method. It will return a method symbol for the delegate invoke method.
  4. You can inspect that method symbol to determine the parameter types and return type of the lambda.
Alternately: if you really just want the lambda parameter types
  1. Pass each parameter into SemanticModel.GetDeclaredSymbol. It'll return the IParameterSymbol object declared by that lambda.
  2. Inspect the parameter symbol for its type.
Lastly:
  1. Pass the entire lambda expression into GetSymbolInfo you'll get back an IMethodSymbol for the lambda itself.
  2. You can directly inspect it for its return type, parameter types, and parameter names.
With these approaches you shouldn't need an exhaustive set of places where lambdas could appear or to special case each of them.

Regards,

Anthony D. Green, Program Manager, Visual Basic & C# Languages Team
Marked as answer by PavelBNovikov on 11/19/2014 at 5:11 AM
Nov 19, 2014 at 12:11 PM
Thanks a lot, Anthony! It really simplifies the things.
I should create entire Compilation object to access SemanticModel. I didn't suppose so and my translator abstraction heirarchy is not ready for that :) So, seems that I should think over little architectural refactoring and integrate with Roslyn more closely.
Thanks, this way is quite acceptable.