DeclaredElement return type is ???

I'm trying to analyse a method and when debuggintg it has a return type as ??? even though the type is declared in the .Net framework (4.0), the return type should be IObservable<T>.

Why is the return type uinknown for this method declaration (IMethodDeclaration)?


Cheers

Ollie Riches

7 comments
Comment actions Permalink

This usually means the file isn't "correct" - there's a syntax or reference error somewhere. Perhaps the method isn't declared properly (no braces, no body, missing brackets, that sort of thing), or the return type isn't referenced correctly. In other words, ReSharper knows there should be a declared element at that point, but doesn't know what that element is. Instead, it gives you a declared element with a name of "???" - this is constant defined in SharedImplUtil.MISSING_DECLARATION_NAME. In your code, you can check for declaredElement.ShortName == SharedImplUtil.MISSING_DECLARATION_NAME to know that there's code you can't analyse, and break out of your processing early.

0
Comment actions Permalink

Matt,

Thanks for the info...

I thought it might be an issue with the test file I'm using and made sure this compiled as expected in the unit test project.

I'll double check this later and report back.


Thanks for the hlep


Ollie

0
Comment actions Permalink

This is the test file I am using for the test fixture. I even included this file as a compiled file in the test fixture and this compiled perfectly fine.

The type IObservable<T> is defined in the core (.Net) framework, it is not part of the Reactive Extensions add-on - so why is resharper not able to resolve the return type for IsReady.

The only other consideration is this is a .Net 4.0 assembly and test assembly.

Cheers

Ollie


namespace Resharper._7._1.ReactivePlugin.Tests
{
    using System;
    using System.Reactive.Concurrency;
    using System.Reactive.Linq;

    class Program
    {
        static void Main(string[] args)
        {
            Observable.Return(42);
        }

        static int Number()
        {
            return 42;
        }

        static IObservable<bool> IsReady()
        {
            return Observable.Return(true);
        }

        static IObservable<bool> IsReadyWithScheduler(IScheduler scheduler = null)
        {
            return Observable.Return(true, scheduler);
        }
    }
}

0
Comment actions Permalink

Yep, the issue is that you're trying to test a .net 4 project. The test system creates a temp solution and project to host your test files in, allowing ReSharper to parse or otherwise handle the file in the right context. By default, it sets up a .net 3.5 project, and .net 3.5 doesn't now about IObservable. This is easily fixed - just add the [TestNetFramework4] attribtute to your test method or class.

There are a bunch of other attributes you can add to change behaviour like this - look for the derived classes of ITestPlatformProvider (such as TestNetFramework4, TestSilverlight2, TestWindowsPhone70, TestMvc4, etc) or derived classes of ITestFlavoursProvider, which can provide the extra guids that change a normal C# project into a Sharepoint or Windows Phone project. There's also ITestMsCorLibFlagProvider, ITestSdkReferencesProvider and ITestLibraryReferncesProvider, which affect what assembly references are made in the project.

Thanks
Matt

0
Comment actions Permalink

Matt - thanks you're a star!



Ollie

0
Comment actions Permalink

Matt,

I suppose this is a general question about the way R# PSI relates to .Net type system.

I can see the return type, but how can I validate the return type - I want to make sure it is from a specific .Net assembly?


return type.png

0
Comment actions Permalink

The IType returned has an inherited property of Module, which is an IPsiModule. This represents either the Visual Studio project or assembly that the type is defined in. You can try to downcast to IAssemblyPsiModule, which will then give you an IPsiAssembly with all the info you need to get at. Or you can use IPsiModule.ContainingProjectModule, which will return you an IModule which you can then downcast to IAssembly or IProject (these types are part of the Project Model, rather than the PSI. The hierarchies are similar, but intended for different purposes - these are for loading and building projects, while the PSI is for introspection of abstract syntax trees and references).

Alternatively, and I'm less sure on this one, you can downcast the IType to IDeclaredType (this might return null!) and that then gets you an AssemblyNameInfo which should give you the info you need. I'm less sure on this because I don't know if you can always downcast that IType to an IDeclaredType.

0

Please sign in to leave a comment.