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); }
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); } } }
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); } } } }
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 { } } }