Esempio n. 1
0
        bool CompileAssemblyDll(List <string> scriptsToCompile)
        {
            try
            {
                var assembly = ScriptingCSharpEngine.CompileScriptsToAssembly(scriptsToCompile, AssemblyFileName);
                if (assembly != null)
                {
                    FillLoadedAssemblyDllTypes(assembly);
                }
            }
            catch (Exception e)
            {
                Log.Info($"Unable to compile \"{AssemblyFileName}\". " + e.Message);
                return(false);
            }

            return(true);
        }
Esempio n. 2
0
        public CompiledScript GetOrCompileScript(string script, out string error)
        {
            if (string.IsNullOrEmpty(script))
            {
                Log.Fatal("ScriptCache: Get: \"script\" is empty.");
            }

            error = "";

            lock ( lockObjectGetOrCompileScript )
            {
                var compiledScript = GetCompiledScript(script);
                if (compiledScript != null)
                {
                    return(compiledScript);
                }

                if (!ScriptingCSharpEngine.CanCompileScripts)
                {
                    error = "Unable to get compiled script. The script is not precompiled in the cache. Script compilation is not supported on the current platform, run scenes on dev machine to make the cache.";
                    return(null);
                }

                try
                {
                    ScriptingCSharpEngine.CheckForSyntaxErrors(script);

                    var assembly = ScriptingCSharpEngine.CompileScriptsToAssembly(new List <string> {
                        script
                    }, null);
                    compiledScript = CompiledScript.CreateFrom(assembly);

                    AddCompiledScript(script, compiledScript);

                    return(compiledScript);
                }
                catch (Exception ex)
                {
                    error = ex.Message;
                    return(null);
                }
            }
        }
Esempio n. 3
0
        public Assembly CompileCode(string scriptText, string writeToDllOptional)
        {
            string scriptFile = null;

            //!!!!
            //slow first exec. ~3 sec
            // https://stackoverflow.com/questions/22974473/using-roslyn-emit-method-with-a-modulebuilder-instead-of-a-memorystream

            string tempScriptFile = null;

            try
            {
                if (DebugBuild)
                {
                    // Excellent example of debugging support
                    // http://www.michalkomorowski.com/2016/10/roslyn-how-to-create-custom-debuggable_27.html

                    if (scriptFile == null)
                    {
                        tempScriptFile = GetScriptTempFileName();
                        File.WriteAllText(tempScriptFile, scriptText, Encoding.UTF8);
                    }

                    scriptText = $"#line 1 \"{scriptFile ?? tempScriptFile}\"{Environment.NewLine}" + scriptText;
                }

                //options
                var options = Settings;
                if (!DebugBuild)
                {
                    // There is a Roslyn bug that prevents emitting debug symbols if file path is specified. And fails
                    // the whole compilation:
                    // It triggers "error CS8055: Cannot emit debug information for a source text without encoding."
                    // Thus disable setting the source path until Roslyn is fixed.
                    options = Settings.WithFilePath(scriptFile ?? tempScriptFile);
                }

                var compilation = CSharpScript.Create(scriptText, options).GetCompilation();

                if (DebugBuild)
                {
                    compilation = compilation.WithOptions(compilation.Options
                                                          .WithOptimizationLevel(OptimizationLevel.Debug)
                                                          .WithOutputKind(OutputKind.DynamicallyLinkedLibrary));
                }

                return(EmitIL(compilation, writeToDllOptional));
            }
            finally
            {
                if (DebugBuild)
                {
                    ScriptingCSharpEngine.AddTempFileToDelete(tempScriptFile);
                }
                else
                {
                    if (File.Exists(tempScriptFile))
                    {
                        File.Delete(tempScriptFile);
                    }
                }
            }
        }
Esempio n. 4
0
        public void Update()
        {
            if (DisableUpdate)
            {
                return;
            }

            //check disabled
            if (!Enabled)
            {
                Clear();
                return;
            }

            var newCode = Code.Value;

            needUpdate = false;
            if (newCode == compiledCode)
            {
                return;
            }
            ////check for updates
            //if( !needUpdate && newCode != compiledCode )
            //	needUpdate = true;
            ////nothing to update
            //if( !needUpdate )
            //	return;

            //do update

            Clear();
            compiledCode = newCode;
            needUpdate   = false;

            if (!string.IsNullOrEmpty(newCode))
            {
                compiledScript = ScriptingCSharpEngine.GetOrCompileScript(compiledCode, out var error);
                if (!string.IsNullOrEmpty(error))
                {
                    Log.Warning($"Unable to compile script.\r\n\r\nComponent \"{GetPathFromRoot( true )}\".\r\n\r\n" + error);
                    return;
                }

                CreateScriptInstance();

                //fields
                foreach (var netField in compiledScript.Fields)
                {
                    if (netField.IsPublic && netField.Name != "Owner")
                    {
                        var type   = MetadataManager.GetTypeOfNetType(netField.FieldType);
                        var member = new PropertyImpl(this, netField.Name, netField.IsStatic, type, type, Array.Empty <Metadata.Parameter>(), false, compiledScript, netField);

                        compiledMembers.Add(member);
                        compiledMemberBySignature[member.Signature] = member;
                    }
                }

                //properties
                foreach (var netProperty in compiledScript.Properties)
                {
                    if (netProperty.GetMethod != null && netProperty.GetMethod.IsPublic)
                    {
                        var type      = MetadataManager.GetTypeOfNetType(netProperty.PropertyType);
                        var unrefType = ReferenceUtility.GetUnreferencedType(type);

                        var netParameters = netProperty.GetIndexParameters();

                        var indexers = new List <Metadata.Parameter>();
                        for (int n = 0; n < netParameters.Length; n++)
                        {
                            var netParam = netParameters[n];

                            var  netType       = netParam.ParameterType;
                            bool isByReference = netType.IsByRef;
                            if (isByReference)
                            {
                                netType = netType.GetElementType();
                            }

                            var type2 = MetadataManager.GetTypeOfNetType(netType);

                            var p = new Metadata.Parameter(netParam.Name, type2, isByReference, netParam.IsIn, netParam.IsOut, netParam.IsRetval,
                                                           netParam.IsOptional, netParam.HasDefaultValue, netParam.DefaultValue);
                            indexers.Add(p);
                        }

                        var member = new PropertyImpl(this, netProperty.Name, ReflectionUtility.PropertyIsStatic(netProperty), type, unrefType, indexers.Count != 0 ? indexers.ToArray() : Array.Empty <Metadata.Parameter>(), !netProperty.CanWrite, compiledScript, netProperty);

                        compiledMembers.Add(member);
                        compiledMemberBySignature[member.Signature] = member;
                    }
                }

                //methods
                foreach (var netMethod in compiledScript.Methods)
                {
                    if (netMethod.IsSpecialName)
                    {
                        if (netMethod.Name.Length > 4 && (netMethod.Name.Substring(0, 4) == "get_" || netMethod.Name.Substring(0, 4) == "set_"))
                        {
                            continue;
                        }
                        if (netMethod.Name.Length > 4 && netMethod.Name.Substring(0, 4) == "add_")
                        {
                            continue;
                        }
                        if (netMethod.Name.Length > 7 && netMethod.Name.Substring(0, 7) == "remove_")
                        {
                            continue;
                        }
                    }

                    if (netMethod.GetBaseDefinition() != netMethod)
                    {
                        continue;
                    }

                    var netParams = netMethod.GetParameters();

                    var parameters = new List <Metadata.Parameter>();
                    for (int n = 0; n < netParams.Length; n++)
                    {
                        var netParam = netParams[n];

                        var  netType       = netParam.ParameterType;
                        bool isByReference = netType.IsByRef;
                        if (isByReference)
                        {
                            netType = netType.GetElementType();
                        }

                        var type = MetadataManager.GetTypeOfNetType(netType);

                        var p = new Metadata.Parameter(netParam.Name, type, isByReference, netParam.IsIn, netParam.IsOut, netParam.IsRetval,
                                                       netParam.IsOptional, netParam.HasDefaultValue, netParam.DefaultValue);
                        parameters.Add(p);
                    }

                    if (netMethod.ReturnType != null && netMethod.ReturnType != typeof(void))
                    {
                        var  netType = netMethod.ReturnType;
                        bool isRef   = netType.IsByRef;
                        if (isRef)
                        {
                            netType = netType.GetElementType();
                        }

                        var paramType = MetadataManager.GetTypeOfNetType(netType);
                        //"_return"
                        var p = new Metadata.Parameter("ReturnValue", paramType, isRef, false, true, true, false, false, null);
                        parameters.Add(p);
                    }

                    bool isOperator = netMethod.IsSpecialName && netMethod.Name.Length > 3 && netMethod.Name.Substring(0, 3) == "op_";

                    var member = new MethodImpl(this, netMethod.Name, netMethod.IsStatic, parameters.ToArray(), false, isOperator, compiledScript, netMethod);

                    compiledMembers.Add(member);
                    compiledMemberBySignature[member.Signature] = member;
                }

                //One method mode
                if (compiledScript != null && compiledMembers.Count == 1)
                {
                    compiledOneMethod = (MethodImpl)compiledMembers[0];
                    OneMethod_AddProperties(compiledOneMethod);

                    //var parameters = new List<Metadata.Parameter>();
                    //parameters.Add( new Metadata.Parameter( "a", MetadataManager.GetTypeOfNetType( typeof( int ) ), false, true, false, false, false, false, null ) );
                    //parameters.Add( new Metadata.Parameter( "ReturnValue", MetadataManager.GetTypeOfNetType( typeof( int ) ), false, true, false, true, false, false, null ) );
                    //xx xx;
                    //var method = new MethodImpl( this, "Method", true, parameters.ToArray(), false, false, compiledScript, compiledScript.PublicMethods[ 0 ] );

                    //compiledMembers.Add( method );
                    //compiledMemberBySignature[ method.Signature ] = method;
                    //compiledOneMethod = method;

                    ////create properties
                    //if( method != null )
                    //{
                    //	//parameters
                    //	propertyMethodParameters = new List<PropertyImpl>();
                    //	for( int nParameter = 0; nParameter < method.Parameters.Length; nParameter++ )
                    //	{
                    //		var parameter = method.Parameters[ nParameter ];

                    //		////!!!!имя еще как-то фиксить?
                    //		//string name = null;
                    //		//!!!!
                    //		//if( parameter.ReturnValue )
                    //		//	name = "ReturnValue";
                    //		//if( name == null )
                    //		var name = parameter.Name.Substring( 0, 1 ).ToUpper() + parameter.Name.Substring( 1 );

                    //		//!!!!поддержать ByReference. еще какие?
                    //		bool readOnly = parameter.Output || parameter.ReturnValue;

                    //		//!!!!
                    //		//var parameterType = GetOverrideParameterType( parameter, out bool error );
                    //		//if( error )
                    //		//{
                    //		//	unableToInit = true;
                    //		//	goto unableToInitLabel;
                    //		//}
                    //		//var parameterType = parameter.Type;

                    //		Metadata.TypeInfo type;
                    //		bool referenceSupport = !readOnly;
                    //		if( referenceSupport )
                    //		{
                    //			Type unrefNetType = parameter.Type.GetNetType();
                    //			var refNetType = typeof( Reference<> ).MakeGenericType( unrefNetType );
                    //			type = MetadataManager.GetTypeOfNetType( refNetType );
                    //		}
                    //		else
                    //			type = parameter.Type;

                    //		bool invoke = parameter.ReturnValue || parameter.ByReference || parameter.Output;

                    //		string namePrefix = "__parameter_";
                    //		string displayName = TypeUtils.DisplayNameAddSpaces( name );

                    //		var p = new PropertyImpl( this, namePrefix + name, false, type, parameter.Type, new Metadata.Parameter[ 0 ], readOnly, "Method's Parameters", displayName, referenceSupport, parameter, invoke );
                    //		p.Description = "";
                    //		if( !readOnly )
                    //			p.Serializable = true;

                    //		properties.Add( p );
                    //		propertyBySignature[ p.Signature ] = p;

                    //		//!!!!так? если несколько?
                    //		if( parameter.ReturnValue )
                    //			propertyMethodReturnParameter = p;
                    //		else
                    //			propertyMethodParameters.Add( p );
                    //	}
                    //}
                }

                //update child handlers
                try
                {
                    foreach (var handler in GetComponents <Component_EventHandler>())
                    {
                        handler.UpdateSubscription();
                    }
                }
                catch { }
            }
        }