praeclarum / Netjs

Compile .NET assemblies to TypeScript and JavaScript
MIT License
964 stars 134 forks source link

CsToTs creates constructor for "any" #27

Open duncanwerner opened 8 years ago

duncanwerner commented 8 years ago

This code:

    public class Class1
    {
        private object X = new object();
    }

results in typescript:

class Class1 extends NObject
{
    private X: any = new any();
    constructor()
    {
        super();
    }
}

which is invalid as any isn't supposed to be instantiated, and the error runs through tsc to javascript. (That should be private X: any = new Object();)

I think this pattern is used to construct generic objects for use in lock and synchronization functions. I'm not 100% sure of my fix, so I'm not submitting it as a patch just yet, but I think the way to fix it is to check in GetPrimitiveTypeReplacement if the parent is a constructor:

public static PrimitiveType GetPrimitiveTypeReplacement (PrimitiveType primitiveType)
{
  switch (primitiveType.KnownTypeCode) {
  case KnownTypeCode.Object:
    if (isAnyConstructor(primitiveType)) return new PrimitiveType("Object");
    return new PrimitiveType ("any");

using the test function

private static bool isAnyConstructor(PrimitiveType primitiveType)
{
  if (null == primitiveType.Parent
    || null == primitiveType.Parent.Annotations ) return false;

  foreach (object obj in primitiveType.Parent.Annotations) {
    Mono.Cecil.MethodReference mr = obj as Mono.Cecil.MethodReference;
    if (null != mr && mr.Name == ".ctor") return true;
  }
  return false;
}

but I'm not really familiar with NRefactory, so there's probably a simpler way to do it.

praeclarum commented 6 years ago

Great catch, thanks.