aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio
diff options
context:
space:
mode:
authorRoy Ben Shabat <Roy.mail.net@gmail.com>2020-08-06 04:34:38 +0300
committerRoy Ben Shabat <Roy.mail.net@gmail.com>2020-08-06 04:34:38 +0300
commit255a47cf96e83e8d11befa9180dc4458f6767188 (patch)
tree5b4229edce3c2c0bc56202e8711ce3a5949cb32f /Software/Visual_Studio
parent03bc9bd370929884f98ee9488146646d44911efd (diff)
downloadTango-255a47cf96e83e8d11befa9180dc4458f6767188.tar.gz
Tango-255a47cf96e83e8d11befa9180dc4458f6767188.zip
Implemented interactive runtime error handling on procedures.
Diffstat (limited to 'Software/Visual_Studio')
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Contracts/IProcedureDesignerView.cs3
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ProcedureContext.cs2
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureDesignerViewVM.cs54
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Views/ProcedureDesignerView.xaml60
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Views/ProcedureDesignerView.xaml.cs47
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Basic/Project.cs3
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs35
7 files changed, 192 insertions, 12 deletions
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Contracts/IProcedureDesignerView.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Contracts/IProcedureDesignerView.cs
index 5797d622a..fa8a4cab6 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Contracts/IProcedureDesignerView.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Contracts/IProcedureDesignerView.cs
@@ -21,5 +21,8 @@ namespace Tango.FSE.Procedures.Contracts
void ResetColrization();
void HighlightError(int position, int length);
void ClearErrors();
+ void ScrollToLine(int lineNumber);
+ void HighlightRuntimeError(int lineNumber);
+ void CloseRunTimeError();
}
}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ProcedureContext.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ProcedureContext.cs
index ef5664772..88ab8dae9 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ProcedureContext.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ProcedureContext.cs
@@ -87,7 +87,7 @@ namespace Tango.FSE.Procedures
var stubType = MessageFactory.GetAvailableRequestStubs().SingleOrDefault(x => x.Name.ToLower() == messageName.ToLower() || x.Name.Replace("Request", "").ToLower() == messageName.ToLower());
if (stubType == null)
{
- throw new ArgumentException("Invalid stub '" + messageName + "'.");
+ throw new ArgumentException($"Stub '{messageName}' could not be located on the PMR.");
}
var stubProps = stubType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureDesignerViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureDesignerViewVM.cs
index 68c8538b8..bd36350c1 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureDesignerViewVM.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureDesignerViewVM.cs
@@ -8,6 +8,7 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
+using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
@@ -200,6 +201,20 @@ namespace Tango.FSE.Procedures.ViewModels
}
}
+ private Exception _runtimeException;
+ public Exception RuntimeException
+ {
+ get { return _runtimeException; }
+ set { _runtimeException = value; RaisePropertyChangedAuto(); }
+ }
+
+ private bool _runtimeErrorFree;
+ public bool RuntimeErrorFree
+ {
+ get { return _runtimeErrorFree; }
+ set { _runtimeErrorFree = value; RaisePropertyChangedAuto(); }
+ }
+
#endregion
#region Commands
@@ -244,6 +259,7 @@ namespace Tango.FSE.Procedures.ViewModels
public RelayCommand<ProcedureResource> RemoveResourceCommand { get; set; }
public RelayCommand<ProcedureResource> OpenResourceCommand { get; set; }
public RelayCommand<ProcedureResource> ExportResourceCommand { get; set; }
+ public RelayCommand CloseRuntimeErrorCommand { get; set; }
#endregion
@@ -256,6 +272,7 @@ namespace Tango.FSE.Procedures.ViewModels
FontSize = 13;
ReplaceText = String.Empty;
+ RuntimeErrorFree = true;
LoadedAssemblies = new ObservableCollection<Assembly>();
ResultsViewVM = new ResultsViewVM();
@@ -309,6 +326,7 @@ namespace Tango.FSE.Procedures.ViewModels
RemoveResourceCommand = new RelayCommand<ProcedureResource>(RemoveProcedureResource);
OpenResourceCommand = new RelayCommand<ProcedureResource>(OpenProcedureResource);
ExportResourceCommand = new RelayCommand<ProcedureResource>(ExportProcedureResource);
+ CloseRuntimeErrorCommand = new RelayCommand(CloseRunTimeError);
}
#endregion
@@ -557,6 +575,32 @@ namespace Tango.FSE.Procedures.ViewModels
SelectedToolWindow = ToolWindows.Output;
Logger.WriteLine("Project terminated with error:");
Logger.WriteLine(ex.FlattenMessage());
+
+ try
+ {
+ Regex regex = new Regex(@"OnExecute\(IProcedureContext context\) in :line (\d+)");
+ var matches = regex.Matches(ex.ToString()).OfType<Match>().ToList();
+
+ if (matches.Count > 0)
+ {
+ var match = matches.First();
+
+ if (match.Groups.Count > 1)
+ {
+ var line = match.Groups[1].Value;
+ int lineNumber = int.Parse(line) - Project.Scripts.Count + 1;
+ OpenScript(Project.Scripts.FirstOrDefault(x => x.IsEntryPoint));
+ RuntimeException = ex;
+ View.HighlightRuntimeError(lineNumber);
+ RuntimeErrorFree = false;
+ Mouse.OverrideCursor = null;
+ }
+ }
+ }
+ catch (Exception exx)
+ {
+ LogManager.Log(exx, "Error occurred while trying to show procedue runtime error.");
+ }
}
}
@@ -1288,5 +1332,15 @@ namespace Tango.FSE.Procedures.ViewModels
}
#endregion
+
+ #region Runtime Error
+
+ private void CloseRunTimeError()
+ {
+ View.CloseRunTimeError();
+ RuntimeErrorFree = true;
+ }
+
+ #endregion
}
}
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Views/ProcedureDesignerView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Views/ProcedureDesignerView.xaml
index 82f799d7b..dd442348f 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Views/ProcedureDesignerView.xaml
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Views/ProcedureDesignerView.xaml
@@ -36,7 +36,7 @@
<Grid>
<Grid>
<DockPanel>
- <Menu IsMainMenu="True" DockPanel.Dock="Top">
+ <Menu IsMainMenu="True" DockPanel.Dock="Top" IsHitTestVisible="{Binding RuntimeErrorFree}">
<MenuItem Header="_File">
<MenuItem Header="_New" MinWidth="250" Command="{Binding NewProjectCommand}" InputGestureText="Ctrl+N">
<MenuItem.Icon>
@@ -166,7 +166,7 @@
</MenuItem>
</Menu>
- <Grid DockPanel.Dock="Top">
+ <Grid DockPanel.Dock="Top" IsHitTestVisible="{Binding RuntimeErrorFree}">
<!--Toolbar-->
<ToolBar ClipToBounds="False" Background="Transparent" HorizontalAlignment="Center" ToolBarTray.IsLocked="True">
<Button ToolTip="Save" Command="{Binding SaveProjectCommand}">
@@ -206,7 +206,7 @@
</ToolBar>
</Grid>
- <Grid DockPanel.Dock="Bottom" Height="25" Background="#007BA5" TextElement.FontSize="{StaticResource FSE_SmallFontSize}">
+ <Grid DockPanel.Dock="Bottom" Height="25" Background="#007BA5" TextElement.FontSize="{StaticResource FSE_SmallFontSize}" IsHitTestVisible="{Binding RuntimeErrorFree}">
<!--Status Bar-->
<Grid>
<StackPanel HorizontalAlignment="Left" Orientation="Horizontal" Margin="5 0 0 0">
@@ -231,7 +231,7 @@
<ColumnDefinition MaxWidth="500" MinWidth="250" Width="134*"/>
</Grid.ColumnDefinitions>
- <Grid Width="350" Margin="0 33 0 0" Visibility="{Binding IsPublishPanelOpened,Converter={StaticResource BooleanToVisibilityConverter}}">
+ <Grid IsHitTestVisible="{Binding RuntimeErrorFree}" Width="350" Margin="0 33 0 0" Visibility="{Binding IsPublishPanelOpened,Converter={StaticResource BooleanToVisibilityConverter}}">
<Border BorderThickness="0 0 5 0" BorderBrush="{StaticResource FSE_PrimaryBackgroundBrush}">
<DockPanel Background="{StaticResource FSE_PrimaryBackgroundDarkBrush}">
<Border DockPanel.Dock="Top" Padding="5" Background="{StaticResource FSE_PrimaryBackgroundLightBrush}" BorderThickness="0 1 0 0" BorderBrush="{StaticResource FSE_BorderBrush}">
@@ -304,7 +304,7 @@
<RowDefinition MinHeight="30" Height="210*"/>
</Grid.RowDefinitions>
- <Grid Grid.Column="2">
+ <Grid Grid.Column="2" IsHitTestVisible="{Binding RuntimeErrorFree}">
<!--Code Editor-->
<DockPanel>
<Grid DockPanel.Dock="Top" Height="35">
@@ -492,13 +492,14 @@
</Border>
</Border>
</Grid>
+
</Grid>
</DockPanel>
</Grid>
- <GridSplitter Grid.Row="1" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
+ <GridSplitter IsHitTestVisible="{Binding RuntimeErrorFree}" Grid.Row="1" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
- <Grid Grid.Row="2">
+ <Grid Grid.Row="2" IsHitTestVisible="{Binding RuntimeErrorFree}">
<!--Output & Error Tabs-->
<TabControl SelectedIndex="{Binding SelectedToolWindow,Mode=TwoWay,Converter={StaticResource EnumToIntConverter}}" ItemContainerStyle="{StaticResource FSE_TabItem_VisualStudio_Output}" TabStripPlacement="Bottom" Margin="0" Background="{StaticResource FSE_PrimaryBackgroundDarkBrush}" BorderThickness="0">
<TabItem Header="OUTPUT">
@@ -630,7 +631,7 @@
</Button>
<controls:FSERoundedCornersComboBox Height="25" FontSize="{StaticResource FSE_SmallFontSize}" ItemsSource="{Binding SelectionInputs}" SelectedValue="{Binding Value}" SelectedValuePath="Value" DisplayMemberPath="Name"/>
</DockPanel>
- </StackPanel>
+ </StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
@@ -734,11 +735,52 @@
</TabItem>
</TabControl>
</Grid>
+
+ <Canvas Grid.Column="1" Grid.RowSpan="4" Background="Transparent" Margin="75 35 0 0" x:Name="runTimeErrorCanvas" IsHitTestVisible="True" Visibility="Hidden">
+ <DockPanel x:Name="runTimeErrorDock" Canvas.Top="200" Canvas.Left="0">
+ <Grid x:Name="runTimeErrorLineGrid" DockPanel.Dock="Bottom" Width="50" Height="50" HorizontalAlignment="Left">
+ <Line RenderTransformOrigin="0.5,0.5" x:Name="runTimeErrorLine" X1="0" Y1="50" X2="50" Y2="0" Stroke="{StaticResource FSE_ErrorBrush}">
+ <Line.RenderTransform>
+ <RotateTransform Angle="0" x:Name="runTimeErrorLineTransform" />
+ </Line.RenderTransform>
+ </Line>
+ </Grid>
+ <Border Margin="50 0 0 0" Width="500" Height="250" BorderBrush="{StaticResource FSE_BorderBrush}" BorderThickness="1" Background="{StaticResource FSE_PrimaryBackgroundMidBrush}">
+ <DockPanel>
+ <DockPanel DockPanel.Dock="Top" Height="25" Background="{StaticResource FSE_PrimaryBackgroundLightBrush}">
+ <controls:IconButton Width="20" Height="20" Cursor="Hand" ToolTip="Close" Padding="0" Icon="Close" DockPanel.Dock="Right" Margin="0 0 5 0" Command="{Binding CloseRuntimeErrorCommand}" />
+ <material:PackIcon Margin="5 0 0 0" Kind="AlertOctagon" VerticalAlignment="Center" />
+ <TextBlock Margin="5 2 0 0" VerticalAlignment="Center" FontSize="{StaticResource FSE_SmallFontSize}">Runtime Error</TextBlock>
+ </DockPanel>
+ <Grid>
+ <DockPanel>
+ <TextBlock Margin="10" DockPanel.Dock="Top" Text="{Binding RuntimeException.Message,Mode=OneWay}" TextWrapping="Wrap" FontSize="{StaticResource FSE_SmallFontSize}" Foreground="{StaticResource FSE_ErrorBrush}"></TextBlock>
+ <TextBox Style="{x:Null}" Margin="5 10 10 10"
+ HorizontalScrollBarVisibility="Hidden"
+ VerticalScrollBarVisibility="Auto"
+ AcceptsReturn="True"
+ TextWrapping="NoWrap"
+ BorderThickness="0"
+ Padding="5"
+ BorderBrush="{StaticResource FSE_BorderBrush}"
+ Background="Transparent"
+ Foreground="{StaticResource FSE_GrayBrush}"
+ CaretBrush="{StaticResource FSE_PrimaryForegroundBrush}"
+ FontSize="{StaticResource FSE_SmallFontSize}" Text="{Binding RuntimeException,Mode=OneWay}"
+ IsReadOnly="True">
+
+ </TextBox>
+ </DockPanel>
+ </Grid>
+ </DockPanel>
+ </Border>
+ </DockPanel>
+ </Canvas>
</Grid>
<GridSplitter Grid.Column="2" Width="5" HorizontalAlignment="Center" VerticalAlignment="Stretch" Margin="0 33 0 30" />
- <Grid Grid.Column="3">
+ <Grid Grid.Column="3" IsHitTestVisible="{Binding RuntimeErrorFree}">
<Grid Margin="0 33 0 29">
<!--Project Explorer-->
<DockPanel Background="{StaticResource FSE_PrimaryBackgroundDarkBrush}">
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Views/ProcedureDesignerView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Views/ProcedureDesignerView.xaml.cs
index 1e5deb04a..a85508b24 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Views/ProcedureDesignerView.xaml.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Views/ProcedureDesignerView.xaml.cs
@@ -16,6 +16,7 @@ using Tango.FSE.Procedures.Contracts;
using Tango.FSE.Procedures.ViewModels;
using Tango.Scripting.Basic;
using Tango.Scripting.Editors;
+using Tango.SharedUI.Helpers;
namespace Tango.FSE.Procedures.Views
{
@@ -92,7 +93,7 @@ namespace Tango.FSE.Procedures.Views
if (editor != null)
{
- int count = editor.ReplaceAll(text, replace);
+ int count = editor.ReplaceAll(text, replace);
ColorizeKeyword(text);
return count;
}
@@ -137,5 +138,49 @@ namespace Tango.FSE.Procedures.Views
{
GetAllEditors().ForEach(x => x.ClearErrors());
}
+
+ public void ScrollToLine(int lineNumber)
+ {
+ GetCurrentEditor().ScrollToLine(lineNumber);
+ }
+
+ public void HighlightRuntimeError(int lineNumber)
+ {
+ ScrollToLine(lineNumber);
+ var editor = GetCurrentEditor();
+ editor.HighlightErrorLine(lineNumber);
+ UIHelper.DoEvents();
+ Point? p = editor.GetLineVisualPosition(lineNumber);
+
+ if (p != null)
+ {
+ Point point = p.Value;
+ point = new Point(point.X, point.Y - editor.VerticalOffset);
+ double height = editor.ActualHeight;
+
+ if (point.Y > runTimeErrorDock.ActualHeight)
+ {
+ DockPanel.SetDock(runTimeErrorLineGrid, Dock.Bottom);
+ runTimeErrorLineTransform.Angle = 0;
+ Canvas.SetTop(runTimeErrorDock, point.Y - runTimeErrorDock.ActualHeight);
+ }
+ else
+ {
+ DockPanel.SetDock(runTimeErrorLineGrid, Dock.Top);
+ runTimeErrorLineTransform.Angle = 90;
+ Canvas.SetTop(runTimeErrorDock, point.Y);
+ }
+
+ Canvas.SetLeft(runTimeErrorDock, Math.Min(point.X, editor.ActualWidth - 110 - runTimeErrorDock.ActualWidth));
+
+ runTimeErrorCanvas.Visibility = Visibility.Visible;
+ }
+ }
+
+ public void CloseRunTimeError()
+ {
+ runTimeErrorCanvas.Visibility = Visibility.Hidden;
+ GetCurrentEditor().ResetColorizationByKeyword();
+ }
}
}
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/Project.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/Project.cs
index 8ca64ca18..2a1a7b7fc 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/Project.cs
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/Project.cs
@@ -121,9 +121,10 @@ namespace Tango.Scripting.Basic
}
}
- var scriptOptions = ScriptOptions.Default.WithReferences(LoadReferenceAssemblies());
+ var scriptOptions = ScriptOptions.Default.WithReferences(LoadReferenceAssemblies()).WithEmitDebugInformation(true);
var s = CSharpScript.Create<object>(mainScriptCode, scriptOptions, typeof(GlobalObject<T>));
+
result.Script = s;
var compileResults = s.Compile();
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs
index 0802cf456..c650ad425 100644
--- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs
@@ -191,6 +191,14 @@ namespace Tango.Scripting.Editors
public static readonly DependencyProperty ColorizeBrushProperty =
DependencyProperty.Register("ColorizeBrush", typeof(Brush), typeof(ScriptEditor), new PropertyMetadata(new SolidColorBrush(Colors.YellowGreen) { Opacity = 0.5 }));
+ public Brush ErrorLineBrush
+ {
+ get { return (Brush)GetValue(ErrorLineBrushProperty); }
+ set { SetValue(ErrorLineBrushProperty, value); }
+ }
+ public static readonly DependencyProperty ErrorLineBrushProperty =
+ DependencyProperty.Register("ErrorLineBrush", typeof(Brush), typeof(ScriptEditor), new PropertyMetadata(new SolidColorBrush(Colors.Red) { Opacity = 0.5 }));
+
#endregion
#region Constructors
@@ -2486,6 +2494,33 @@ namespace Tango.Scripting.Editors
errorMarkerService.RemoveAll(m => true);
}
+ public void HighlightErrorLine(int lineNumber)
+ {
+ Document.BeginUpdate();
+
+ var line = Document.GetLineByNumber(lineNumber);
+ OffsetColorizer errorLineColrizer = new OffsetColorizer(line, line.Offset, line.EndOffset, ErrorLineBrush);
+ TextArea.TextView.LineTransformers.Add(errorLineColrizer);
+
+ Document.EndUpdate();
+ }
+
+ public Point? GetLineVisualPosition(int lineNumber)
+ {
+ double top = TextArea.TextView.GetVisualTopByDocumentLine(lineNumber);
+ var visualLine = TextArea.TextView.GetVisualLine(lineNumber);
+
+ if (visualLine != null)
+ {
+ var textLine = visualLine.GetTextLine(0);
+ var x = visualLine.GetTextLineVisualXPosition(textLine, visualLine.VisualLengthWithEndOfLineMarker);
+ var left = visualLine.VisualLengthWithEndOfLineMarker;
+ return new Point(x, top);
+ }
+
+ return null;
+ }
+
#endregion
}
}