scriptsharp icon indicating copy to clipboard operation
scriptsharp copied to clipboard

Incomplete Interface Inheritance In Import libraries

Open Emdot opened this issue 12 years ago • 4 comments

When I create [Imported] interfaces in an import library and use them from a Script# script library, the Script# compiler fails when compiling a line where an inherited member is accessed from a derived interface. A minimal test case follows:

ImportLibraryFile.cs in an import library:

using System.Runtime.CompilerServices;

namespace N
{
    [Imported]
    public interface A
    {
        void Go();
    }

    [Imported]
    public interface B : A
    {
    }
}

Consumer.cs in a script library that references the import library:

using System;
using System.Runtime.CompilerServices;
using N;

namespace ScriptSharpTest2
{
    [GlobalMethods]
    public static class Test
    {
        public static void Main()
        {
            B b = null;
            b.Go();
        }
    }
}

The error produced is:

Error   1   
Check that your C# source compiles and that you are not using an unsupported feature. Common things to check for include use of fully-qualified names (use a using statement to import namespaces instead) or accessing private members of a type from a static member of the same type.
Consumer.cs, Line 13, Column 13     <-- this refers to b.Go() line

This example works correctly if I use class instead of interface (and make the necessary changes that go along with that). Usage of [IgnoreNamespace] and [ScriptName] do not appear to affect the results.

I am using the Script# plugin (version 0.7.5) in Visual Studio 2012 Pro (version 11.0.51106.01 Update 1).

Emdot avatar Jan 11 '13 03:01 Emdot

Continuing the stack overflow question ... where you asked what the changes required might be:

The first thing to be done is remove the rule in the validator that prevents interface inheritance - this is simple enough. It is in https://github.com/nikhilk/scriptsharp/blob/cc/src/Core/Compiler/Validator/CustomTypeNodeValidator.cs

This rule was there since previously the script runtime (in ss.js/mscorlib.js) did not walk inherited interfaces to do "is" checks and type assignability checks.

  • This can be simplified by flattening the list of interfaces when generating a class definition. The class registration is done in GenerateRegistrationScript in https://github.com/nikhilk/scriptsharp/blob/cc/src/Core/Compiler/Generator/TypeGenerator.cs.
  • This is based off of the interfaces property of ClassSymbol. Will need to check whether the behavior can be changed, or a new property needs to be introduced.
  • InterfaceSymbol (https://github.com/nikhilk/scriptsharp/blob/cc/src/Core/Compiler/ScriptModel/Symbols/InterfaceSymbol.cs) needs to start holding on to parents... like ClassSymbol does.

The parts I fear will require some more work are how potential generic base interfaces are handled. And how members are looked up by potentially walking the interface hierarchy. Both of these are done for ClassSymbol, so its doable certainly.

nikhilk avatar Jan 13 '13 01:01 nikhilk

Thanks! I'll take a look at whether it's something that I can reasonably do well in the time I can spend on it. If so I may ask another question or two. (If not, I have the ugly work-around working. -smile-)

Emdot avatar Jan 13 '13 04:01 Emdot

Hi Nikhil,

Since I'm only interested in interfaces that are marked with [Import], CustomTypeNodeValidator.Validate and TypeGenerator don't apply. InterfaceSymbol.cs got me where I needed to be, though.

Since the error is happening during compilation of the project that uses the interface rather than the one that defines it, I'm suspicious of the code that reflects over the import library's DLL to populate the TypeSymbol's members. It looks to me that the root problem is in ScriptSharp.Importer.MetadataImporter.ImportAssemblies (which never calls ImportBaseType for interfaces) and in ImportBaseType (which always passes null for interface inheritance). I plan to make small changes in those two locations, and to move the inheritance-related members from ClassSymbol to TypeSymbol.

Sounds sane?

--Matt

Emdot avatar Jan 13 '13 22:01 Emdot

Hi Emdot and Nikhil,

I'm interested in having Interface Inheritance working for all Script# generated code (not just [Imported] functions). Is this already a planned/requested feature?

As Nikhil said:

previously the script runtime (in ss.js/mscorlib.js) did not walk inherited interfaces to do "is" checks and type assignability checks

Does this mean that the current version does check inherited interfaces? Would that mean that removing the "Derived interface types are not supported" validator is all that is required?

I'd be happy to contribute this feature, but I'd like to know how much work is really involved and what challenges might prevent it's implementation. Note that I'm not really interested in generic interfaces (these could be still disallowed by the validation rules).

Thanks for your help!

badcommandorfilename avatar May 26 '13 00:05 badcommandorfilename