dotnet-websharper / core

WebSharper - Full-stack, functional, reactive web apps and microservices in F# and C#
https://websharper.com
Apache License 2.0
591 stars 52 forks source link

WebSharper Compiler throws exception when same name is used for static and non-static member #704

Open amieres opened 7 years ago

amieres commented 7 years ago

This little example throws:

[<WebSharper.JavaScript>]
module test =

  type Type = Type with
    static member inline Member x = x
    member inline   this.Member x = x

with exception:

System.ArgumentException: An item with the same key has already been added.
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at <StartupCode$WebSharper-Compiler>.$Compilation.resolveRemainingInstanceMembers@1229-1.Invoke(String n)
at <StartupCode$WebSharper-Compiler>.$Compilation.resolveRemainingInstanceMembers@1173(Compilation this, FSharpTypeFunc printerrf, Resolver r, Dictionary`2 remainingInstanceMembers, HashSet`1 resolved, Hashed`1 typ, ClassInfo cls, FSharpList`1 ms)
at WebSharper.Compiler.Compilation.Resolve()
at WebSharper.Compiler.FSharp.ProjectReader.transformAssembly(Compilation comp, String assemblyName, FSharpCheckProjectResults checkResults)
at WebSharper.Compiler.FSharp.WebSharperFSharpCompiler.Compile(Task`1 prevMeta, String[] argv, String path, String assemblyName)
Jand42 commented 7 years ago

Hi, thanks for the report!

I found a bit strange that F# compiler allows this, but indeed, F# can resolve the uses correctly. I would still think this is bit of bad practice because it is an unresolvable ambiguity from C#.

F# 4.1 has support for inplicit "Module" suffix for modules and types with the same name (we will release a WebSharper 4 version with full support for F#4.1/C#7 very soon), so this is one possible workaround:

    type Type = Type with
        member inline this.Member x = x

    module Type =
        let inline Member x = x
amieres commented 7 years ago

Thanks for the tip!

Jand42 commented 6 years ago

Keeping this open, as the error message could use some improvement, even if WS will continue to not allow it.

V0d01ey commented 6 years ago

Hello! I've got the same exception when trying to build C# project:

1>  Creating Roslyn compilation: 00:00:02.7370000
1>WEBSHARPERTASK : WebSharper error : Global error 'Элемент с тем же ключом уже был добавлен.' at    в System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)   в System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)   в <StartupCode$WebSharper-Compiler>.$Compilation.resolveRemainingInstanceMembers@1321-1.Invoke(String n)   в <StartupCode$WebSharper-Compiler>.$Compilation.resolveRemainingInstanceMembers@1265(Compilation this, FSharpTypeFunc printerrf, Resolver r, Dictionary`2 remainingInstanceMembers, HashSet`1 resolved, Hashed`1 typ, ClassInfo cls, FSharpList`1 ms)   в <StartupCode$WebSharper-Compiler>.$Compilation.resolveRemainingInstanceMembers@1265(Compilation this, FSharpTypeFunc printerrf, Resolver r, Dictionary`2 remainingInstanceMembers, HashSet`1 resolved, Hashed`1 typ, ClassInfo cls, FSharpList`1 ms)   в WebSharper.Compiler.Compilation.Resolve()   в WebSharper.Compiler.CSharp.ProjectReader.transformAssembly(Compilation comp, CSharpCompilation rcomp)   в WebSharper.Compiler.CSharp.WebSharperCSharpCompiler.Compile(Info refMeta, IEnumerable`1 argv, String path)   в WebSharper.CSharp.Program.Compile$cont@49(WsConfig config, Boolean isBundleOnly, Unit unitVar)   в WebSharper.CSharp.Program.compileMain$cont@177(String[] argv, Unit unitVar)
1>  The command exited with code 1.
1>Done executing task "WebSharperTask" -- FAILED.
1>Done building target "WebSharperCompile" in project "WebPrime.csproj" -- FAILED.

How can it be resolved? Add some information to the error message about the duplicate key please.

V0d01ey commented 6 years ago

Found that this code

    [JavaScript]
    public class LayoutObject
    {
        public const int k = -2;

        public virtual float GetT()
        {
            return 0;
        }
    }

gives the exception.