1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . Diagnostics ;
4+ using System . Text . RegularExpressions ;
5+
6+ using JavaScriptEngineSwitcher . Core . Extensions ;
7+ using JavaScriptEngineSwitcher . Core . Helpers ;
8+
9+ using CoreStrings = JavaScriptEngineSwitcher . Core . Resources . Strings ;
10+
11+ namespace JavaScriptEngineSwitcher . NiL . Helpers
12+ {
13+ /// <summary>
14+ /// JS error helpers
15+ /// </summary>
16+ internal static class NiLJsErrorHelpers
17+ {
18+ #region Error location
19+
20+ private const string AtLinePrefix = " at " ;
21+ private const string DotNetStackTraceLinePrefix = AtLinePrefix + "NiL.JS." ;
22+
23+ private const string OriginalGlobalCode = "anonymous" ;
24+ private const string OriginalAnonymousFunctionName = "<anonymous method>" ;
25+ private const string WrapperGlobalCode = "Global code" ;
26+ private const string WrapperAnonymousFunctionName = "Anonymous function" ;
27+
28+ /// <summary>
29+ /// Regular expression for working with line of the script error location
30+ /// </summary>
31+ private static readonly Regex _errorLocationLineRegex =
32+ new Regex ( @"^" + AtLinePrefix +
33+ @"(?<functionName>" +
34+ @"[\w][\w ]*" +
35+ @"|" +
36+ CommonRegExps . JsFullNamePattern +
37+ @"|" +
38+ Regex . Escape ( OriginalAnonymousFunctionName ) +
39+ @")" +
40+ @"(?::line (?<lineNumber>\d+):(?<columnNumber>\d+))?$" ) ;
41+
42+
43+ /// <summary>
44+ /// Parses a string representation of the script error location to produce an array of
45+ /// <see cref="ErrorLocationItem"/> instances
46+ /// </summary>
47+ /// <param name="errorLocation">String representation of the script error location</param>
48+ /// <returns>An array of <see cref="ErrorLocationItem"/> instances</returns>
49+ public static ErrorLocationItem [ ] ParseErrorLocation ( string errorLocation )
50+ {
51+ if ( string . IsNullOrWhiteSpace ( errorLocation ) )
52+ {
53+ return new ErrorLocationItem [ 0 ] ;
54+ }
55+
56+ var errorLocationItems = new List < ErrorLocationItem > ( ) ;
57+ string [ ] lines = errorLocation . SplitToLines ( ) ;
58+ int lineCount = lines . Length ;
59+
60+ for ( int lineIndex = 0 ; lineIndex < lineCount ; lineIndex ++ )
61+ {
62+ string line = lines [ lineIndex ] ;
63+
64+ if ( line . Length == 0 )
65+ {
66+ continue ;
67+ }
68+
69+ // Completing parsing when a .NET stack trace is found
70+ if ( line . StartsWith ( DotNetStackTraceLinePrefix , StringComparison . Ordinal ) )
71+ {
72+ break ;
73+ }
74+
75+ Match lineMatch = _errorLocationLineRegex . Match ( line ) ;
76+ if ( lineMatch . Success )
77+ {
78+ GroupCollection lineGroups = lineMatch . Groups ;
79+ Group lineNumberGroup = lineGroups [ "lineNumber" ] ;
80+ Group columnNumberGroup = lineGroups [ "columnNumber" ] ;
81+
82+ var errorLocationItem = new ErrorLocationItem
83+ {
84+ FunctionName = lineGroups [ "functionName" ] . Value ,
85+ LineNumber = lineNumberGroup . Success ? int . Parse ( lineNumberGroup . Value ) : 0 ,
86+ ColumnNumber = columnNumberGroup . Success ? int . Parse ( columnNumberGroup . Value ) : 0 ,
87+ } ;
88+ errorLocationItems . Add ( errorLocationItem ) ;
89+ }
90+ else
91+ {
92+ Debug . WriteLine ( string . Format ( CoreStrings . Runtime_InvalidErrorLocationLineFormat , line ) ) ;
93+ return new ErrorLocationItem [ 0 ] ;
94+ }
95+ }
96+
97+ return errorLocationItems . ToArray ( ) ;
98+ }
99+
100+ /// <summary>
101+ /// Fixes a error location items
102+ /// </summary>
103+ /// <param name="errorLocationItems">An array of <see cref="ErrorLocationItem"/> instances</param>
104+ public static void FixErrorLocationItems ( ErrorLocationItem [ ] errorLocationItems )
105+ {
106+ foreach ( ErrorLocationItem errorLocationItem in errorLocationItems )
107+ {
108+ string functionName = errorLocationItem . FunctionName ;
109+ if ( functionName . Length == 0 || functionName == OriginalGlobalCode )
110+ {
111+ errorLocationItem . FunctionName = WrapperGlobalCode ;
112+ }
113+ else if ( functionName == OriginalAnonymousFunctionName )
114+ {
115+ errorLocationItem . FunctionName = WrapperAnonymousFunctionName ;
116+ }
117+ }
118+ }
119+
120+ #endregion
121+ }
122+ }
0 commit comments