@@ -32,6 +32,7 @@ public class ASGenerator
32
32
const string NewLine = "$(Boundary)\n " ;
33
33
static private Regex reModifiers = new Regex ( "^\\ s*(\\ $\\ (Boundary\\ ))?([a-z ]+)(function|var|const)" , RegexOptions . Compiled ) ;
34
34
static private Regex reModifier = new Regex ( "(public |private |protected )" , RegexOptions . Compiled ) ;
35
+ static private Regex reSuperCall = new Regex ( "^super\\ s*\\ (" , RegexOptions . Compiled ) ;
35
36
36
37
static private string contextToken ;
37
38
static private string contextParam ;
@@ -1741,26 +1742,22 @@ private static void AddInterfaceDefJob(ClassModel inClass, ScintillaControl sci,
1741
1742
private static void GenerateFieldFromParameter ( ScintillaControl sci , MemberModel member , ClassModel inClass ,
1742
1743
Visibility scope )
1743
1744
{
1744
- int funcBodyStart = GetBodyStart ( member . LineFrom , member . LineTo , sci ) ;
1745
+ int funcBodyStart = GetBodyStart ( member . LineFrom , member . LineTo , sci , false ) ;
1746
+ int fbsLine = sci . LineFromPosition ( funcBodyStart ) ;
1747
+ int endPos = sci . LineEndPosition ( member . LineTo ) ;
1745
1748
1746
- sci . SetSel ( funcBodyStart , sci . LineEndPosition ( member . LineTo ) ) ;
1749
+ sci . SetSel ( funcBodyStart , endPos ) ;
1747
1750
string body = sci . SelText ;
1748
1751
string trimmed = body . TrimStart ( ) ;
1749
1752
1750
- Regex re = new Regex ( "^super\\ s*[\\ (|\\ .]" ) ;
1751
- Match m = re . Match ( trimmed ) ;
1752
- if ( m . Success )
1753
+ Match m = reSuperCall . Match ( trimmed ) ;
1754
+ if ( m . Success && m . Index == 0 )
1753
1755
{
1754
- if ( m . Index == 0 )
1755
- {
1756
- int p = funcBodyStart + ( body . Length - trimmed . Length ) ;
1757
- int l = sci . LineFromPosition ( p ) ;
1758
- p = sci . PositionFromLine ( l + 1 ) ;
1759
- throw new NotImplementedException ( "reimplement" ) ;
1760
- //funcBodyStart = GetBodyStart(member.LineFrom, member.LineTo, sci, p);
1761
- }
1756
+ funcBodyStart = GetEndOfStatement ( funcBodyStart + ( body . Length - trimmed . Length ) , endPos , sci ) ;
1762
1757
}
1763
1758
1759
+ funcBodyStart = GetOrSetPointOfInsertion ( funcBodyStart , endPos , fbsLine , sci ) ;
1760
+
1764
1761
sci . SetSel ( funcBodyStart , funcBodyStart ) ;
1765
1762
sci . CurrentPos = funcBodyStart ;
1766
1763
@@ -1797,8 +1794,6 @@ private static void GenerateFieldFromParameter(ScintillaControl sci, MemberModel
1797
1794
}
1798
1795
}
1799
1796
1800
-
1801
-
1802
1797
string template = TemplateUtils . GetTemplate ( "FieldFromParameter" ) ;
1803
1798
template = TemplateUtils . ReplaceTemplateVariable ( template , "Name" , scopedVarName ) ;
1804
1799
template = TemplateUtils . ReplaceTemplateVariable ( template , "Value" , paramName ) ;
@@ -1830,87 +1825,187 @@ private static void GenerateFieldFromParameter(ScintillaControl sci, MemberModel
1830
1825
/// <summary>
1831
1826
/// Tries to get the best position inside a code block, delimited by { and }, to add new code, inserting new lines if needed.
1832
1827
/// </summary>
1833
- /// <param name="lineFrom">The line inside the scintilla document where the owner member of the body starts</param>
1834
- /// <param name="lineTo">The line inside the scintilla document where the owner member of the body ends</param>
1835
- /// <param name="Sci ">The Scintilla control containing the document</param>
1828
+ /// <param name="lineFrom">The line inside the Scintilla document where the owner member of the body starts</param>
1829
+ /// <param name="lineTo">The line inside the Scintilla document where the owner member of the body ends</param>
1830
+ /// <param name="sci ">The Scintilla control containing the document</param>
1836
1831
/// <returns>The position inside the scintilla document, or -1 if not suitable position was found</returns>
1837
- public static int GetBodyStart ( int lineFrom , int lineTo , ScintillaControl Sci )
1832
+ public static int GetBodyStart ( int lineFrom , int lineTo , ScintillaControl sci )
1838
1833
{
1839
- int posStart = Sci . PositionFromLine ( lineFrom ) ;
1840
- int posEnd = Sci . LineEndPosition ( lineTo ) ;
1834
+ return GetBodyStart ( lineFrom , lineTo , sci , true ) ;
1835
+ }
1836
+
1837
+ /// <summary>
1838
+ /// Tries to get the start position of a code block, delimited by { and }
1839
+ /// </summary>
1840
+ /// <param name="lineFrom">The line inside the Scintilla document where the owner member of the body starts</param>
1841
+ /// <param name="lineTo">The line inside the Scintilla document where the owner member of the body ends</param>
1842
+ /// <param name="sci">The Scintilla control containing the document</param>
1843
+ /// <param name="needsPointOfInsertion">If true looks for the position to add new code, inserting new lines if needed</param>
1844
+ /// <returns>The position inside the Scintilla document, or -1 if not suitable position was found</returns>
1845
+ public static int GetBodyStart ( int lineFrom , int lineTo , ScintillaControl sci , bool needsPointOfInsertion )
1846
+ {
1847
+ int posStart = sci . PositionFromLine ( lineFrom ) ;
1848
+ int posEnd = sci . LineEndPosition ( lineTo ) ;
1841
1849
1842
- char [ ] characterClass = new [ ] { ' ' , '\r ' , '\n ' , '\t ' } ;
1843
- int nCount = 0 ;
1844
1850
int funcBodyStart = - 1 ;
1845
- int extraLine = 1 ;
1846
1851
1847
1852
int genCount = 0 ;
1848
1853
for ( int i = posStart ; i <= posEnd ; i ++ )
1849
1854
{
1850
- char c = ( char ) Sci . CharAt ( i ) ;
1855
+ char c = ( char ) sci . CharAt ( i ) ;
1851
1856
1852
1857
if ( c == '{' )
1853
1858
{
1854
- int style = Sci . BaseStyleAt ( i ) ;
1859
+ int style = sci . BaseStyleAt ( i ) ;
1855
1860
if ( ASComplete . IsCommentStyle ( style ) || ASComplete . IsLiteralStyle ( style ) || genCount > 0 )
1856
1861
continue ;
1857
1862
funcBodyStart = i ;
1858
1863
break ;
1859
1864
}
1860
1865
else if ( c == '<' )
1861
1866
{
1862
- int style = Sci . BaseStyleAt ( i ) ;
1867
+ int style = sci . BaseStyleAt ( i ) ;
1863
1868
if ( style == 10 )
1864
1869
genCount ++ ;
1865
1870
}
1866
1871
else if ( c == '>' )
1867
1872
{
1868
- int style = Sci . BaseStyleAt ( i ) ;
1873
+ int style = sci . BaseStyleAt ( i ) ;
1869
1874
if ( style == 10 )
1870
1875
genCount -- ;
1871
1876
}
1872
1877
}
1873
1878
1874
1879
if ( funcBodyStart == - 1 )
1875
- return - 1 ;
1880
+ return - 1 ;
1881
+
1882
+ if ( needsPointOfInsertion )
1883
+ {
1884
+ int ln = sci . LineFromPosition ( funcBodyStart ) ;
1876
1885
1877
- int ln = Sci . LineFromPosition ( funcBodyStart ) ;
1878
- int indent = Sci . GetLineIndentation ( ln ) ;
1879
- while ( funcBodyStart <= posEnd )
1886
+ funcBodyStart ++ ;
1887
+ return GetOrSetPointOfInsertion ( funcBodyStart , posEnd , ln , sci ) ;
1888
+ }
1889
+
1890
+ return funcBodyStart + 1 ;
1891
+ }
1892
+
1893
+ /// <summary>
1894
+ /// Tries to get the best position after a statement, to add new code, inserting new lines if needed.
1895
+ /// </summary>
1896
+ /// <param name="startPos">The position inside the Scintilla document where the statement starts</param>
1897
+ /// <param name="endPos">The position inside the Scintilla document where the owner member of the statement ends</param>
1898
+ /// <param name="sci">The Scintilla control containing the document</param>
1899
+ /// <returns>The position inside the Scintilla document</returns>
1900
+ /// <remarks>For now internal because for the current use we don't need to detect a lot of cases! use with caution!</remarks>
1901
+ internal static int GetEndOfStatement ( int startPos , int endPos , ScintillaControl sci )
1902
+ {
1903
+ int groupCount = 0 ;
1904
+ int brCount = 0 ;
1905
+ int statementEnd = startPos ;
1906
+ while ( statementEnd < endPos )
1880
1907
{
1881
- char c = ( char ) Sci . CharAt ( ++ funcBodyStart ) ;
1908
+ char c = ( char ) sci . CharAt ( statementEnd ++ ) ;
1909
+
1910
+ bool endOfStatement = false ;
1911
+ switch ( c )
1912
+ {
1913
+ case '\r ' :
1914
+ case '\n ' :
1915
+ endOfStatement = groupCount == 0 && brCount == 0 ;
1916
+ break ;
1917
+ case ';' :
1918
+ endOfStatement = brCount == 0 ; // valid or invalid end of statement
1919
+ break ;
1920
+ case '(' :
1921
+ case '[' :
1922
+ groupCount ++ ;
1923
+ break ;
1924
+ case '{' :
1925
+ brCount ++ ;
1926
+ break ;
1927
+ case ')' :
1928
+ case ']' :
1929
+ groupCount -- ;
1930
+ break ;
1931
+ case '}' :
1932
+ brCount -- ;
1933
+ break ;
1934
+ }
1935
+
1936
+ if ( endOfStatement ) break ;
1937
+ }
1938
+
1939
+ return statementEnd ;
1940
+ }
1941
+
1942
+ /// <summary>
1943
+ /// Looks for the best next position to insert new code, inserting new lines if needed
1944
+ /// </summary>
1945
+ /// <param name="startPos">The position inside the Scintilla document to start looking for the insertion position</param>
1946
+ /// <param name="endPos">The end position inside the Scintilla document</param>
1947
+ /// <param name="baseLine">The line inside the document to use as the base for the indentation level and detect if the desired point
1948
+ /// matches the end line</param>
1949
+ /// <param name="sci">The ScintillaControl where our document resides</param>
1950
+ /// <returns>The insertion point position</returns>
1951
+ private static int GetOrSetPointOfInsertion ( int startPos , int endPos , int baseLine , ScintillaControl sci )
1952
+ {
1953
+ char [ ] characterClass = { ' ' , '\r ' , '\n ' , '\t ' } ;
1954
+ int nCount = 0 ;
1955
+ int extraLine = 1 ;
1956
+
1957
+ int initialLn = sci . LineFromPosition ( startPos ) ;
1958
+ int baseIndent = sci . GetLineIndentation ( baseLine ) ;
1959
+
1960
+ bool found = false ;
1961
+ while ( startPos <= endPos )
1962
+ {
1963
+ char c = ( char ) sci . CharAt ( startPos ) ;
1882
1964
if ( Array . IndexOf ( characterClass , c ) == - 1 )
1883
1965
{
1884
- int endLn = Sci . LineFromPosition ( funcBodyStart ) ;
1885
- if ( endLn == ln )
1966
+ int endLn = sci . LineFromPosition ( startPos ) ;
1967
+ if ( endLn == baseLine || endLn == initialLn )
1886
1968
{
1887
- Sci . InsertText ( funcBodyStart , Sci . NewLineMarker ) ;
1969
+ sci . InsertText ( startPos , sci . NewLineMarker ) ;
1888
1970
// Do we want to set the line indentation no matter what? {\r\t\t\t\r} -> {\r\t\r}
1889
1971
// Better results in most cases, but maybe highly unwanted in others?
1890
- Sci . SetLineIndentation ( ++ endLn , indent + Sci . Indent ) ;
1891
- funcBodyStart = Sci . LineIndentPosition ( endLn ) ;
1972
+ sci . SetLineIndentation ( ++ endLn , baseIndent + sci . Indent ) ;
1973
+ startPos = sci . LineIndentPosition ( endLn ) ;
1892
1974
}
1893
1975
if ( c == '}' )
1894
1976
{
1895
- Sci . InsertText ( funcBodyStart , Sci . NewLineMarker ) ;
1896
- Sci . SetLineIndentation ( endLn + 1 , indent ) ;
1977
+ sci . InsertText ( startPos , sci . NewLineMarker ) ;
1978
+ sci . SetLineIndentation ( endLn + 1 , baseIndent ) ;
1979
+ // In relation with previous comment... we'll reinden this one: {\r} -> {\r\t\r}
1980
+ if ( sci . GetLineIndentation ( endLn ) <= baseIndent )
1981
+ {
1982
+ sci . SetLineIndentation ( endLn , baseIndent + sci . Indent ) ;
1983
+ startPos = sci . LineIndentPosition ( endLn ) ;
1984
+ }
1897
1985
}
1986
+ found = true ;
1898
1987
break ;
1899
1988
}
1900
- else if ( Sci . EOLMode == 1 && c == '\r ' && ( ++ nCount ) > extraLine )
1989
+ else if ( sci . EOLMode == 1 && c == '\r ' && ( ++ nCount ) > extraLine )
1901
1990
{
1991
+ found = true ;
1902
1992
break ;
1903
1993
}
1904
1994
else if ( c == '\n ' && ( ++ nCount ) > extraLine )
1905
1995
{
1906
- if ( Sci . EOLMode != 2 )
1996
+ if ( sci . EOLMode != 2 )
1907
1997
{
1908
- funcBodyStart -- ;
1998
+ startPos -- ;
1909
1999
}
2000
+ found = true ;
1910
2001
break ;
1911
2002
}
1912
- }
1913
- return funcBodyStart ;
2003
+ startPos ++ ;
2004
+ }
2005
+
2006
+ if ( ! found ) startPos -- ;
2007
+
2008
+ return startPos ;
1914
2009
}
1915
2010
1916
2011
private static void GenerateToString ( ClassModel inClass , ScintillaControl sci , MemberModel member )
0 commit comments