Browse Source

Fixed SD2-398: Add support for nullables to the C# parser.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@331 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 21 years ago
parent
commit
8bc61f3898
  1. 7
      src/Libraries/NRefactory/Project/Src/Output/CSharp/CSharpOutputVisitor.cs
  2. 1988
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/Parser.cs
  3. 30
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/cs.ATG
  4. 48
      src/Libraries/NRefactory/Test/Parser/Statements/LocalVariableDeclarationTests.cs

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

@ -128,18 +128,23 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
} }
if (typeReference.Type == null || typeReference.Type.Length ==0) { if (typeReference.Type == null || typeReference.Type.Length ==0) {
outputFormatter.PrintText("void"); outputFormatter.PrintText("void");
} else if (typeReference.SystemType == "System.Nullable" && typeReference.GenericTypes != null
&& typeReference.GenericTypes.Count == 1)
{
nodeTracker.TrackedVisit(typeReference.GenericTypes[0], data);
outputFormatter.PrintText("?");
} else { } else {
if (typeReference.SystemType.Length > 0) { if (typeReference.SystemType.Length > 0) {
outputFormatter.PrintText(ConvertTypeString(typeReference.SystemType)); outputFormatter.PrintText(ConvertTypeString(typeReference.SystemType));
} else { } else {
outputFormatter.PrintText(typeReference.Type); outputFormatter.PrintText(typeReference.Type);
} }
}
if (typeReference.GenericTypes != null && typeReference.GenericTypes.Count > 0) { if (typeReference.GenericTypes != null && typeReference.GenericTypes.Count > 0) {
outputFormatter.PrintToken(Tokens.LessThan); outputFormatter.PrintToken(Tokens.LessThan);
AppendCommaSeparatedList(typeReference.GenericTypes); AppendCommaSeparatedList(typeReference.GenericTypes);
outputFormatter.PrintToken(Tokens.GreaterThan); outputFormatter.PrintToken(Tokens.GreaterThan);
} }
}
for (int i = 0; i < typeReference.PointerNestingLevel; ++i) { for (int i = 0; i < typeReference.PointerNestingLevel; ++i) {
outputFormatter.PrintToken(Tokens.Times); outputFormatter.PrintToken(Tokens.Times);
} }

1988
src/Libraries/NRefactory/Project/Src/Parser/CSharp/Parser.cs

File diff suppressed because it is too large Load Diff

30
src/Libraries/NRefactory/Project/Src/Parser/CSharp/cs.ATG

@ -263,8 +263,8 @@ bool LBrackAndCommaOrRBrack () {
bool IsDims () { return LBrackAndCommaOrRBrack(); } bool IsDims () { return LBrackAndCommaOrRBrack(); }
/* True, if "[" is followed by "," or "]" * /* True, if "[" is followed by "," or "]" */
* or if the current token is "*" */ /* or if the current token is "*" */
bool TimesOrLBrackAndCommaOrRBrack () { bool TimesOrLBrackAndCommaOrRBrack () {
return la.kind == Tokens.Times || LBrackAndCommaOrRBrack(); return la.kind == Tokens.Times || LBrackAndCommaOrRBrack();
} }
@ -287,12 +287,19 @@ bool SkipGeneric(ref Token pt)
} }
} }
pt = Peek(); pt = Peek();
}
return true; return true;
} }
bool SkipQuestionMark(ref Token pt)
{
if (pt.kind == Tokens.Question) {
pt = Peek();
}
return true; return true;
} }
/* True, if lookahead is a primitive type keyword, or *
* if it is a type declaration followed by an ident */ /* True, if lookahead is a primitive type keyword, or */
/* if it is a type declaration followed by an ident */
bool IsLocalVarDecl () { bool IsLocalVarDecl () {
if (IsYieldStatement()) { if (IsYieldStatement()) {
return false; return false;
@ -305,7 +312,7 @@ bool IsLocalVarDecl () {
Token pt = la ; Token pt = la ;
string ignore; string ignore;
return IsQualident(ref pt, out ignore) && SkipGeneric(ref pt) && IsPointerOrDims(ref pt) && return IsQualident(ref pt, out ignore) && SkipGeneric(ref pt) && SkipQuestionMark(ref pt) && IsPointerOrDims(ref pt) &&
pt.kind == Tokens.Identifier; pt.kind == Tokens.Identifier;
} }
@ -902,6 +909,7 @@ Type<out TypeReference type>
= =
( ClassType<out type> ( ClassType<out type>
| SimpleType<out name> (. type = new TypeReference(name); .) | SimpleType<out name> (. type = new TypeReference(name); .)
[ NullableQuestionMark<ref type> ]
| "void" "*" (. pointer = 1; type = new TypeReference("void"); .) | "void" "*" (. pointer = 1; type = new TypeReference("void"); .)
) (. List<int> r = new List<int>(); .) ) (. List<int> r = new List<int>(); .)
@ -926,6 +934,7 @@ NonArrayType<out TypeReference type>
= =
( ClassType<out type> ( ClassType<out type>
| SimpleType<out name> (. type = new TypeReference(name); .) | SimpleType<out name> (. type = new TypeReference(name); .)
[ NullableQuestionMark<ref type> ]
| "void" "*" (. pointer = 1; type = new TypeReference("void"); .) | "void" "*" (. pointer = 1; type = new TypeReference("void"); .)
) )
@ -2244,6 +2253,17 @@ TypeName<out TypeReference typeRef>
typeRef = new TypeReference(alias + "." + qualident, typeArguments); typeRef = new TypeReference(alias + "." + qualident, typeArguments);
} }
.) .)
[ NullableQuestionMark<ref typeRef> ]
.
NullableQuestionMark<ref TypeReference typeRef>
(. List<TypeReference> typeArguments = new List<TypeReference>(1); .)
=
"?"
(.
if (typeRef != null) typeArguments.Add(typeRef);
typeRef = new TypeReference("System.Nullable", typeArguments);
.)
. .
TypeArgumentList<out List<TypeReference> types> TypeArgumentList<out List<TypeReference> types>

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

@ -113,6 +113,7 @@ namespace ICSharpCode.NRefactory.Tests.AST
Assert.AreEqual(1, type.GenericTypes.Count); Assert.AreEqual(1, type.GenericTypes.Count);
Assert.AreEqual("int", type.GenericTypes[0].Type); Assert.AreEqual("int", type.GenericTypes[0].Type);
} }
[Test] [Test]
public void CSharpSimpleLocalVariableDeclarationTest() public void CSharpSimpleLocalVariableDeclarationTest()
{ {
@ -123,6 +124,7 @@ namespace ICSharpCode.NRefactory.Tests.AST
Assert.AreEqual("MyVar", type.Type); Assert.AreEqual("MyVar", type.Type);
// TODO: Check initializer // TODO: Check initializer
} }
[Test] [Test]
public void CSharpSimpleLocalVariableDeclarationTest1() public void CSharpSimpleLocalVariableDeclarationTest1()
{ {
@ -134,6 +136,52 @@ namespace ICSharpCode.NRefactory.Tests.AST
// TODO: Check initializer // TODO: Check initializer
} }
[Test]
public void CSharpNullableLocalVariableDeclarationTest1()
{
LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilCSharp.ParseStatment("int? a;", typeof(LocalVariableDeclaration));
Assert.AreEqual(1, lvd.Variables.Count);
Assert.AreEqual("a", ((VariableDeclaration)lvd.Variables[0]).Name);
TypeReference type = lvd.GetTypeForVariable(0);
Assert.AreEqual("System.Nullable", type.SystemType);
Assert.AreEqual("System.Int32", type.GenericTypes[0].SystemType);
}
[Test]
public void CSharpNullableLocalVariableDeclarationTest2()
{
LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilCSharp.ParseStatment("DateTime? a;", typeof(LocalVariableDeclaration));
Assert.AreEqual(1, lvd.Variables.Count);
Assert.AreEqual("a", ((VariableDeclaration)lvd.Variables[0]).Name);
TypeReference type = lvd.GetTypeForVariable(0);
Assert.AreEqual("System.Nullable", type.SystemType);
Assert.AreEqual("DateTime", type.GenericTypes[0].Type);
}
[Test]
public void CSharpNullableLocalVariableDeclarationTest3()
{
LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilCSharp.ParseStatment("DateTime?[] a;", typeof(LocalVariableDeclaration));
Assert.AreEqual(1, lvd.Variables.Count);
Assert.AreEqual("a", ((VariableDeclaration)lvd.Variables[0]).Name);
TypeReference type = lvd.GetTypeForVariable(0);
Assert.IsTrue(type.IsArrayType);
Assert.AreEqual("System.Nullable", type.SystemType);
Assert.AreEqual("DateTime", type.GenericTypes[0].Type);
}
[Test]
public void CSharpNullableLocalVariableDeclarationTest4()
{
LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilCSharp.ParseStatment("SomeStruct<int?>? a;", typeof(LocalVariableDeclaration));
Assert.AreEqual(1, lvd.Variables.Count);
Assert.AreEqual("a", ((VariableDeclaration)lvd.Variables[0]).Name);
TypeReference type = lvd.GetTypeForVariable(0);
Assert.AreEqual("System.Nullable", type.SystemType);
Assert.AreEqual("SomeStruct", type.GenericTypes[0].Type);
Assert.AreEqual("System.Nullable", type.GenericTypes[0].GenericTypes[0].SystemType);
Assert.AreEqual("System.Int32", type.GenericTypes[0].GenericTypes[0].GenericTypes[0].SystemType);
}
#endregion #endregion
#region VB.NET #region VB.NET

Loading…
Cancel
Save