Browse Source

Added generics support to the VB.Net parser.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@212 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 21 years ago
parent
commit
5b197228c4
  1. 64
      src/AddIns/BackendBindings/VBNetBinding/Project/Src/FormattingStrategy/VBNetFormattingStrategy.cs
  2. 1
      src/Libraries/ICSharpCode.TextEditor/Project/Resources/VBNET-Mode.xshd
  3. 3
      src/Libraries/NRefactory/Project/NRefactory.csproj
  4. 12
      src/Libraries/NRefactory/Project/Src/Lexer/BuildKeywords.pl
  5. 0
      src/Libraries/NRefactory/Project/Src/Lexer/CSharp/KeywordList.txt
  6. 2
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Keywords.cs
  7. 150
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs
  8. 14
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Tokens.cs
  9. 3
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/VBNetKeywordList.txt
  10. 5
      src/Libraries/NRefactory/Project/Src/Output/CSharp/CSharpOutputVisitor.cs
  11. 13
      src/Libraries/NRefactory/Project/Src/Output/VBNet/VBNetOutputVisitor.cs
  12. 2
      src/Libraries/NRefactory/Project/Src/Parser/AST/General/Expressions/BinaryOperatorExpression.cs
  13. 18
      src/Libraries/NRefactory/Project/Src/Parser/AST/General/Expressions/GlobalReferenceExpression.cs
  14. 2
      src/Libraries/NRefactory/Project/Src/Parser/AST/General/GlobalScope/TypeDeclaration.cs
  15. 2748
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs
  16. 138
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG
  17. 6
      src/Libraries/NRefactory/Project/Src/Parser/Visitors/AbstractASTVisitor.cs
  18. 1
      src/Libraries/NRefactory/Project/Src/Parser/Visitors/IASTVisitor.cs
  19. 3
      src/Libraries/NRefactory/Project/Src/Parser/gen.bat
  20. 84
      src/Libraries/NRefactory/Test/Lexer/VBNet/LexerTests.cs
  21. 70
      src/Libraries/NRefactory/Test/Lexer/VBNet/LiteralsTests.cs
  22. 79
      src/Libraries/NRefactory/Test/Parser/GlobalScope/TypeDeclarationTests.cs
  23. 161
      src/Libraries/NRefactory/Test/Parser/Statements/LocalVariableDeclarationTests.cs
  24. 24
      src/Main/Base/Project/Src/Dom/Implementations/DefaultClass.cs
  25. 12
      src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs
  26. 5
      src/Main/Base/Project/Src/Services/ParserService/DefaultProjectContent.cs

64
src/AddIns/BackendBindings/VBNetBinding/Project/Src/FormattingStrategy/VBNetFormattingStrategy.cs

@ -59,24 +59,47 @@ namespace VBNetBinding.FormattingStrategy
keywords = new StringCollection(); keywords = new StringCollection();
keywords.AddRange(new string[] { keywords.AddRange(new string[] {
"AddHandler", "AddressOf", "Alias", "And", "AndAlso", "Ansi", "As", "Assembly", "AddHandler", "AddressOf", "Alias", "And",
"Auto", "Boolean", "ByRef", "Byte", "ByVal", "Call", "Case", "Catch", "AndAlso", "As", "Boolean", "ByRef",
"CBool", "CByte", "CChar", "CDate", "CDec", "CDbl", "Char", "CInt", "Class", "Byte", "ByVal", "Call", "Case",
"CLng", "CObj", "Const", "CShort", "CSng", "CStr", "CType", "Catch", "CBool", "CByte", "CChar",
"Date", "Decimal", "Declare", "Default", "Delegate", "Dim", "DirectCast", "Do", "CDate", "CDbl", "CDec", "Char",
"Double", "Each", "Else", "ElseIf", "End", "Enum", "Erase", "Error", "CInt", "Class", "CLng", "CObj",
"Event", "Exit", "False", "Finally", "For", "Friend", "Function", "Get", "Const", "Continue", "CSByte", "CShort",
"GetType", "GoSub", "GoTo", "Handles", "If", "Implements", "Imports", "In", "CSng", "CStr", "CType", "CUInt",
"Inherits", "Integer", "Interface", "Is", "Let", "Lib", "Like", "Long", "CULng", "CUShort", "Date", "Decimal",
"Loop", "Me", "Mod", "Module", "MustInherit", "MustOverride", "MyBase", "MyClass", "Declare", "Default", "Delegate", "Dim",
"Namespace", "New", "Next", "Not", "Nothing", "NotInheritable", "NotOverridable", "Object", "DirectCast", "Do", "Double", "Each",
"On", "Option", "Optional", "Or", "OrElse", "Overloads", "Overridable", "Overrides", "Else", "ElseIf", "End", "EndIf", // EndIf special case: converted to "End If"
"ParamArray", "Preserve", "Private", "Property", "Protected", "Public", "RaiseEvent", "ReadOnly", "Enum", "Erase", "Error", "Event",
"ReDim", "Region", "REM", "RemoveHandler", "Resume", "Return", "Select", "Set", "Shadows", "Exit", "False", "Finally", "For",
"Shared", "Short", "Single", "Static", "Step", "Stop", "String", "Structure", "Friend", "Function", "Get", "GetType",
"Sub", "SyncLock", "Then", "Throw", "To", "True", "Try", "TypeOf", "Global", "GoSub", "GoTo", "Handles",
"Unicode", "Until", "Variant", "When", "While", "With", "WithEvents", "WriteOnly", "Xor" "If", "Implements", "Imports", "In",
}); "Inherits", "Integer", "Interface", "Is",
"IsNot", "Let", "Lib", "Like",
"Long", "Loop", "Me", "Mod",
"Module", "MustInherit", "MustOverride", "MyBase",
"MyClass", "Namespace", "Narrowing", "New",
"Next", "Not", "Nothing", "NotInheritable",
"NotOverridable", "Object", "Of", "On",
"Operator", "Option", "Optional", "Or",
"OrElse", "Overloads", "Overridable", "Overrides",
"ParamArray", "Partial", "Private", "Property",
"Protected", "Public", "RaiseEvent", "ReadOnly",
"ReDim", "REM", "RemoveHandler", "Resume",
"Return", "SByte", "Select", "Set",
"Shadows", "Shared", "Short", "Single",
"Static", "Step", "Stop", "String",
"Structure", "Sub", "SyncLock", "Then",
"Throw", "To", "True", "Try",
"TryCast", "TypeOf", "UInteger", "ULong",
"UShort", "Using", "Variant", "Wend",
"When", "While", "Widening", "With",
"WithEvents", "WriteOnly", "Xor",
// these are not keywords, but context dependend
"Until", "Ansi", "Unicode", "Region", "Preserve"
});
} }
/// <summary> /// <summary>
@ -245,7 +268,10 @@ namespace VBNetBinding.FormattingStrategy
string regex = "(?:\\W|^)(" + keyword + ")(?:\\W|$)"; string regex = "(?:\\W|^)(" + keyword + ")(?:\\W|$)";
MatchCollection matches = Regex.Matches(texttoreplace, regex, RegexOptions.IgnoreCase | RegexOptions.Singleline); MatchCollection matches = Regex.Matches(texttoreplace, regex, RegexOptions.IgnoreCase | RegexOptions.Singleline);
foreach (Match match in matches) { foreach (Match match in matches) {
textArea.Document.Replace(lineAbove.Offset + match.Groups[1].Index, match.Groups[1].Length, keyword); if (keyword == "EndIf") // special case
textArea.Document.Replace(lineAbove.Offset + match.Groups[1].Index, match.Groups[1].Length, "End If");
else
textArea.Document.Replace(lineAbove.Offset + match.Groups[1].Index, match.Groups[1].Length, keyword);
++undoCount; ++undoCount;
} }
} }

1
src/Libraries/ICSharpCode.TextEditor/Project/Resources/VBNET-Mode.xshd

@ -169,6 +169,7 @@
<Key word = "Continue" /> <Key word = "Continue" />
<Key word = "Dim" /> <Key word = "Dim" />
<Key word = "ReDim" /> <Key word = "ReDim" />
<Key word = "Preserve" />
<Key word = "Erase" /> <Key word = "Erase" />
<Key word = "On" /> <Key word = "On" />
<Key word = "Error" /> <Key word = "Error" />

3
src/Libraries/NRefactory/Project/NRefactory.csproj

@ -188,9 +188,10 @@
<Compile Include="Src\Parser\Visitors\CSharpToVBNetConvertVisitor.cs" /> <Compile Include="Src\Parser\Visitors\CSharpToVBNetConvertVisitor.cs" />
<Compile Include="Src\Parser\Visitors\PrefixFieldsVisitor.cs" /> <Compile Include="Src\Parser\Visitors\PrefixFieldsVisitor.cs" />
<Compile Include="Src\Parser\Visitors\VBNetToCSharpConvertVisitor.cs" /> <Compile Include="Src\Parser\Visitors\VBNetToCSharpConvertVisitor.cs" />
<Compile Include="Src\Parser\AST\General\Expressions\GlobalReferenceExpression.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Src\Lexer\CSharp\CSharpKeywordList.txt" /> <Content Include="Src\Lexer\CSharp\KeywordList.txt" />
<Content Include="Src\Lexer\VBNet\VBNetKeywordList.txt" /> <Content Include="Src\Lexer\VBNet\VBNetKeywordList.txt" />
<Content Include="Src\Parser\CSharp\trace.txt" /> <Content Include="Src\Parser\CSharp\trace.txt" />
<Content Include="Src\Parser\Frames\OldSharpCoco.exe" /> <Content Include="Src\Parser\Frames\OldSharpCoco.exe" />

12
src/Libraries/NRefactory/Project/Src/Lexer/BuildKeywords.pl

@ -1,7 +1,7 @@
#!/bin/perl #!/bin/perl
# File names # File names
$keyword_file = "CSharpKeywordList.txt"; $keyword_file = "KeywordList.txt";
$keywords_outfile = "Keywords.cs"; $keywords_outfile = "Keywords.cs";
$tokens_outfile = "Tokens.cs"; $tokens_outfile = "Tokens.cs";
$unittests_outfile = "LexerTests.cs"; $unittests_outfile = "LexerTests.cs";
@ -19,10 +19,10 @@ print "done.\n";
print "starting analysation ... this could take a few minutes.\n"; print "starting analysation ... this could take a few minutes.\n";
foreach (@raw_data) { foreach (@raw_data) {
if ($_=~/^\s*\$(\w+)\s*=\s*(\S+)$/) { if ($_=~/^\s*\$(\w+)\s*=\s*(\S+)\s*$/) {
#properties form: $PROPERTY = "VALUE" #properties form: $PROPERTY = "VALUE"
$properties{$1} = $2; $properties{$1} = $2;
} elsif ($_=~/^\s*(\w+)\s*=\s*(\S+)$/) { } elsif ($_=~/^\s*(\w+)\s*=\s*(\S+)\s*$/) {
#special characters form: name = "VALUE" #special characters form: name = "VALUE"
$specialCharLookup{$2} = $1; $specialCharLookup{$2} = $1;
$special_chars[$#special_chars + 1] = $1; $special_chars[$#special_chars + 1] = $1;
@ -40,7 +40,11 @@ foreach (@raw_data) {
} elsif ($_=~/^\s*(\w+)\s*$/) { } elsif ($_=~/^\s*(\w+)\s*$/) {
#special terminal classes form: name #special terminal classes form: name
$terminals[$#terminals + 1] = $1 $terminals[$#terminals + 1] = $1
} } elsif ($_=~/^\s*(#.*)?$/) {
#ignore empty line
} else {
print "unknown line: $_";
}
} }

0
src/Libraries/NRefactory/Project/Src/Lexer/CSharp/CSharpKeywordList.txt → src/Libraries/NRefactory/Project/Src/Lexer/CSharp/KeywordList.txt

2
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Keywords.cs

@ -159,6 +159,8 @@ namespace ICSharpCode.NRefactory.Parser.VB
"UINTEGER", "UINTEGER",
"ULONG", "ULONG",
"USHORT", "USHORT",
"GLOBAL",
"TRYCAST",
"OF", "OF",
"NARROWING", "NARROWING",
"WIDENING", "WIDENING",

150
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs

@ -123,9 +123,9 @@ namespace ICSharpCode.NRefactory.Parser.VB
int x = col; int x = col;
int y = line; int y = line;
string s = ReadDate(); string s = ReadDate();
DateTime time = DateTime.Now; DateTime time = new DateTime(1, 1, 1, 0, 0, 0);
try { try {
time = System.DateTime.Parse(s, System.Globalization.CultureInfo.InvariantCulture); time = DateTime.Parse(s, System.Globalization.CultureInfo.InvariantCulture, DateTimeStyles.NoCurrentDateDefault);
} catch (Exception e) { } catch (Exception e) {
errors.Error(line, col, String.Format("Invalid date time {0}", e)); errors.Error(line, col, String.Format("Invalid date time {0}", e));
} }
@ -169,7 +169,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
return new Token(keyWordToken, x, y, s); return new Token(keyWordToken, x, y, s);
} }
// handle 'REM' comments // handle 'REM' comments
if (s.ToUpper() == "REM") { if (s.ToUpper() == "REM") {
ReadComment(); ReadComment();
if (!lineEnd) { if (!lineEnd) {
@ -178,10 +178,10 @@ namespace ICSharpCode.NRefactory.Parser.VB
} }
continue; continue;
} }
lineEnd = false; lineEnd = false;
return new Token(Tokens.Identifier, x, y, s); return new Token(Tokens.Identifier, x, y, s);
} }
if (Char.IsDigit(ch)) { if (Char.IsDigit(ch)) {
lineEnd = false; lineEnd = false;
@ -197,10 +197,10 @@ namespace ICSharpCode.NRefactory.Parser.VB
if (Char.ToUpper(ch) == 'H' || Char.ToUpper(ch) == 'O') { if (Char.ToUpper(ch) == 'H' || Char.ToUpper(ch) == 'O') {
--col; --col;
return ReadDigit('&', col); return ReadDigit('&', col);
} }
return ReadOperator('&'); return ReadOperator('&');
} }
if (ch == '\'') { if (ch == '\'' || ch == '\u2018' || ch == '\u2019') {
int x = col - 1; int x = col - 1;
int y = line; int y = line;
ReadComment(); ReadComment();
@ -236,7 +236,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
return new Token(Tokens.EOF); return new Token(Tokens.EOF);
} }
string ReadIdent(char ch) string ReadIdent(char ch)
{ {
sb.Length = 0; sb.Length = 0;
sb.Append(ch); sb.Append(ch);
@ -301,7 +301,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
++col; ++col;
while (reader.Peek() != -1 && hex.IndexOf(Char.ToUpper((char)reader.Peek())) != -1) { while (reader.Peek() != -1 && hex.IndexOf(Char.ToUpper((char)reader.Peek())) != -1) {
ch = (char)reader.Read(); ch = (char)reader.Read();
sb.Append(ch); sb.Append(ch);
digit += Char.ToUpper(ch); digit += Char.ToUpper(ch);
++col; ++col;
} }
@ -312,7 +312,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
++col; ++col;
while (reader.Peek() != -1 && okt.IndexOf(Char.ToUpper((char)reader.Peek())) != -1) { while (reader.Peek() != -1 && okt.IndexOf(Char.ToUpper((char)reader.Peek())) != -1) {
ch = (char)reader.Read(); ch = (char)reader.Read();
sb.Append(ch); sb.Append(ch);
digit += Char.ToUpper(ch); digit += Char.ToUpper(ch);
++col; ++col;
} }
@ -326,47 +326,74 @@ namespace ICSharpCode.NRefactory.Parser.VB
} }
} }
if (reader.Peek() != -1 && ("%&SIL".IndexOf(Char.ToUpper((char)reader.Peek())) != -1 || ishex || isokt)) { if (reader.Peek() != -1 && ("%&SILU".IndexOf(Char.ToUpper((char)reader.Peek())) != -1 || ishex || isokt)) {
ch = (char)reader.Peek(); ch = (char)reader.Peek();
sb.Append(ch); sb.Append(ch);
ch = Char.ToUpper(ch); ch = Char.ToUpper(ch);
bool unsigned = ch == 'U';
if (unsigned) {
ch = (char)reader.Peek();
sb.Append(ch);
ch = Char.ToUpper(ch);
if (ch != 'I' && ch != 'L' && ch != 'S') {
errors.Error(line, col, "Invalid type character: U" + ch);
}
}
++col; ++col;
if (isokt) { if (isokt) {
reader.Read(); reader.Read();
long number = 0L; ulong number = 0L;
for (int i = 0; i < digit.Length; ++i) { for (int i = 0; i < digit.Length; ++i) {
number = number * 8 + digit[i] - '0'; number = number * 8 + digit[i] - '0';
} }
if (ch == 'S') { if (ch == 'S') {
return new Token(Tokens.LiteralSingle, x, y, sb.ToString(), (short)number); if (unsigned)
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), (ushort)number);
else
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), (short)number);
} else if (ch == '%' || ch == 'I') { } else if (ch == '%' || ch == 'I') {
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), (int)number); if (unsigned)
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), (uint)number);
else
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), (int)number);
} else if (ch == '&' || ch == 'L') { } else if (ch == '&' || ch == 'L') {
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), (long)number); if (unsigned)
} else { return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), (ulong)number);
if (number > int.MaxValue || number < int.MinValue) { else
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), (long)number); return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), (long)number);
} else {
if (number > uint.MaxValue) {
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), unchecked((long)number));
} else { } else {
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), (int)number); return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), unchecked((int)number));
} }
} }
} }
if (ch == 'S') { if (ch == 'S') {
reader.Read(); reader.Read();
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int16.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number)); if (unsigned)
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), UInt16.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number));
else
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int16.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number));
} else if (ch == '%' || ch == 'I') { } else if (ch == '%' || ch == 'I') {
reader.Read(); reader.Read();
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int32.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number)); if (unsigned)
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), UInt32.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number));
else
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int32.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number));
} else if (ch == '&' || ch == 'L') { } else if (ch == '&' || ch == 'L') {
reader.Read(); reader.Read();
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int64.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number)); if (unsigned)
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), UInt64.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number));
else
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int64.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number));
} else if (ishex) { } else if (ishex) {
--col; --col;
long number = Int64.Parse(digit, NumberStyles.HexNumber); ulong number = UInt64.Parse(digit, NumberStyles.HexNumber);
if (number > int.MaxValue || number < int.MinValue) { if (number > uint.MaxValue) {
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), number); return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), unchecked((long)number));
} else { } else {
return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), (int)number); return new Token(Tokens.LiteralInteger, x, y, sb.ToString(), unchecked((int)number));
} }
} }
} }
@ -385,7 +412,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
++col; ++col;
} }
} else { } else {
nextToken = new Token(Tokens.Dot, x, y); nextToken = new Token(Tokens.Dot, x, y);
} }
} }
@ -404,29 +431,46 @@ namespace ICSharpCode.NRefactory.Parser.VB
} }
if (reader.Peek() != -1) { if (reader.Peek() != -1) {
if (Char.ToUpper((char)reader.Peek()) == 'R' || Char.ToUpper((char)reader.Peek()) == '#') { // double type suffix (obsolete, double is default) switch (char.ToUpper((char)reader.Peek())) {
reader.Read(); case 'R':
++col; case '#':
isdouble = true; reader.Read();
} else if (Char.ToUpper((char)reader.Peek()) == 'D' || Char.ToUpper((char)reader.Peek()) == '@') { // decimal value ++col;
reader.Read(); isdouble = true;
++col; break;
isdecimal = true; case 'D':
} else if (Char.ToUpper((char)reader.Peek()) == 'F' || Char.ToUpper((char)reader.Peek()) == '!') { // decimal value case '@':
reader.Read(); reader.Read();
++col; ++col;
issingle = true; isdecimal = true;
break;
case 'F':
case '!':
reader.Read();
++col;
issingle = true;
break;
} }
} }
if (issingle) { try {
return new Token(Tokens.LiteralSingle, x, y, sb.ToString(), Single.Parse(digit, CultureInfo.InvariantCulture)); if (issingle) {
} return new Token(Tokens.LiteralSingle, x, y, sb.ToString(), Single.Parse(digit, CultureInfo.InvariantCulture));
if (isdecimal) { }
return new Token(Tokens.LiteralDecimal, x, y, sb.ToString(), Decimal.Parse(digit, CultureInfo.InvariantCulture)); if (isdecimal) {
} return new Token(Tokens.LiteralDecimal, x, y, sb.ToString(), Decimal.Parse(digit, NumberStyles.Currency | NumberStyles.AllowExponent, CultureInfo.InvariantCulture));
if (isdouble) { }
return new Token(Tokens.LiteralDouble, x, y, sb.ToString(), Double.Parse(digit, CultureInfo.InvariantCulture)); if (isdouble) {
return new Token(Tokens.LiteralDouble, x, y, sb.ToString(), Double.Parse(digit, CultureInfo.InvariantCulture));
}
} catch (FormatException) {
errors.Error(line, col, String.Format("{0} is not a parseable number", digit));
if (issingle)
return new Token(Tokens.LiteralSingle, x, y, sb.ToString(), 0f);
if (isdecimal)
return new Token(Tokens.LiteralDecimal, x, y, sb.ToString(), 0m);
if (isdouble)
return new Token(Tokens.LiteralDouble, x, y, sb.ToString(), 0.0);
} }
Token token; Token token;
try { try {
@ -434,8 +478,12 @@ namespace ICSharpCode.NRefactory.Parser.VB
} catch (Exception) { } catch (Exception) {
try { try {
token = new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int64.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number)); token = new Token(Tokens.LiteralInteger, x, y, sb.ToString(), Int64.Parse(digit, ishex ? NumberStyles.HexNumber : NumberStyles.Number));
} catch (Exception) { } catch (FormatException) {
errors.Error(line, col, String.Format("{0} is not a parseable number (too long?)", sb.ToString())); errors.Error(line, col, String.Format("{0} is not a parseable number", digit));
// fallback, when nothing helps :)
token = new Token(Tokens.LiteralInteger, x, y, sb.ToString(), 0);
} catch (OverflowException) {
errors.Error(line, col, String.Format("{0} is too long for a integer literal", digit));
// fallback, when nothing helps :) // fallback, when nothing helps :)
token = new Token(Tokens.LiteralInteger, x, y, sb.ToString(), 0); token = new Token(Tokens.LiteralInteger, x, y, sb.ToString(), 0);
} }
@ -670,8 +718,8 @@ namespace ICSharpCode.NRefactory.Parser.VB
// Prevent OverflowException when Peek returns -1 // Prevent OverflowException when Peek returns -1
int tmp = reader.Peek(); int tmp = reader.Peek();
if (tmp > 0 && Char.IsDigit((char)tmp)) { if (tmp > 0 && Char.IsDigit((char)tmp)) {
--col; --col;
return ReadDigit('.', col); return ReadDigit('.', col);
} }
return new Token(Tokens.Dot, x, y); return new Token(Tokens.Dot, x, y);
case '(': case '(':

14
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Tokens.cs

@ -205,12 +205,14 @@ namespace ICSharpCode.NRefactory.Parser.VB
public const int UInteger = 191; public const int UInteger = 191;
public const int ULong = 192; public const int ULong = 192;
public const int UShort = 193; public const int UShort = 193;
public const int Of = 194; public const int Global = 194;
public const int Narrowing = 195; public const int TryCast = 195;
public const int Widening = 196; public const int Of = 196;
public const int Partial = 197; public const int Narrowing = 197;
public const int Widening = 198;
public const int Partial = 199;
public const int maxToken = 198; public const int maxToken = 200;
static BitArray NewSet(params int[] values) static BitArray NewSet(params int[] values)
{ {
BitArray bitArray = new BitArray(maxToken); BitArray bitArray = new BitArray(maxToken);
@ -420,6 +422,8 @@ namespace ICSharpCode.NRefactory.Parser.VB
"UInteger", "UInteger",
"ULong", "ULong",
"UShort", "UShort",
"Global",
"TryCast",
"Of", "Of",
"Narrowing", "Narrowing",
"Widening", "Widening",

3
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/VBNetKeywordList.txt

@ -217,7 +217,8 @@ ConcatStringAssign = "&="
"UInteger" "UInteger"
"ULong" "ULong"
"UShort" "UShort"
# TODO: What about Global, Expands ? "Global"
"TryCast"
"Of" "Of"
"Narrowing" "Narrowing"
"Widening" "Widening"

5
src/Libraries/NRefactory/Project/Src/Output/CSharp/CSharpOutputVisitor.cs

@ -1973,6 +1973,11 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
return null; return null;
} }
public object Visit(GlobalReferenceExpression globalReferenceExpression, object data) {
outputFormatter.PrintIdentifier("global::");
return null;
}
public object Visit(ObjectCreateExpression objectCreateExpression, object data) public object Visit(ObjectCreateExpression objectCreateExpression, object data)
{ {
outputFormatter.PrintToken(Tokens.New); outputFormatter.PrintToken(Tokens.New);

13
src/Libraries/NRefactory/Project/Src/Output/VBNet/VBNetOutputVisitor.cs

@ -1737,13 +1737,9 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
break; break;
case BinaryOperatorType.AsCast: case BinaryOperatorType.AsCast:
outputFormatter.PrintIdentifier("CType(Microsoft.VisualBasic.IIf(TypeOf "); outputFormatter.PrintIdentifier("TryCast(");
nodeTracker.TrackedVisit(binaryOperatorExpression.Left, data); nodeTracker.TrackedVisit(binaryOperatorExpression.Left, data);
outputFormatter.PrintIdentifier(" Is ");
nodeTracker.TrackedVisit(binaryOperatorExpression.Right, data);
outputFormatter.PrintIdentifier(", "); outputFormatter.PrintIdentifier(", ");
nodeTracker.TrackedVisit(binaryOperatorExpression.Left, data);
outputFormatter.PrintIdentifier(", Nothing), ");
nodeTracker.TrackedVisit(binaryOperatorExpression.Right, data); nodeTracker.TrackedVisit(binaryOperatorExpression.Right, data);
outputFormatter.PrintIdentifier(")"); outputFormatter.PrintIdentifier(")");
return null; return null;
@ -2103,6 +2099,13 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
return null; return null;
} }
public object Visit(GlobalReferenceExpression globalReferenceExpression, object data)
{
outputFormatter.PrintToken(Tokens.Global);
outputFormatter.PrintToken(Tokens.Dot);
return null;
}
public object Visit(ObjectCreateExpression objectCreateExpression, object data) public object Visit(ObjectCreateExpression objectCreateExpression, object data)
{ {
outputFormatter.PrintToken(Tokens.New); outputFormatter.PrintToken(Tokens.New);

2
src/Libraries/NRefactory/Project/Src/Parser/AST/General/Expressions/BinaryOperatorExpression.cs

@ -59,7 +59,7 @@ namespace ICSharpCode.NRefactory.Parser.AST
ReferenceInequality, ReferenceInequality,
/// <summary>C#: Is</summary> /// <summary>C#: Is</summary>
TypeCheck, TypeCheck,
/// <summary>C#: as-cast</summary> /// <summary>'as' in C#, 'TryCast(l, r)' in VB</summary>
AsCast, AsCast,
/// <summary>VB-only: Like</summary> /// <summary>VB-only: Like</summary>
Like, Like,

18
src/Libraries/NRefactory/Project/Src/Parser/AST/General/Expressions/GlobalReferenceExpression.cs

@ -0,0 +1,18 @@
using System;
using System.Collections;
namespace ICSharpCode.NRefactory.Parser.AST
{
public class GlobalReferenceExpression : Expression
{
public override object AcceptVisitor(IASTVisitor visitor, object data)
{
return visitor.Visit(this, data);
}
public override string ToString()
{
return String.Format("[ThisReferenceExpression]");
}
}
}

2
src/Libraries/NRefactory/Project/Src/Parser/AST/General/GlobalScope/TypeDeclaration.cs

@ -137,6 +137,8 @@ namespace ICSharpCode.NRefactory.Parser.AST
public TemplateDefinition(string name, ArrayList attributes) : base(attributes) public TemplateDefinition(string name, ArrayList attributes) : base(attributes)
{ {
if (name == null || name.Length == 0)
name = "?";
this.name = name; this.name = name;
} }

2748
src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs

File diff suppressed because it is too large Load Diff

138
src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG

@ -411,12 +411,14 @@ TOKENS
"UInteger" "UInteger"
"ULong" "ULong"
"UShort" "UShort"
"Global"
"TryCast"
"Of" "Of"
"Narrowing" "Narrowing"
"Widening" "Widening"
"Partial" "Partial"
/* END AUTOGENERATED TOKENS SECTION */ /* END AUTOGENERATED TOKENS SECTION */
PRODUCTIONS PRODUCTIONS
VBNET VBNET
@ -536,6 +538,50 @@ NamespaceMemberDecl
{ TypeModifier<m> } NonModuleDeclaration<m, attributes> { TypeModifier<m> } NonModuleDeclaration<m, attributes>
. .
/* 4.9.1 */
TypeParameterList<List<TemplateDefinition> templates>
(.
TemplateDefinition template;
.) =
"(" "Of" TypeParameter<out template>
(.
if (template != null) templates.Add(template);
.)
{
"," TypeParameter<out template>
(.
if (template != null) templates.Add(template);
.)
}
")"
.
/* 4.9.1 */
TypeParameter<out TemplateDefinition template>
=
Identifier (. template = new TemplateDefinition(t.val, null); .)
[TypeParameterConstraints<template>]
.
/* 4.9.2 */
TypeParameterConstraints<TemplateDefinition template>
(.
TypeReference constraint;
.)
=
"As"
(
"{"
TypeName<out constraint> (. if (constraint != null) { template.Bases.Add(constraint); } .)
{
","
TypeName<out constraint> (. if (constraint != null) { template.Bases.Add(constraint); } .)
}
"}"
| TypeName<out constraint> (. if (constraint != null) { template.Bases.Add(constraint); } .)
)
.
/* 6.4.2 */ /* 6.4.2 */
NonModuleDeclaration<Modifiers m,ArrayList attributes> NonModuleDeclaration<Modifiers m,ArrayList attributes>
(. (.
@ -554,6 +600,7 @@ NonModuleDeclaration<Modifiers m,ArrayList attributes>
newType.Type = Types.Class; newType.Type = Types.Class;
.) .)
Identifier (. newType.Name = t.val; newType.StartLocation = t.EndLocation; .) Identifier (. newType.Name = t.val; newType.StartLocation = t.EndLocation; .)
[ TypeParameterList<newType.Templates> ]
EndOfStmt EndOfStmt
[ ClassBaseType<out name> (. newType.BaseTypes.Add(name); .) ] [ ClassBaseType<out name> (. newType.BaseTypes.Add(name); .) ]
{ TypeImplementsClause<out names> (. newType.BaseTypes.AddRange(names); .) } { TypeImplementsClause<out names> (. newType.BaseTypes.AddRange(names); .) }
@ -587,6 +634,7 @@ NonModuleDeclaration<Modifiers m,ArrayList attributes>
newType.Type = Types.Struct; ArrayList baseInterfaces = new ArrayList(); newType.Type = Types.Struct; ArrayList baseInterfaces = new ArrayList();
.) .)
Identifier (. newType.Name = t.val; newType.StartLocation = t.EndLocation; .) Identifier (. newType.Name = t.val; newType.StartLocation = t.EndLocation; .)
[ TypeParameterList<newType.Templates> ]
EOL { TypeImplementsClause<out baseInterfaces> (. newType.BaseTypes.AddRange(baseInterfaces);.) } EOL { TypeImplementsClause<out baseInterfaces> (. newType.BaseTypes.AddRange(baseInterfaces);.) }
StructureBody<newType> StructureBody<newType>
(. (.
@ -622,6 +670,7 @@ NonModuleDeclaration<Modifiers m,ArrayList attributes>
newType.Type = Types.Interface;ArrayList baseInterfaces; newType.Type = Types.Interface;ArrayList baseInterfaces;
.) .)
Identifier (. newType.Name = t.val; newType.StartLocation = t.EndLocation; .) Identifier (. newType.Name = t.val; newType.StartLocation = t.EndLocation; .)
[ TypeParameterList<newType.Templates> ]
EndOfStmt { InterfaceBase<out baseInterfaces> (. newType.BaseTypes.AddRange(baseInterfaces.ToArray()); .) } EndOfStmt { InterfaceBase<out baseInterfaces> (. newType.BaseTypes.AddRange(baseInterfaces.ToArray()); .) }
InterfaceBody<newType> InterfaceBody<newType>
(. (.
@ -1423,10 +1472,12 @@ SimpleExpr<out Expression pexpr>
| (. Expression retExpr = null; .) | (. Expression retExpr = null; .)
( "MyBase" (. retExpr = new BaseReferenceExpression(); .) ( "MyBase" (. retExpr = new BaseReferenceExpression(); .)
| "MyClass" (. retExpr = new ClassReferenceExpression(); .) | "MyClass" (. retExpr = new ClassReferenceExpression(); .)
| "Global" (. retExpr = new GlobalReferenceExpression(); .)
) )
"." IdentifierOrKeyword<out name> (. pexpr = new FieldReferenceExpression(retExpr, name); .) "." IdentifierOrKeyword<out name> (. pexpr = new FieldReferenceExpression(retExpr, name); .)
| ObjectCreateExpression<out expr> (. pexpr = expr; .) | ObjectCreateExpression<out expr> (. pexpr = expr; .)
| /* 11.11 */ ( "DirectCast" | "CType" ) "(" Expr<out expr> "," TypeName<out type> ")" (. pexpr = new CastExpression(type, expr); .) | /* 11.11 */ ( "DirectCast" | "CType" ) "(" Expr<out expr> "," TypeName<out type> ")" (. pexpr = new CastExpression(type, expr); .)
| /* 11.11 */ "TryCast" "(" Expr<out expr> "," TypeName<out type> ")" (. pexpr = new BinaryOperatorExpression(expr, BinaryOperatorType.AsCast, new TypeReferenceExpression(type)); .)
| /* 11.11 */ CastTarget<out type> "(" Expr<out expr> ")" (. pexpr = new CastExpression(type, expr, true); .) | /* 11.11 */ CastTarget<out type> "(" Expr<out expr> ")" (. pexpr = new CastExpression(type, expr, true); .)
| /* 11.4.5 */ "AddressOf" Expr<out expr> (. pexpr = new AddressOfExpression(expr); .) | /* 11.4.5 */ "AddressOf" Expr<out expr> (. pexpr = new AddressOfExpression(expr); .)
| /* 11.5.1 */ "GetType" "(" TypeName<out type> ")" (. pexpr = new TypeOfExpression(type); .) | /* 11.5.1 */ "GetType" "(" TypeName<out type> ")" (. pexpr = new TypeOfExpression(type); .)
@ -1604,12 +1655,13 @@ MultiplicativeExpr<out Expression outExpr>
. .
ObjectCreateExpression<out Expression oce> ObjectCreateExpression<out Expression oce>
(. (.
TypeReference type = null; TypeReference type = null;
Expression initializer = null;ArrayList arguments = null; Expression initializer = null;
oce = null; ArrayList arguments = null;
.) = oce = null;
"New" TypeNameWithoutRank<out type> .) =
"New" NonArrayTypeName<out type>
["(" [ ArgumentList<out arguments> ] ")" ] ["(" [ ArgumentList<out arguments> ] ")" ]
[ ArrayInitializer<out initializer> ] [ ArrayInitializer<out initializer> ]
(. (.
@ -1621,7 +1673,7 @@ ObjectCreateExpression<out Expression oce>
oce = ace; oce = ace;
} }
.) .)
. .
/* 9.3.2 */ /* 9.3.2 */
ArgumentList<out ArrayList arguments> ArgumentList<out ArrayList arguments>
@ -1653,54 +1705,48 @@ Argument<out Expression argumentexpr>
Expr<out argumentexpr> Expr<out argumentexpr>
. .
/* Used for object create expressions (RSH) */
TypeNameWithoutRank<out TypeReference typeref>
=
NonArrayTypeName<out typeref>
(.
typeref = new TypeReference(typeref == null ? "UNKNOWN" : typeref.Type, new int[] {} );
.)
.
/* 7.1. */ /* 7.1. */
TypeName<out TypeReference typeref> TypeName<out TypeReference typeref>
(. ArrayList rank = null; typeref = null; .) (. ArrayList rank = null; typeref = null; .)
= =
NonArrayTypeName<out typeref> NonArrayTypeName<out typeref>
ArrayTypeModifiers<out rank> ArrayTypeModifiers<out rank>
(. (.
if (rank != null) { if (rank != null && typeref != null) {
typeref = new TypeReference(typeref == null ? "UNKNOWN" : typeref.Type, (int[])rank.ToArray(typeof(int))); typeref.RankSpecifier = (int[])rank.ToArray(typeof(int));
} }
.) .)
. .
/* 7.1 */ /* 7.1 */
NonArrayTypeName<out TypeReference typeref> NonArrayTypeName<out TypeReference typeref>
(. (.
string name; string name;
typeref = null; typeref = null;
.) = .) =
Qualident<out name> (. typeref = new TypeReference(name); .) Qualident<out name> (. typeref = new TypeReference(name); .)
[IF (la.kind == Tokens.OpenParenthesis && Peek(1).kind == Tokens.Of)
"(" "Of" TypeArgumentList<typeref.GenericTypes> ")"
]
| "Object" (. typeref = new TypeReference("System.Object"); .) | "Object" (. typeref = new TypeReference("System.Object"); .)
| PrimitiveTypeName<out name> (. typeref = new TypeReference(name); .) | PrimitiveTypeName<out name> (. typeref = new TypeReference(name); .)
. .
/* 7.9 */ /* 7.9 */
ArrayNameModifier<out ArrayList arrayModifiers> ArrayNameModifier<out ArrayList arrayModifiers>
(. (.
arrayModifiers = null; arrayModifiers = null;
.) = .) =
ArrayTypeModifiers<out arrayModifiers> ArrayTypeModifiers<out arrayModifiers>
. .
/* 7.9 */ /* 7.9 */
ArrayTypeModifiers<out ArrayList arrayModifiers> ArrayTypeModifiers<out ArrayList arrayModifiers>
(. (.
arrayModifiers = new ArrayList(); arrayModifiers = new ArrayList();
int i = 0; int i = 0;
.) = .) =
{ IF (IsDims()) { IF (IsDims())
"(" "("
[ RankList<out i>] [ RankList<out i>]
@ -1714,13 +1760,25 @@ ArrayTypeModifiers<out ArrayList arrayModifiers>
arrayModifiers = null; arrayModifiers = null;
} }
.) .)
. .
/* 7.9 */ /* 7.9 */
RankList<out int i> RankList<out int i>
(. i = 0; .) = (. i = 0; .) =
{ "," (. ++i; .) } { "," (. ++i; .) }
. .
/* 7.12 */
TypeArgumentList<List<TypeReference> typeArguments>
(.
TypeReference typeref;
.) =
TypeName<out typeref> (. if (typeref != null) typeArguments.Add(typeref); .)
{
","
TypeName<out typeref> (. if (typeref != null) typeArguments.Add(typeref); .)
}
.
GlobalAttributeSection = GlobalAttributeSection =
(. Point startPos = t.Location; .) (. Point startPos = t.Location; .)
@ -2197,7 +2255,7 @@ EmbeddedStatement<out Statement statement>
(. (.
// a field reference expression that stands alone is a // a field reference expression that stands alone is a
// invocation expression without parantheses and arguments // invocation expression without parantheses and arguments
if(expr is FieldReferenceExpression) { if(expr is FieldReferenceExpression || expr is IdentifierExpression) {
expr = new InvocationExpression(expr); expr = new InvocationExpression(expr);
} }
statement = new StatementExpression(expr); statement = new StatementExpression(expr);

6
src/Libraries/NRefactory/Project/Src/Parser/Visitors/AbstractASTVisitor.cs

@ -966,6 +966,12 @@ namespace ICSharpCode.NRefactory.Parser
return data; return data;
} }
public virtual object Visit(GlobalReferenceExpression globalReferenceExpression, object data)
{
Debug.Assert(globalReferenceExpression != null);
return data;
}
public virtual object Visit(ObjectCreateExpression objectCreateExpression, object data) public virtual object Visit(ObjectCreateExpression objectCreateExpression, object data)
{ {
Debug.Assert(objectCreateExpression != null); Debug.Assert(objectCreateExpression != null);

1
src/Libraries/NRefactory/Project/Src/Parser/Visitors/IASTVisitor.cs

@ -110,6 +110,7 @@ namespace ICSharpCode.NRefactory.Parser
object Visit(IndexerExpression indexerExpression, object data); object Visit(IndexerExpression indexerExpression, object data);
object Visit(ThisReferenceExpression thisReferenceExpression, object data); object Visit(ThisReferenceExpression thisReferenceExpression, object data);
object Visit(BaseReferenceExpression baseReferenceExpression, object data); object Visit(BaseReferenceExpression baseReferenceExpression, object data);
object Visit(GlobalReferenceExpression globalReferenceExpression, object data);
object Visit(ObjectCreateExpression objectCreateExpression, object data); object Visit(ObjectCreateExpression objectCreateExpression, object data);
object Visit(ArrayCreateExpression arrayCreateExpression, object data); object Visit(ArrayCreateExpression arrayCreateExpression, object data);
object Visit(FieldReferenceExpression fieldReferenceExpression, object data); object Visit(FieldReferenceExpression fieldReferenceExpression, object data);

3
src/Libraries/NRefactory/Project/Src/Parser/gen.bat

@ -29,7 +29,8 @@ copy ..\VBNet\VBNET.ATG
OldSharpCoco -trace GIPXA -namespace ICSharpCode.NRefactory.Parser.VB VBNET.ATG OldSharpCoco -trace GIPXA -namespace ICSharpCode.NRefactory.Parser.VB VBNET.ATG
move Parser.cs ..\VBNet move Parser.cs ..\VBNet
del cs.ATG VBNET.ATG >NUL del cs.ATG
del VBNET.ATG
:exit :exit
pause pause

84
src/Libraries/NRefactory/Test/Lexer/VBNet/LexerTests.cs

@ -1095,5 +1095,89 @@ namespace ICSharpCode.NRefactory.Tests.Lexer.VB
ILexer lexer = GenerateLexer(new StringReader("Xor")); ILexer lexer = GenerateLexer(new StringReader("Xor"));
Assert.AreEqual(Tokens.Xor, lexer.NextToken().kind); Assert.AreEqual(Tokens.Xor, lexer.NextToken().kind);
} }
[Test()]
public void TestContinue()
{
ILexer lexer = GenerateLexer(new StringReader("Continue"));
Assert.AreEqual(Tokens.Continue, lexer.NextToken().kind);
}
[Test()]
public void TestOperator()
{
ILexer lexer = GenerateLexer(new StringReader("Operator"));
Assert.AreEqual(Tokens.Operator, lexer.NextToken().kind);
}
[Test()]
public void TestUsing()
{
ILexer lexer = GenerateLexer(new StringReader("Using"));
Assert.AreEqual(Tokens.Using, lexer.NextToken().kind);
}
[Test()]
public void TestIsNot()
{
ILexer lexer = GenerateLexer(new StringReader("IsNot"));
Assert.AreEqual(Tokens.IsNot, lexer.NextToken().kind);
}
[Test()]
public void TestSByte()
{
ILexer lexer = GenerateLexer(new StringReader("SByte"));
Assert.AreEqual(Tokens.SByte, lexer.NextToken().kind);
}
[Test()]
public void TestUInteger()
{
ILexer lexer = GenerateLexer(new StringReader("UInteger"));
Assert.AreEqual(Tokens.UInteger, lexer.NextToken().kind);
}
[Test()]
public void TestULong()
{
ILexer lexer = GenerateLexer(new StringReader("ULong"));
Assert.AreEqual(Tokens.ULong, lexer.NextToken().kind);
}
[Test()]
public void TestUShort()
{
ILexer lexer = GenerateLexer(new StringReader("UShort"));
Assert.AreEqual(Tokens.UShort, lexer.NextToken().kind);
}
[Test()]
public void TestGlobal()
{
ILexer lexer = GenerateLexer(new StringReader("Global"));
Assert.AreEqual(Tokens.Global, lexer.NextToken().kind);
}
[Test()]
public void TestTryCast()
{
ILexer lexer = GenerateLexer(new StringReader("TryCast"));
Assert.AreEqual(Tokens.TryCast, lexer.NextToken().kind);
}
[Test()]
public void TestOf()
{
ILexer lexer = GenerateLexer(new StringReader("Of"));
Assert.AreEqual(Tokens.Of, lexer.NextToken().kind);
}
[Test()]
public void TestNarrowing()
{
ILexer lexer = GenerateLexer(new StringReader("Narrowing"));
Assert.AreEqual(Tokens.Narrowing, lexer.NextToken().kind);
}
[Test()]
public void TestWidening()
{
ILexer lexer = GenerateLexer(new StringReader("Widening"));
Assert.AreEqual(Tokens.Widening, lexer.NextToken().kind);
}
[Test()]
public void TestPartial()
{
ILexer lexer = GenerateLexer(new StringReader("Partial"));
Assert.AreEqual(Tokens.Partial, lexer.NextToken().kind);
}
} }
} }

70
src/Libraries/NRefactory/Test/Lexer/VBNet/LiteralsTests.cs

@ -75,12 +75,68 @@ namespace ICSharpCode.NRefactory.Tests.Lexer.VB
CheckToken("\"\"\"\"c", Tokens.LiteralCharacter, '"'); CheckToken("\"\"\"\"c", Tokens.LiteralCharacter, '"');
} }
/* [Test]
* TODO : Test the following: public void TestDateLiterals()
public const int LiteralDouble = 6; {
public const int LiteralSingle = 7; CheckToken("# 8/23/1970 #", Tokens.LiteralDate, new DateTime(1970, 8, 23, 0, 0, 0));
public const int LiteralDecimal = 8; CheckToken("#8/23/1970#", Tokens.LiteralDate, new DateTime(1970, 8, 23, 0, 0, 0));
public const int LiteralDate = 9; CheckToken("# 8/23/1970 3:45:39AM #", Tokens.LiteralDate, new DateTime(1970, 8, 23, 3, 45, 39));
*/ CheckToken("# 3:45:39AM #", Tokens.LiteralDate, new DateTime(1, 1, 1, 3, 45, 39));
CheckToken("# 3:45:39 PM #", Tokens.LiteralDate, new DateTime(1, 1, 1, 15, 45, 39));
CheckToken("# 3:45:39 #", Tokens.LiteralDate, new DateTime(1, 1, 1, 3, 45, 39));
CheckToken("# 13:45:39 #", Tokens.LiteralDate, new DateTime(1, 1, 1, 13, 45, 39));
CheckToken("# 1AM #", Tokens.LiteralDate, new DateTime(1, 1, 1, 1, 0, 0));
}
[Test]
public void TestDouble()
{
CheckToken("1.0", Tokens.LiteralDouble, 1.0);
CheckToken("1.1", Tokens.LiteralDouble, 1.1);
CheckToken("2e-5", Tokens.LiteralDouble, 2e-5);
CheckToken("2.0e-5", Tokens.LiteralDouble, 2e-5);
CheckToken("2e5", Tokens.LiteralDouble, 2e5);
CheckToken("2.2e5", Tokens.LiteralDouble, 2.2e5);
CheckToken("2e+5", Tokens.LiteralDouble, 2e5);
CheckToken("2.2e+5", Tokens.LiteralDouble, 2.2e5);
CheckToken("1r", Tokens.LiteralDouble, 1.0);
CheckToken("1.0r", Tokens.LiteralDouble, 1.0);
CheckToken("1.1r", Tokens.LiteralDouble, 1.1);
CheckToken("2e-5r", Tokens.LiteralDouble, 2e-5);
CheckToken("2.0e-5r", Tokens.LiteralDouble, 2e-5);
CheckToken("2e5r", Tokens.LiteralDouble, 2e5);
CheckToken("2.2e5r", Tokens.LiteralDouble, 2.2e5);
CheckToken("2e+5r", Tokens.LiteralDouble, 2e5);
CheckToken("2.2e+5r", Tokens.LiteralDouble, 2.2e5);
}
[Test]
public void TestSingle()
{
CheckToken("1f", Tokens.LiteralSingle, 1.0f);
CheckToken("1.0f", Tokens.LiteralSingle, 1.0f);
CheckToken("1.1f", Tokens.LiteralSingle, 1.1f);
CheckToken("2e-5f", Tokens.LiteralSingle, 2e-5f);
CheckToken("2.0e-5f", Tokens.LiteralSingle, 2e-5f);
CheckToken("2e5f", Tokens.LiteralSingle, 2e5f);
CheckToken("2.2e5f", Tokens.LiteralSingle, 2.2e5f);
CheckToken("2e+5f", Tokens.LiteralSingle, 2e5f);
CheckToken("2.2e+5f", Tokens.LiteralSingle, 2.2e5f);
}
[Test]
public void TestDecimal()
{
CheckToken("1d", Tokens.LiteralDecimal, 1m);
CheckToken("1.0d", Tokens.LiteralDecimal, 1.0m);
CheckToken("1.1d", Tokens.LiteralDecimal, 1.1m);
CheckToken("2e-5d", Tokens.LiteralDecimal, 2e-5m);
CheckToken("2.0e-5d", Tokens.LiteralDecimal, 2.0e-5m);
CheckToken("2e5d", Tokens.LiteralDecimal, 2e5m);
CheckToken("2.2e5d", Tokens.LiteralDecimal, 2.2e5m);
CheckToken("2e+5d", Tokens.LiteralDecimal, 2e5m);
CheckToken("2.2e+5d", Tokens.LiteralDecimal, 2.2e5m);
}
} }
} }

79
src/Libraries/NRefactory/Test/Parser/GlobalScope/TypeDeclarationTests.cs

@ -175,6 +175,18 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2
Assert.AreEqual(2, td.EndLocation.Y, "end line"); Assert.AreEqual(2, td.EndLocation.Y, "end line");
} }
[Test]
public void VBNetEnumWithBaseClassDeclarationTest()
{
string program = "Enum TestEnum As Byte\n" +
"End Enum\n";
TypeDeclaration td = (TypeDeclaration)ParseUtilVBNet.ParseGlobal(program, typeof(TypeDeclaration));
Assert.AreEqual("TestEnum", td.Name);
Assert.AreEqual(Types.Enum, td.Type);
Assert.AreEqual("Byte", td.BaseTypes[0].ToString());
}
[Test] [Test]
public void VBNetSimpleClassTypeDeclarationWithoutLastNewLineTest() public void VBNetSimpleClassTypeDeclarationWithoutLastNewLineTest()
{ {
@ -199,6 +211,73 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2
Assert.AreEqual(Types.Class, td.Type); Assert.AreEqual(Types.Class, td.Type);
Assert.AreEqual(Modifier.Partial, td.Modifier); Assert.AreEqual(Modifier.Partial, td.Modifier);
} }
[Test]
public void VBNetGenericClassTypeDeclarationTest()
{
string declr = @"
Public Class Test(Of T)
End Class
";
TypeDeclaration td = (TypeDeclaration)ParseUtilVBNet.ParseGlobal(declr, typeof(TypeDeclaration));
Assert.AreEqual(Types.Class, td.Type);
Assert.AreEqual("Test", td.Name);
Assert.AreEqual(Modifier.Public, td.Modifier);
Assert.AreEqual(0, td.BaseTypes.Count);
Assert.AreEqual(1, td.Templates.Count);
Assert.AreEqual("T", td.Templates[0].Name);
}
[Test]
public void VBNetGenericClassWithConstraint()
{
string declr = @"
Public Class Test(Of T As IMyInterface)
End Class
";
TypeDeclaration td = (TypeDeclaration)ParseUtilVBNet.ParseGlobal(declr, typeof(TypeDeclaration));
Assert.AreEqual(Types.Class, td.Type);
Assert.AreEqual("Test", td.Name);
Assert.AreEqual(1, td.Templates.Count);
Assert.AreEqual("T", td.Templates[0].Name);
Assert.AreEqual("IMyInterface", td.Templates[0].Bases[0].Type);
}
[Test]
public void VBNetComplexGenericClassTypeDeclarationTest()
{
string declr = @"
Public Class Generic(Of T As MyNamespace.IMyInterface, S As {G(Of T()), IAnotherInterface})
Implements System.IComparable
End Class
";
TypeDeclaration td = (TypeDeclaration)ParseUtilVBNet.ParseGlobal(declr, typeof(TypeDeclaration));
Assert.AreEqual(Types.Class, td.Type);
Assert.AreEqual("Generic", td.Name);
Assert.AreEqual(Modifier.Public, td.Modifier);
Assert.AreEqual(1, td.BaseTypes.Count);
Assert.AreEqual("System.IComparable", td.BaseTypes[0]);
Assert.AreEqual(2, td.Templates.Count);
Assert.AreEqual("T", td.Templates[0].Name);
Assert.AreEqual("MyNamespace.IMyInterface", td.Templates[0].Bases[0].Type);
Assert.AreEqual("S", td.Templates[1].Name);
Assert.AreEqual(2, td.Templates[1].Bases.Count);
Assert.AreEqual("G", td.Templates[1].Bases[0].Type);
Assert.AreEqual(1, td.Templates[1].Bases[0].GenericTypes.Count);
Assert.IsTrue(td.Templates[1].Bases[0].GenericTypes[0].IsArrayType);
Assert.AreEqual("T", td.Templates[1].Bases[0].GenericTypes[0].Type);
Assert.AreEqual(new int[] {0}, td.Templates[1].Bases[0].GenericTypes[0].RankSpecifier);
Assert.AreEqual("IAnotherInterface", td.Templates[1].Bases[1].Type);
}
#endregion #endregion
} }
} }

161
src/Libraries/NRefactory/Test/Parser/Statements/LocalVariableDeclarationTests.cs

@ -24,7 +24,11 @@ namespace ICSharpCode.NRefactory.Tests.AST
public void CSharpLocalVariableDeclarationTest() public void CSharpLocalVariableDeclarationTest()
{ {
LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilCSharp.ParseStatment("int a = 5;", typeof(LocalVariableDeclaration)); LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilCSharp.ParseStatment("int a = 5;", typeof(LocalVariableDeclaration));
// TODO : Extend test. Assert.AreEqual(1, lvd.Variables.Count);
Assert.AreEqual("a", ((VariableDeclaration)lvd.Variables[0]).Name);
TypeReference type = lvd.GetTypeForVariable(0);
Assert.AreEqual("int", type.Type);
// TODO: Check initializer
} }
[Test] [Test]
@ -41,51 +45,192 @@ namespace ICSharpCode.NRefactory.Tests.AST
Assert.AreEqual("G", type.GenericTypes[1].Type); Assert.AreEqual("G", type.GenericTypes[1].Type);
Assert.AreEqual(1, type.GenericTypes[1].GenericTypes.Count); Assert.AreEqual(1, type.GenericTypes[1].GenericTypes.Count);
Assert.AreEqual("Printable", type.GenericTypes[1].GenericTypes[0].Type); Assert.AreEqual("Printable", type.GenericTypes[1].GenericTypes[0].Type);
// TODO: Check initializer
} }
[Test] [Test]
public void CSharpGenericWithArrayLocalVariableDeclarationTest1() public void CSharpGenericWithArrayLocalVariableDeclarationTest1()
{ {
LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilCSharp.ParseStatment("G<int>[] a;", typeof(LocalVariableDeclaration)); LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilCSharp.ParseStatment("G<int>[] a;", typeof(LocalVariableDeclaration));
Assert.AreEqual(1, lvd.Variables.Count);
TypeReference type = lvd.GetTypeForVariable(0);
Assert.AreEqual("G", type.Type);
Assert.AreEqual(1, type.GenericTypes.Count);
Assert.AreEqual("int", type.GenericTypes[0].Type);
Assert.AreEqual(0, type.GenericTypes[0].GenericTypes.Count);
Assert.IsFalse(type.GenericTypes[0].IsArrayType);
Assert.AreEqual(1, type.RankSpecifier.Length);
Assert.AreEqual(0, type.RankSpecifier[0]);
} }
[Test] [Test]
public void CSharpGenericWithArrayLocalVariableDeclarationTest2() public void CSharpGenericWithArrayLocalVariableDeclarationTest2()
{ {
LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilCSharp.ParseStatment("G<int[]> a;", typeof(LocalVariableDeclaration)); LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilCSharp.ParseStatment("G<int[]> a;", typeof(LocalVariableDeclaration));
Assert.AreEqual(1, lvd.Variables.Count);
TypeReference type = lvd.GetTypeForVariable(0);
Assert.AreEqual("G", type.Type);
Assert.AreEqual(1, type.GenericTypes.Count);
Assert.AreEqual("int", type.GenericTypes[0].Type);
Assert.AreEqual(0, type.GenericTypes[0].GenericTypes.Count);
Assert.IsFalse(type.IsArrayType);
Assert.AreEqual(1, type.GenericTypes[0].RankSpecifier.Length);
Assert.AreEqual(0, type.GenericTypes[0].RankSpecifier[0]);
} }
[Test] [Test]
public void CSharpGenericLocalVariableDeclarationTest2() public void CSharpGenericLocalVariableDeclarationTest2()
{ {
LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilCSharp.ParseStatment("G<G<int> > a;", typeof(LocalVariableDeclaration)); LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilCSharp.ParseStatment("G<G<int> > a;", typeof(LocalVariableDeclaration));
Assert.AreEqual(1, lvd.Variables.Count);
TypeReference type = lvd.GetTypeForVariable(0);
Assert.AreEqual("G", type.Type);
Assert.AreEqual(1, type.GenericTypes.Count);
Assert.AreEqual("G", type.GenericTypes[0].Type);
Assert.AreEqual(1, type.GenericTypes[0].GenericTypes.Count);
Assert.AreEqual("int", type.GenericTypes[0].GenericTypes[0].Type);
}
[Test]
public void CSharpGenericLocalVariableDeclarationTest2WithoutSpace()
{
LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilCSharp.ParseStatment("G<G<int>> a;", typeof(LocalVariableDeclaration));
Assert.AreEqual(1, lvd.Variables.Count);
TypeReference type = lvd.GetTypeForVariable(0);
Assert.AreEqual("G", type.Type);
Assert.AreEqual(1, type.GenericTypes.Count);
Assert.AreEqual("G", type.GenericTypes[0].Type);
Assert.AreEqual(1, type.GenericTypes[0].GenericTypes.Count);
Assert.AreEqual("int", type.GenericTypes[0].GenericTypes[0].Type);
} }
[Test] [Test]
public void CSharpGenericLocalVariableDeclarationTest() public void CSharpGenericLocalVariableDeclarationTest()
{ {
LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilCSharp.ParseStatment("G<int> a;", typeof(LocalVariableDeclaration)); LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilCSharp.ParseStatment("G<int> a;", typeof(LocalVariableDeclaration));
Assert.AreEqual(1, lvd.Variables.Count);
TypeReference type = lvd.GetTypeForVariable(0);
Assert.AreEqual("G", type.Type);
Assert.AreEqual(1, type.GenericTypes.Count);
Assert.AreEqual("int", type.GenericTypes[0].Type);
} }
[Test] [Test]
public void CSharpSimpleLocalVariableDeclarationTest() public void CSharpSimpleLocalVariableDeclarationTest()
{ {
LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilCSharp.ParseStatment("MyVar var = new MyVar();", typeof(LocalVariableDeclaration)); LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilCSharp.ParseStatment("MyVar var = new MyVar();", typeof(LocalVariableDeclaration));
Assert.AreEqual(1, lvd.Variables.Count);
Assert.AreEqual("var", ((VariableDeclaration)lvd.Variables[0]).Name);
TypeReference type = lvd.GetTypeForVariable(0);
Assert.AreEqual("MyVar", type.Type);
// TODO: Check initializer
} }
[Test] [Test]
public void CSharpSimpleLocalVariableDeclarationTest1() public void CSharpSimpleLocalVariableDeclarationTest1()
{ {
LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilCSharp.ParseStatment("yield yield = new yield();", typeof(LocalVariableDeclaration)); LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilCSharp.ParseStatment("yield yield = new yield();", typeof(LocalVariableDeclaration));
Assert.AreEqual(1, lvd.Variables.Count);
Assert.AreEqual("yield", ((VariableDeclaration)lvd.Variables[0]).Name);
TypeReference type = lvd.GetTypeForVariable(0);
Assert.AreEqual("yield", type.Type);
// TODO: Check initializer
} }
#endregion #endregion
#region VB.NET #region VB.NET
// TODO [Test]
#endregion public void VBNetLocalVariableDeclarationTest()
{
LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilVBNet.ParseStatment("Dim a As Integer = 5", typeof(LocalVariableDeclaration));
Assert.AreEqual(1, lvd.Variables.Count);
Assert.AreEqual("a", ((VariableDeclaration)lvd.Variables[0]).Name);
TypeReference type = lvd.GetTypeForVariable(0);
Assert.AreEqual("Integer", type.Type);
// TODO: Check initializer
}
[Test]
public void VBNetComplexGenericLocalVariableDeclarationTest()
{
LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilVBNet.ParseStatment("Dim where As Generic(Of Printable, G(Of Printable()))", typeof(LocalVariableDeclaration));
Assert.AreEqual(1, lvd.Variables.Count);
Assert.AreEqual("where", ((VariableDeclaration)lvd.Variables[0]).Name);
TypeReference type = lvd.GetTypeForVariable(0);
Assert.AreEqual("Generic", type.Type);
Assert.AreEqual(2, type.GenericTypes.Count);
Assert.AreEqual("Printable", type.GenericTypes[0].Type);
Assert.AreEqual(0, type.GenericTypes[0].GenericTypes.Count);
Assert.AreEqual("G", type.GenericTypes[1].Type);
Assert.AreEqual(1, type.GenericTypes[1].GenericTypes.Count);
Assert.AreEqual("Printable", type.GenericTypes[1].GenericTypes[0].Type);
}
[Test]
public void VBNetGenericWithArrayLocalVariableDeclarationTest1()
{
LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilVBNet.ParseStatment("Dim a As G(Of Integer)()", typeof(LocalVariableDeclaration));
Assert.AreEqual(1, lvd.Variables.Count);
TypeReference type = lvd.GetTypeForVariable(0);
Assert.AreEqual("G", type.Type);
Assert.AreEqual(1, type.GenericTypes.Count);
Assert.AreEqual("Integer", type.GenericTypes[0].Type);
Assert.AreEqual(0, type.GenericTypes[0].GenericTypes.Count);
Assert.IsFalse(type.GenericTypes[0].IsArrayType);
Assert.AreEqual(1, type.RankSpecifier.Length);
Assert.AreEqual(0, type.RankSpecifier[0]);
}
[Test]
public void VBNetGenericWithArrayLocalVariableDeclarationTest2()
{
LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilVBNet.ParseStatment("Dim a As G(Of Integer())", typeof(LocalVariableDeclaration));
Assert.AreEqual(1, lvd.Variables.Count);
TypeReference type = lvd.GetTypeForVariable(0);
Assert.AreEqual("G", type.Type);
Assert.AreEqual(1, type.GenericTypes.Count);
Assert.AreEqual("Integer", type.GenericTypes[0].Type);
Assert.AreEqual(0, type.GenericTypes[0].GenericTypes.Count);
Assert.IsFalse(type.IsArrayType);
Assert.AreEqual(1, type.GenericTypes[0].RankSpecifier.Length);
Assert.AreEqual(0, type.GenericTypes[0].RankSpecifier[0]);
}
[Test]
public void VBNetGenericLocalVariableDeclarationTest2()
{
LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilVBNet.ParseStatment("Dim a As G(Of G(Of Integer))", typeof(LocalVariableDeclaration));
Assert.AreEqual(1, lvd.Variables.Count);
TypeReference type = lvd.GetTypeForVariable(0);
Assert.AreEqual("G", type.Type);
Assert.AreEqual(1, type.GenericTypes.Count);
Assert.AreEqual("G", type.GenericTypes[0].Type);
Assert.AreEqual(1, type.GenericTypes[0].GenericTypes.Count);
Assert.AreEqual("Integer", type.GenericTypes[0].GenericTypes[0].Type);
}
[Test]
public void VBNetGenericLocalVariableDeclarationTest()
{
LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilVBNet.ParseStatment("Dim a As G(Of Integer)", typeof(LocalVariableDeclaration));
Assert.AreEqual(1, lvd.Variables.Count);
TypeReference type = lvd.GetTypeForVariable(0);
Assert.AreEqual("G", type.Type);
Assert.AreEqual(1, type.GenericTypes.Count);
Assert.AreEqual("Integer", type.GenericTypes[0].Type);
}
[Test]
public void VBNetGenericLocalVariableInitializationTest()
{
LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilVBNet.ParseStatment("Dim a As New G(Of Integer)", typeof(LocalVariableDeclaration));
Assert.AreEqual(1, lvd.Variables.Count);
TypeReference type = lvd.GetTypeForVariable(0);
Assert.AreEqual("G", type.Type);
Assert.AreEqual(1, type.GenericTypes.Count);
Assert.AreEqual("Integer", type.GenericTypes[0].Type);
// TODO: Check initializer
}
#endregion
} }
} }

24
src/Main/Base/Project/Src/Dom/Implementations/DefaultClass.cs

@ -254,10 +254,20 @@ namespace ICSharpCode.SharpDevelop.Dom
return true; return true;
} }
} }
// used to prevent StackOverflowException because SearchType might search for inner classes in the base type
bool blockBaseClassSearch = false;
public IClass GetBaseClass(int index) public IClass GetBaseClass(int index)
{ {
return ProjectContent.SearchType(BaseTypes[index], this, Region != null ? Region.BeginLine : 0, Region != null ? Region.BeginColumn : 0); if (blockBaseClassSearch)
return null;
blockBaseClassSearch = true;
try {
return ProjectContent.SearchType(BaseTypes[index], this, Region != null ? Region.BeginLine : 0, Region != null ? Region.BeginColumn : 0);
} finally {
blockBaseClassSearch = false;
}
} }
public IClass BaseClass { public IClass BaseClass {
@ -273,17 +283,17 @@ namespace ICSharpCode.SharpDevelop.Dom
// no baseType found // no baseType found
switch (ClassType) { switch (ClassType) {
case ClassType.Enum:
return ProjectContent.GetClass("System.Enum");
case ClassType.Class: case ClassType.Class:
if (FullyQualifiedName != "System.Object") { if (FullyQualifiedName != "System.Object") {
return ProjectContent.GetClass("System.Object"); return ReflectionReturnType.Object.GetUnderlyingClass();
} }
break; break;
case ClassType.Enum:
return ProjectContentRegistry.GetMscorlibContent().GetClass("System.Enum");
case ClassType.Delegate: case ClassType.Delegate:
return ProjectContent.GetClass("System.Delegate"); return ProjectContentRegistry.GetMscorlibContent().GetClass("System.Delegate");
case ClassType.Struct: case ClassType.Struct:
return ProjectContent.GetClass("System.ValueType"); return ProjectContentRegistry.GetMscorlibContent().GetClass("System.ValueType");
} }
return null; return null;
} }

12
src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs

@ -119,9 +119,13 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return null; return null;
} }
Expression expr = null; Expression expr = null;
if (expression == "") { if (language == SupportedLanguages.VBNet) {
if ((expr = WithResolve()) == null) { if (expression == "") {
return null; if ((expr = WithResolve()) == null) {
return null;
}
} else if ("global".Equals(expression, StringComparison.InvariantCultureIgnoreCase)) {
return new NamespaceResolveResult(null, null, "");
} }
} }
if (expr == null) { if (expr == null) {
@ -453,7 +457,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return new BaseReferenceExpression(); return new BaseReferenceExpression();
} else if ("myclass".Equals(expression, StringComparison.InvariantCultureIgnoreCase)) { } else if ("myclass".Equals(expression, StringComparison.InvariantCultureIgnoreCase)) {
return new ClassReferenceExpression(); return new ClassReferenceExpression();
} } // Global is handled in Resolve() because we don't need an expression for that
} else if (language == SupportedLanguages.CSharp) { } else if (language == SupportedLanguages.CSharp) {
// generic type names are no expressions, only property access on them is an expression // generic type names are no expressions, only property access on them is an expression
if (expression.EndsWith(">")) { if (expression.EndsWith(">")) {

5
src/Main/Base/Project/Src/Services/ParserService/DefaultProjectContent.cs

@ -392,7 +392,10 @@ namespace ICSharpCode.Core
if (dict.ContainsKey(nameSpace)) { if (dict.ContainsKey(nameSpace)) {
NamespaceStruct ns = dict[nameSpace]; NamespaceStruct ns = dict[nameSpace];
list.AddRange(ns.Classes); list.AddRange(ns.Classes);
list.AddRange(ns.SubNamespaces); foreach (string subns in ns.SubNamespaces) {
if (!list.Contains(subns))
list.Add(subns);
}
} }
} }

Loading…
Cancel
Save