microsoft / ClearScript

A library for adding scripting to .NET applications. Supports V8 (Windows, Linux, macOS) and JScript/VBScript (Windows).
https://microsoft.github.io/ClearScript/
MIT License
1.77k stars 148 forks source link

host object and type with same name #495

Closed Tor012 closed 1 year ago

Tor012 commented 1 year ago

Hello, is it possible to use "global members" if member and type have the same name?

Sample code here

using System;
using System.Drawing;
using Microsoft.ClearScript;
using Microsoft.ClearScript.Windows;
using Microsoft.VisualBasic.CompilerServices;

namespace ConsoleApp1
{
    internal class Program
    {
        public static void Main()
        {
            using (var engine = new VBScriptEngine())
            {
                var vCar = new CarDef() { name = "myCar", color = "yellow" }; ;

                engine.AddHostTypes(vCar.GetType().Assembly.GetTypes());
                engine.AddHostObject("car", HostItemFlags.GlobalMembers, vCar);

                //ok
                Console.WriteLine(engine.Evaluate("car.CarSpecs.CarType Is CarSpecs.enCarType.Cabrio"));
                //error
                Console.WriteLine(engine.Evaluate("CarSpecs.CarType Is CarSpecs.enCarType.Cabrio"));
            }
            Console.ReadLine();
        }
    }

    public partial class CarDef
    {
        public string name { get; set; } = "";
        public string color { get; set; } = "";
        public CarSpecs CarSpecs { get; set; } = new CarSpecs();
    }

    public partial class CarSpecs
    {
        public enum enCarType
        {
            SUV = 1,
            Cabrio = 2,
            Coupe = 3
        }
        public enCarType CarType { get; set; } = enCarType.Cabrio;

    }
}
ClearScriptLib commented 1 year ago

Hi @Tor012,

In C#, the unqualified identifier CarSpecs can refer to both a type and an object; the compiler resolves the ambiguity based on the identifier's syntactic context. In VBScript, however, both the property and the host type are objects, and a single identifier can't refer to more than one object.

One thing you could do is expose the host type under a different name:

engine.AddHostType("CarSpecsT", typeof(CarSpecs));
engine.AddHostObject("car", HostItemFlags.GlobalMembers, vCar);
Console.WriteLine(engine.Evaluate("car.CarSpecs.CarType Is CarSpecsT.enCarType.Cabrio"));
Console.WriteLine(engine.Evaluate("CarSpecs.CarType Is CarSpecsT.enCarType.Cabrio"));

Good luck!

ClearScriptLib commented 1 year ago

Please reopen this issue if you have additional thoughts or questions about this topic. Thank you!