-
Notifications
You must be signed in to change notification settings - Fork 0
/
ConsoleExtension.cs
154 lines (136 loc) · 6.05 KB
/
ConsoleExtension.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
using System;
using System.Collections;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
using PX.Data;
namespace AcuShell
{
public class ConsoleExtension : PXGraphExtension<PXGraph>
{
public static ScriptState<object> CurrentState { get; set; }
public static Type CurrentType;
public static object CurrentGraphUID;
public PXFilter<ConsoleFields> ConsoleView;
public override void Initialize()
{
base.Initialize();
if (Base.GetType() != typeof(PXGraph) && Base.PrimaryItemType != null)
{
PXAction runAction = PXNamedAction.AddAction(Base, Base.PrimaryItemType, nameof(ConsoleRunAction), "Run", new PXButtonDelegate(ConsoleRunAction));
PXAction clearOutputAction = PXNamedAction.AddAction(Base, Base.PrimaryItemType, nameof(ConsoleClearOutputAction), "ConsoleClearOutput", new PXButtonDelegate(ConsoleClearOutputAction));
ConsoleView.Cache.SetValueExt<ConsoleFields.graphType>(ConsoleView.Current, PX.Api.CustomizedTypeManager.GetTypeNotCustomized(Base).FullName); //For code completion on Graph.
}
}
[PXButton(VisibleOnDataSource = false, CommitChanges = true)]
public IEnumerable ConsoleRunAction(PXAdapter adapter)
{
const string OutputStartTag = "<p style='font-family: Consolas; font-size: 10pt; line-height: 16px'>"; //We should edit the CSS of the editor instead
const string OutputEndTag = "</p>";
try
{
var genericScope = typeof(ConsoleGlobalScope<>);
var typeNotCustomized = PX.Api.CustomizedTypeManager.GetTypeNotCustomized(Base);
var typedScopedType = genericScope.MakeGenericType(typeNotCustomized);
object typedScope = Activator.CreateInstance(typedScopedType);
((IHaveGraph)typedScope).SetGraph(Base);
var assemblies = AppDomain.CurrentDomain.GetAssemblies().Where(it => !it.IsDynamic && !it.ReflectionOnly && it.ManifestModule.Name != "<Unknown>");
//TODO This is also hardcoded in the console JS file
var imports = new string[] { "System",
"System.Collections",
"System.Collections.Generic",
"System.Linq",
"PX.Data",
"PX.Common",
"PX.Objects.GL",
"PX.Objects.CM",
"PX.Objects.CS",
"PX.Objects.CR",
"PX.Objects.TX",
"PX.Objects.IN",
"PX.Objects.EP",
"PX.Objects.AP",
"PX.TM",
"PX.Objects",
"PX.Objects.PO",
"PX.Objects.SO"
};
ScriptState<object> result;
if(CurrentState == null || CurrentType != typeNotCustomized || CurrentGraphUID != Base.UID)
{
result = Task.Run(() => CSharpScript.RunAsync<object>(ConsoleView.Current.Input, globalsType: typedScopedType,
options: ScriptOptions.Default
.WithReferences(assemblies)
.WithImports(imports)
, globals: typedScope)).Result;
CurrentState = result;
CurrentType = typeNotCustomized;
CurrentGraphUID = Base.UID;
}
else
{
result = CurrentState.ContinueWithAsync(ConsoleView.Current.Input).Result;
}
if (result?.ReturnValue != null)
{
ConsoleView.Cache.SetValueExt<ConsoleFields.output>(ConsoleView.Current, ConsoleView.Current.Output + OutputStartTag + result.ReturnValue.ToString() + OutputEndTag);
}
else
{
ConsoleView.Cache.SetValueExt<ConsoleFields.output>(ConsoleView.Current, ConsoleView.Current.Output + OutputStartTag + "Expression has been evaluated and has no value." + OutputEndTag);
}
}
catch(CompilationErrorException ex)
{
ConsoleView.Cache.SetValueExt<ConsoleFields.output>(ConsoleView.Current, ConsoleView.Current.Output + OutputStartTag + ex.Message + OutputEndTag);
}
catch (AggregateException ae)
{
var sb = new System.Text.StringBuilder();
foreach (Exception ex in ae.InnerExceptions)
{
sb.AppendLine(ex.Message);
}
ConsoleView.Cache.SetValueExt<ConsoleFields.output>(ConsoleView.Current, ConsoleView.Current.Output + OutputStartTag + sb.ToString() + OutputEndTag);
}
return adapter.Get();
}
[PXButton(VisibleOnDataSource = false, CommitChanges = false)]
public IEnumerable ConsoleClearOutputAction(PXAdapter adapter)
{
ConsoleView.Cache.SetValueExt<ConsoleFields.output>(ConsoleView.Current, String.Empty);
CurrentState = null;
return adapter.Get();
}
}
public interface IHaveGraph
{
void SetGraph(PXGraph graph);
}
public class ConsoleGlobalScope<T> : IHaveGraph
where T : PXGraph
{
public T Graph
{
get;
set;
}
public void SetGraph(PXGraph graph)
{
this.Graph = graph as T;
}
}
[Serializable]
public class ConsoleFields : IBqlTable
{
public abstract class graphType : IBqlField { }
[PXUIField(Visible = false)]
public string GraphType { get; set; }
public abstract class input : IBqlField { }
[PXUIField(Visible = false)]
public string Input { get; set; }
public abstract class output : IBqlField { }
public string Output { get; set; }
}
}