Resolving type created by CSharpElementFactory.CreateExpression

If  I create a new expression using the CSharpElementFactory.CreateExpression method how can I get this to resolve successfully, the new expression is test whether a certain overload would be valid for an invocation expression (method call).

Trying the following, does not work becuase the 'Type' is unknown:

     var result = invocationExpression.Type().GetScalarType().Resolve();

So I guess I want to know when I call CreateExpression how can I make sure the Type is NOT UnknownType.


ta

Ollie

3 comments
Comment actions Permalink

Hi.
Hi. You need to set context for code fragment to get types resolved. Context is a tree node in a file belonging to a project. You can set context using SetResolveContextForSandBox extension method. Type resolve will use context information from the provided tree node.

0
Comment actions Permalink

Hi,

I tried what you suggested but it lead to some strange results, I think I might have something wrong.

I am using the following code to determine if a new expression is valid by attempt to resolve the scalar type and checking the IsResolved property:

var module = expression.GetPsiModule();
var elementFactory = CSharpElementFactory.GetInstance(module);

var newExpression = elementFactory.CreateExpression(newText);
var invocationExpression = newExpression;

newExpression.SetResolveContextForSandBox(expression);

var type = invocationExpression.Type().GetScalarType();
var result = type.Resolve();

var isResolved = type.IsResolved;



I attempting to replace the following:

     Observable.Return(42);

with:

     Observable.Return(42, System.Reactive.Concurrency.Scheduler.Immediate);


Now this does resolve correctly as expected but when I use the following this also resolves correctly even thought it would not compile:

     Observable.Return(42, This.Should.Not.Resolve);

Where as the following will not resolve (as expected) because there isn't an overload with these parameters:

     Observable.Return(42, 42);


So, am I doing something wrong when resolving or am I using the API incorrectly - it's not designed to guarantee it will compile?




ta

Ollie
0
Comment actions Permalink

Seems that you are trying to calculate type for expression 'Observable.Return(42, System.Reactive.Concurrency.Scheduler.Immediate)' which is a return type of the method 'Return' and it doesn't depend on the arguments provided. Creating expression from text is not the best way of using PSI. If you need to add argument that references 'System.Reactive.Concurrency.Scheduler.Immediate' you'd better find 'Scheduler' class by it's FQN in the SymbolCache. After that you can find property 'Immediate' in this class and create expression that references exactly that property using '$' syntax that is allowed in elements factory.

IExpression expression = null;

// API here can be different in version 7.1, should be smth. like GetSymbolCache inplace of Symbls

var symbolScope = expression.GetPsiServices().Symbols.GetSymbolScope(expression.GetPsiModule(), true, null);

var typeElement = symbolScope.GetTypeElementByCLRName("System.Reactive.Concurrency.Scheduler");

var immediateProperty = typeElement.Properties.Where(x => x.ShortName == "Immediate").FirstOrDefault();

elementFactory.CreateExpression("$0", immediateProperty);

0

Please sign in to leave a comment.