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

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

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

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

@ -188,9 +188,10 @@ @@ -188,9 +188,10 @@
<Compile Include="Src\Parser\Visitors\CSharpToVBNetConvertVisitor.cs" />
<Compile Include="Src\Parser\Visitors\PrefixFieldsVisitor.cs" />
<Compile Include="Src\Parser\Visitors\VBNetToCSharpConvertVisitor.cs" />
<Compile Include="Src\Parser\AST\General\Expressions\GlobalReferenceExpression.cs" />
</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\Parser\CSharp\trace.txt" />
<Content Include="Src\Parser\Frames\OldSharpCoco.exe" />

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

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
#!/bin/perl
# File names
$keyword_file = "CSharpKeywordList.txt";
$keyword_file = "KeywordList.txt";
$keywords_outfile = "Keywords.cs";
$tokens_outfile = "Tokens.cs";
$unittests_outfile = "LexerTests.cs";
@ -19,10 +19,10 @@ print "done.\n"; @@ -19,10 +19,10 @@ print "done.\n";
print "starting analysation ... this could take a few minutes.\n";
foreach (@raw_data) {
if ($_=~/^\s*\$(\w+)\s*=\s*(\S+)$/) {
if ($_=~/^\s*\$(\w+)\s*=\s*(\S+)\s*$/) {
#properties form: $PROPERTY = "VALUE"
$properties{$1} = $2;
} elsif ($_=~/^\s*(\w+)\s*=\s*(\S+)$/) {
} elsif ($_=~/^\s*(\w+)\s*=\s*(\S+)\s*$/) {
#special characters form: name = "VALUE"
$specialCharLookup{$2} = $1;
$special_chars[$#special_chars + 1] = $1;
@ -40,7 +40,11 @@ foreach (@raw_data) { @@ -40,7 +40,11 @@ foreach (@raw_data) {
} elsif ($_=~/^\s*(\w+)\s*$/) {
#special terminal classes form: name
$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 @@ -159,6 +159,8 @@ namespace ICSharpCode.NRefactory.Parser.VB
"UINTEGER",
"ULONG",
"USHORT",
"GLOBAL",
"TRYCAST",
"OF",
"NARROWING",
"WIDENING",

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

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

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

@ -205,12 +205,14 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -205,12 +205,14 @@ namespace ICSharpCode.NRefactory.Parser.VB
public const int UInteger = 191;
public const int ULong = 192;
public const int UShort = 193;
public const int Of = 194;
public const int Narrowing = 195;
public const int Widening = 196;
public const int Partial = 197;
public const int Global = 194;
public const int TryCast = 195;
public const int Of = 196;
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)
{
BitArray bitArray = new BitArray(maxToken);
@ -420,6 +422,8 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -420,6 +422,8 @@ namespace ICSharpCode.NRefactory.Parser.VB
"UInteger",
"ULong",
"UShort",
"Global",
"TryCast",
"Of",
"Narrowing",
"Widening",

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

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

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

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

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

@ -1737,13 +1737,9 @@ namespace ICSharpCode.NRefactory.PrettyPrinter @@ -1737,13 +1737,9 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
break;
case BinaryOperatorType.AsCast:
outputFormatter.PrintIdentifier("CType(Microsoft.VisualBasic.IIf(TypeOf ");
outputFormatter.PrintIdentifier("TryCast(");
nodeTracker.TrackedVisit(binaryOperatorExpression.Left, data);
outputFormatter.PrintIdentifier(" Is ");
nodeTracker.TrackedVisit(binaryOperatorExpression.Right, data);
outputFormatter.PrintIdentifier(", ");
nodeTracker.TrackedVisit(binaryOperatorExpression.Left, data);
outputFormatter.PrintIdentifier(", Nothing), ");
nodeTracker.TrackedVisit(binaryOperatorExpression.Right, data);
outputFormatter.PrintIdentifier(")");
return null;
@ -2103,6 +2099,13 @@ namespace ICSharpCode.NRefactory.PrettyPrinter @@ -2103,6 +2099,13 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
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)
{
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 @@ -59,7 +59,7 @@ namespace ICSharpCode.NRefactory.Parser.AST
ReferenceInequality,
/// <summary>C#: Is</summary>
TypeCheck,
/// <summary>C#: as-cast</summary>
/// <summary>'as' in C#, 'TryCast(l, r)' in VB</summary>
AsCast,
/// <summary>VB-only: Like</summary>
Like,

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

@ -0,0 +1,18 @@ @@ -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 @@ -137,6 +137,8 @@ namespace ICSharpCode.NRefactory.Parser.AST
public TemplateDefinition(string name, ArrayList attributes) : base(attributes)
{
if (name == null || name.Length == 0)
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 @@ -411,12 +411,14 @@ TOKENS
"UInteger"
"ULong"
"UShort"
"Global"
"TryCast"
"Of"
"Narrowing"
"Widening"
"Partial"
/* END AUTOGENERATED TOKENS SECTION */
PRODUCTIONS
VBNET
@ -536,6 +538,50 @@ NamespaceMemberDecl @@ -536,6 +538,50 @@ NamespaceMemberDecl
{ 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 */
NonModuleDeclaration<Modifiers m,ArrayList attributes>
(.
@ -554,6 +600,7 @@ NonModuleDeclaration<Modifiers m,ArrayList attributes> @@ -554,6 +600,7 @@ NonModuleDeclaration<Modifiers m,ArrayList attributes>
newType.Type = Types.Class;
.)
Identifier (. newType.Name = t.val; newType.StartLocation = t.EndLocation; .)
[ TypeParameterList<newType.Templates> ]
EndOfStmt
[ ClassBaseType<out name> (. newType.BaseTypes.Add(name); .) ]
{ TypeImplementsClause<out names> (. newType.BaseTypes.AddRange(names); .) }
@ -587,6 +634,7 @@ NonModuleDeclaration<Modifiers m,ArrayList attributes> @@ -587,6 +634,7 @@ NonModuleDeclaration<Modifiers m,ArrayList attributes>
newType.Type = Types.Struct; ArrayList baseInterfaces = new ArrayList();
.)
Identifier (. newType.Name = t.val; newType.StartLocation = t.EndLocation; .)
[ TypeParameterList<newType.Templates> ]
EOL { TypeImplementsClause<out baseInterfaces> (. newType.BaseTypes.AddRange(baseInterfaces);.) }
StructureBody<newType>
(.
@ -622,6 +670,7 @@ NonModuleDeclaration<Modifiers m,ArrayList attributes> @@ -622,6 +670,7 @@ NonModuleDeclaration<Modifiers m,ArrayList attributes>
newType.Type = Types.Interface;ArrayList baseInterfaces;
.)
Identifier (. newType.Name = t.val; newType.StartLocation = t.EndLocation; .)
[ TypeParameterList<newType.Templates> ]
EndOfStmt { InterfaceBase<out baseInterfaces> (. newType.BaseTypes.AddRange(baseInterfaces.ToArray()); .) }
InterfaceBody<newType>
(.
@ -1423,10 +1472,12 @@ SimpleExpr<out Expression pexpr> @@ -1423,10 +1472,12 @@ SimpleExpr<out Expression pexpr>
| (. Expression retExpr = null; .)
( "MyBase" (. retExpr = new BaseReferenceExpression(); .)
| "MyClass" (. retExpr = new ClassReferenceExpression(); .)
| "Global" (. retExpr = new GlobalReferenceExpression(); .)
)
"." IdentifierOrKeyword<out name> (. pexpr = new FieldReferenceExpression(retExpr, name); .)
| ObjectCreateExpression<out expr> (. pexpr = 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.4.5 */ "AddressOf" Expr<out expr> (. pexpr = new AddressOfExpression(expr); .)
| /* 11.5.1 */ "GetType" "(" TypeName<out type> ")" (. pexpr = new TypeOfExpression(type); .)
@ -1604,12 +1655,13 @@ MultiplicativeExpr<out Expression outExpr> @@ -1604,12 +1655,13 @@ MultiplicativeExpr<out Expression outExpr>
.
ObjectCreateExpression<out Expression oce>
(.
TypeReference type = null;
Expression initializer = null;ArrayList arguments = null;
oce = null;
.) =
"New" TypeNameWithoutRank<out type>
(.
TypeReference type = null;
Expression initializer = null;
ArrayList arguments = null;
oce = null;
.) =
"New" NonArrayTypeName<out type>
["(" [ ArgumentList<out arguments> ] ")" ]
[ ArrayInitializer<out initializer> ]
(.
@ -1621,7 +1673,7 @@ ObjectCreateExpression<out Expression oce> @@ -1621,7 +1673,7 @@ ObjectCreateExpression<out Expression oce>
oce = ace;
}
.)
.
.
/* 9.3.2 */
ArgumentList<out ArrayList arguments>
@ -1653,54 +1705,48 @@ Argument<out Expression argumentexpr> @@ -1653,54 +1705,48 @@ Argument<out Expression 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. */
TypeName<out TypeReference typeref>
(. ArrayList rank = null; typeref = null; .)
=
(. ArrayList rank = null; typeref = null; .)
=
NonArrayTypeName<out typeref>
ArrayTypeModifiers<out rank>
(.
if (rank != null) {
typeref = new TypeReference(typeref == null ? "UNKNOWN" : typeref.Type, (int[])rank.ToArray(typeof(int)));
if (rank != null && typeref != null) {
typeref.RankSpecifier = (int[])rank.ToArray(typeof(int));
}
.)
.
.
/* 7.1 */
NonArrayTypeName<out TypeReference typeref>
(.
string name;
typeref = null;
.) =
(.
string name;
typeref = null;
.) =
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"); .)
| PrimitiveTypeName<out name> (. typeref = new TypeReference(name); .)
.
.
/* 7.9 */
ArrayNameModifier<out ArrayList arrayModifiers>
(.
arrayModifiers = null;
.) =
(.
arrayModifiers = null;
.) =
ArrayTypeModifiers<out arrayModifiers>
.
.
/* 7.9 */
ArrayTypeModifiers<out ArrayList arrayModifiers>
(.
arrayModifiers = new ArrayList();
int i = 0;
.) =
(.
arrayModifiers = new ArrayList();
int i = 0;
.) =
{ IF (IsDims())
"("
[ RankList<out i>]
@ -1714,13 +1760,25 @@ ArrayTypeModifiers<out ArrayList arrayModifiers> @@ -1714,13 +1760,25 @@ ArrayTypeModifiers<out ArrayList arrayModifiers>
arrayModifiers = null;
}
.)
.
.
/* 7.9 */
RankList<out int i>
(. i = 0; .) =
(. i = 0; .) =
{ "," (. ++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 =
(. Point startPos = t.Location; .)
@ -2197,7 +2255,7 @@ EmbeddedStatement<out Statement statement> @@ -2197,7 +2255,7 @@ EmbeddedStatement<out Statement statement>
(.
// a field reference expression that stands alone is a
// invocation expression without parantheses and arguments
if(expr is FieldReferenceExpression) {
if(expr is FieldReferenceExpression || expr is IdentifierExpression) {
expr = new InvocationExpression(expr);
}
statement = new StatementExpression(expr);

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

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

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

@ -110,6 +110,7 @@ namespace ICSharpCode.NRefactory.Parser @@ -110,6 +110,7 @@ namespace ICSharpCode.NRefactory.Parser
object Visit(IndexerExpression indexerExpression, object data);
object Visit(ThisReferenceExpression thisReferenceExpression, object data);
object Visit(BaseReferenceExpression baseReferenceExpression, object data);
object Visit(GlobalReferenceExpression globalReferenceExpression, object data);
object Visit(ObjectCreateExpression objectCreateExpression, object data);
object Visit(ArrayCreateExpression arrayCreateExpression, 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 @@ -29,7 +29,8 @@ copy ..\VBNet\VBNET.ATG
OldSharpCoco -trace GIPXA -namespace ICSharpCode.NRefactory.Parser.VB VBNET.ATG
move Parser.cs ..\VBNet
del cs.ATG VBNET.ATG >NUL
del cs.ATG
del VBNET.ATG
:exit
pause

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

@ -1095,5 +1095,89 @@ namespace ICSharpCode.NRefactory.Tests.Lexer.VB @@ -1095,5 +1095,89 @@ namespace ICSharpCode.NRefactory.Tests.Lexer.VB
ILexer lexer = GenerateLexer(new StringReader("Xor"));
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 @@ -75,12 +75,68 @@ namespace ICSharpCode.NRefactory.Tests.Lexer.VB
CheckToken("\"\"\"\"c", Tokens.LiteralCharacter, '"');
}
/*
* TODO : Test the following:
public const int LiteralDouble = 6;
public const int LiteralSingle = 7;
public const int LiteralDecimal = 8;
public const int LiteralDate = 9;
*/
[Test]
public void TestDateLiterals()
{
CheckToken("# 8/23/1970 #", Tokens.LiteralDate, new DateTime(1970, 8, 23, 0, 0, 0));
CheckToken("#8/23/1970#", Tokens.LiteralDate, new DateTime(1970, 8, 23, 0, 0, 0));
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 @@ -175,6 +175,18 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2
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]
public void VBNetSimpleClassTypeDeclarationWithoutLastNewLineTest()
{
@ -199,6 +211,73 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2 @@ -199,6 +211,73 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2
Assert.AreEqual(Types.Class, td.Type);
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
}
}

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

@ -24,7 +24,11 @@ namespace ICSharpCode.NRefactory.Tests.AST @@ -24,7 +24,11 @@ namespace ICSharpCode.NRefactory.Tests.AST
public void CSharpLocalVariableDeclarationTest()
{
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]
@ -41,51 +45,192 @@ namespace ICSharpCode.NRefactory.Tests.AST @@ -41,51 +45,192 @@ namespace ICSharpCode.NRefactory.Tests.AST
Assert.AreEqual("G", type.GenericTypes[1].Type);
Assert.AreEqual(1, type.GenericTypes[1].GenericTypes.Count);
Assert.AreEqual("Printable", type.GenericTypes[1].GenericTypes[0].Type);
// TODO: Check initializer
}
[Test]
public void CSharpGenericWithArrayLocalVariableDeclarationTest1()
{
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]
public void CSharpGenericWithArrayLocalVariableDeclarationTest2()
{
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]
public void CSharpGenericLocalVariableDeclarationTest2()
{
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]
public void CSharpGenericLocalVariableDeclarationTest()
{
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]
public void CSharpSimpleLocalVariableDeclarationTest()
{
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]
public void CSharpSimpleLocalVariableDeclarationTest1()
{
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
#region VB.NET
// TODO
#endregion
[Test]
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 @@ -254,10 +254,20 @@ namespace ICSharpCode.SharpDevelop.Dom
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)
{
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 {
@ -273,17 +283,17 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -273,17 +283,17 @@ namespace ICSharpCode.SharpDevelop.Dom
// no baseType found
switch (ClassType) {
case ClassType.Enum:
return ProjectContent.GetClass("System.Enum");
case ClassType.Class:
if (FullyQualifiedName != "System.Object") {
return ProjectContent.GetClass("System.Object");
return ReflectionReturnType.Object.GetUnderlyingClass();
}
break;
case ClassType.Enum:
return ProjectContentRegistry.GetMscorlibContent().GetClass("System.Enum");
case ClassType.Delegate:
return ProjectContent.GetClass("System.Delegate");
return ProjectContentRegistry.GetMscorlibContent().GetClass("System.Delegate");
case ClassType.Struct:
return ProjectContent.GetClass("System.ValueType");
return ProjectContentRegistry.GetMscorlibContent().GetClass("System.ValueType");
}
return null;
}

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

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

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

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

Loading…
Cancel
Save