Compilation error C# targeting Java

Hi!

I found a compilation bug. Here is the code:

namespace Test
{
    struct Data
    {
        public readonly int X;
         
        public Data(int x)
        {
            X = x;
        }

        public static Data operator + (Data left, Data right)
        {
            return new Data(left.X + right.X);
        } 
    }

    public class Class1
    {
        public static void Test()
        {
            var origin = new Data();
            
            foreach (var data in new List<Data>())
            {
                var newData = origin + data;
            }
        }
    }
}

It fails with:

E: Internal error: System.NullReferenceException: Object reference not set to an instance of an object
  at f.a (RemObjects.Oxygene.Code.BaseType a, System.Boolean b) [0x00257] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at f.b (RemObjects.Oxygene.Code.BaseType a) [0x00000] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at i.VisitScopeStatement (RemObjects.Oxygene.Code.ScopeStatement a) [0x00074] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at i.VisitStatement (RemObjects.Oxygene.Code.Statement a) [0x001af] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at i.VisitBeginStatement (RemObjects.Oxygene.Code.BeginStatement a) [0x0002b] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at i.VisitStatement (RemObjects.Oxygene.Code.Statement a) [0x00195] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at i.VisitWhileStatement (RemObjects.Oxygene.Code.WhileStatement a) [0x000ab] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at i.VisitStatement (RemObjects.Oxygene.Code.Statement a) [0x001f0] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at i.VisitTryStatement (RemObjects.Oxygene.Code.TryStatement a) [0x000a7] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at i.VisitStatement (RemObjects.Oxygene.Code.Statement a) [0x00224] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at i.VisitIfStatement (RemObjects.Oxygene.Code.IfStatement a) [0x000b3] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at i.VisitStatement (RemObjects.Oxygene.Code.Statement a) [0x001c9] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at i.VisitBeginStatement (RemObjects.Oxygene.Code.BeginStatement a) [0x0002b] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at i.VisitStatement (RemObjects.Oxygene.Code.Statement a) [0x00195] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at i.VisitIfStatement (RemObjects.Oxygene.Code.IfStatement a) [0x000b3] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at i.VisitStatement (RemObjects.Oxygene.Code.Statement a) [0x001c9] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at i.VisitBeginStatement (RemObjects.Oxygene.Code.BeginStatement a) [0x0002b] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at i.VisitStatement (RemObjects.Oxygene.Code.Statement a) [0x00195] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at RemObjects.Oxygene.Code.BaseVisitor.VisitScopeStatement (RemObjects.Oxygene.Code.ScopeStatement element) [0x00007] in <7d7d6c1a816a42ca8edae363c82d5028>:0 
  at i.VisitScopeStatement (RemObjects.Oxygene.Code.ScopeStatement a) [0x000a6] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at i.VisitStatement (RemObjects.Oxygene.Code.Statement a) [0x001af] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at i.VisitBeginStatement (RemObjects.Oxygene.Code.BeginStatement a) [0x0002b] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at i.VisitStatement (RemObjects.Oxygene.Code.Statement a) [0x00195] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at RemObjects.Oxygene.Code.BaseVisitor.VisitScopeStatement (RemObjects.Oxygene.Code.ScopeStatement element) [0x00007] in <7d7d6c1a816a42ca8edae363c82d5028>:0 
  at i.VisitScopeStatement (RemObjects.Oxygene.Code.ScopeStatement a) [0x000a6] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at i.VisitStatement (RemObjects.Oxygene.Code.Statement a) [0x001af] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at RemObjects.Oxygene.Code.BaseVisitor.Visit (RemObjects.Oxygene.Code.Node element) [0x00c69] in <7d7d6c1a816a42ca8edae363c82d5028>:0 
  at f.a (RemObjects.Oxygene.Code.IMethodInfo a) [0x010a0] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at RemObjects.Oxygene.Code.CombinedParsedType.ForAllMethods (System.Func`2[T,TResult] action) [0x00053] in <7d7d6c1a816a42ca8edae363c82d5028>:0 
  at f.a (RemObjects.Oxygene.Code.IParsedType a) [0x00073] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at f.f () [0x0002e] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at f.GenerateExecutable () [0x0001a] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at RemObjects.Oxygene.Code.Compiler.Compiler.GenerateExecutable () [0x00000] in <7d7d6c1a816a42ca8edae363c82d5028>:0 
  at RemObjects.Oxygene.Code.Compiler.Compiler.Compile () [0x001ac] in <7d7d6c1a816a42ca8edae363c82d5028>:0 

The fix is to use the proper type instead of var on the foreach:

       foreach (Data data in new List<Data>())
       {
           var newData = origin + data;
       }

Hope you can fix this soon.

Thanks!

That does sound like a compiler bug, but unfortunately I cannot reproduce this by just pasting suer code into a new console app (I get one error:

foreach (var data in new List<Data>()) // E121 Cannot instantiate interface type "java.util.List<Data?!>"

Can you send me your project, and also can you see if the attached project shows the same IE for you (maybe something got changed.fixed there already, if you’re on an older build; I’m using 2501):

consoleapplication3 1.bugreport.zip (6.3 KB)

That said, this errors still seems to be wrong, so I’ll log that one as a bug…

yours,
marc

Thanks, logged as bugs://84178

Hm, actually, List is an interface s that error is as designed:

public interface List<Data>
{

remember, each platform ha sits own set of types; System.Collections.Generic.List<T> is part of the .NET platform, not of the C# language spec. I think ArrayList is the closest equivalent, on Java.

You can use Elements RTL to get a common set of types that work across all supported platforms; without it, you’re dealing with each platforms native types and the don’t always look (or behave (!) the same, everywhere).

Hi!,

I forgot to mention that I’m using RTL and I set it as default import as described on

For ease of use, we recommend adding RemObjects.Elements.RTL to the global " Default Uses " Project Setting.

So List is the RTL implementation.

/Simon

On the example project provided by you, if you delete the using statement on top, it will then use RTL List implementation and you will get the same compilation error I described.

I’m using the latest public build

Ah yes, me too, but mt file had “using java.util;” at the top which overrode that.

I now get

E:                   Internal error: System.NullReferenceException: Object reference not set to an instance of an object
  at RemObjects.Oxygene.Code.Output.Java.JavaOutput.GetType (RemObjects.Oxygene.Code.BaseType aType, System.Boolean aIsBoxingContext) [0x00257] in <a009c8035a3b4cbb99dc7e26b85e3066>:0 
  at RemObjects.Oxygene.Code.Output.Java.JavaOutput.GetType (RemObjects.Oxygene.Code.BaseType aType) [0x00000] in <a009c8035a3b4cbb99dc7e26b85e3066>:0 
  at RemObjects.Oxygene.Code.Output.Java.OutputGeneratorVisitor.VisitScopeStatement (RemObjects.Oxygene.Code.ScopeStatement element) [0x00074] in <a009c8035a3b4cbb99dc7e26b85e3066>:0 
  at RemObjects.Oxygene.Code.Output.Java.OutputGeneratorVisitor.VisitStatement (RemObjects.Oxygene.Code.Statement element) [0x001af] in <a009c8035a3b4cbb99dc7e26b85e3066>:0 
  at RemObjects.Oxygene.Code.Output.Java.OutputGeneratorVisitor.VisitBeginStatement (RemObjects.Oxygene.Code.BeginStatement beginStatement) [0x0002b] in <a009c8035a3b4cbb99dc7e26b85e3066>:0 
  at RemObjects.Oxygene.Code.Output.Java.OutputGeneratorVisitor.VisitStatement (RemObjects.Oxygene.Code.Statement element) [0x00195] in <a009c8035a3b4cbb99dc7e26b85e3066>:0 
  at RemObjects.Oxygene.Code.Output.Java.OutputGeneratorVisitor.VisitWhileStatement (RemObjects.Oxygene.Code.WhileStatement whileStatement) [0x000ab] in <a009c8035a3b4cbb99dc7e26b85e3066>:0 

Updated the logged bug to reflect that.

Hi Just found another compilation error that seems to be related:

Using the same Data struct from before.

var origin = new Data();
new List<Data>().Select(data => data + origin);

E: Internal error: System.NullReferenceException: Object reference not set to an instance of an object
  at f.a (RemObjects.Oxygene.Code.BaseType a, System.Boolean b) [0x00257] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at f.b (RemObjects.Oxygene.Code.BaseType a) [0x00000] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at f.a (RemObjects.Oxygene.Code.IMutableMethodImplementation a, RemObjects.Oxygene.Java.ClassDefinition b) [0x004bd] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at f+<>c__DisplayClass1.<a>b__1 (RemObjects.Oxygene.Code.IMemberInfo el) [0x00063] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at RemObjects.Oxygene.Code.CombinedParsedType.ForAllMembers (System.Func`2[T,TResult] action) [0x0003c] in <7d7d6c1a816a42ca8edae363c82d5028>:0 
  at f.a (RemObjects.Oxygene.Code.IMutableParsedType a) [0x0027d] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at f.a (RemObjects.Oxygene.Code.IMutableParsedType a) [0x002bc] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at f.e () [0x0002e] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at f.GenerateExecutable () [0x00014] in <7c57d2ac02f04fd280695424e0ae7c47>:0 
  at RemObjects.Oxygene.Code.Compiler.Compiler.GenerateExecutable () [0x00000] in <7d7d6c1a816a42ca8edae363c82d5028>:0 
  at RemObjects.Oxygene.Code.Compiler.Compiler.Compile () [0x001ac] in <7d7d6c1a816a42ca8edae363c82d5028>:0 

I think it is related because is like the compiler doesn’t know how to handle the + operator on the struct. If I cast the param, then it does compile.

var origin = new Data();
new List<Data>().Select(data => (Data)data + origin);

Reproduced and added to the issue; probably related, yes.

And another one:

var dataList = new List<Data> {new Data(1)};
var newData = origin + dataList[0];

The fix is to cast again:

var dataList = new List<Data> {new Data(1)};
var newData = origin + (Data)dataList[0];

Added