Browse Source

Fixed forum-8128: C# parser bug when type parameter is a fully qualified name.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/2.0@1437 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 19 years ago
parent
commit
30d6d5f7fa
  1. 2
      src/Libraries/ICSharpCode.TextEditor/Project/Resources/Mode.xsd
  2. 17
      src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/Span.cs
  3. 2133
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/Parser.cs
  4. 69
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/cs.ATG
  5. 4
      src/Libraries/NRefactory/Test/Parser/Statements/LocalVariableDeclarationTests.cs

2
src/Libraries/ICSharpCode.TextEditor/Project/Resources/Mode.xsd

@ -186,7 +186,7 @@
<xsd:element name="End" minOccurs="0" type="End" /> <xsd:element name="End" minOccurs="0" type="End" />
</xsd:sequence> </xsd:sequence>
<!-- The name of the span definition --> <!-- The name of the span definition -->
<xsd:attribute name="name" type="xsd:string" /> <xsd:attribute name="name" type="xsd:string" use="required" />
<!-- Defines the rule set that is applicable in the Span. May be omitted. --> <!-- Defines the rule set that is applicable in the Span. May be omitted. -->
<xsd:attribute name="rule" type="xsd:string" /> <xsd:attribute name="rule" type="xsd:string" />
<!-- Defines wether the Span should terminate automatically at the end of line. Typical examples <!-- Defines wether the Span should terminate automatically at the end of line. Typical examples

17
src/Libraries/ICSharpCode.TextEditor/Project/Src/Document/HighlightingStrategy/Span.cs

@ -63,7 +63,7 @@ namespace ICSharpCode.TextEditor.Document
} }
public HighlightColor BeginColor { public HighlightColor BeginColor {
get { get {
if(beginColor != null) { if(beginColor != null) {
return beginColor; return beginColor;
} else { } else {
@ -112,16 +112,19 @@ namespace ICSharpCode.TextEditor.Document
{ {
color = new HighlightColor(span); color = new HighlightColor(span);
if (span.Attributes["rule"] != null) { if (span.HasAttribute("rule")) {
rule = span.Attributes["rule"].InnerText; rule = span.GetAttribute("rule");
}
if (span.HasAttribute("noescapesequences")) {
noEscapeSequences = Boolean.Parse(span.GetAttribute("noescapesequences"));
} }
if (span.Attributes["noescapesequences"] != null) { name = span.GetAttribute("name");
noEscapeSequences = Boolean.Parse(span.Attributes["noescapesequences"].InnerText); if (span.HasAttribute("stopateol")) {
stopEOL = Boolean.Parse(span.GetAttribute("stopateol"));
} }
name = span.Attributes["name"].InnerText;
stopEOL = Boolean.Parse(span.Attributes["stopateol"].InnerText);
begin = span["Begin"].InnerText.ToCharArray(); begin = span["Begin"].InnerText.ToCharArray();
beginColor = new HighlightColor(span["Begin"], color); beginColor = new HighlightColor(span["Begin"], color);

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

File diff suppressed because it is too large Load Diff

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

@ -82,11 +82,7 @@ bool IsTypeKWForTypeCast(ref Token pt)
{ {
if (Tokens.TypeKW[pt.kind]) { if (Tokens.TypeKW[pt.kind]) {
pt = lexer.Peek(); pt = lexer.Peek();
if (pt.kind == Tokens.Times || pt.kind == Tokens.OpenSquareBracket) { return IsPointerOrDims(ref pt) && SkipQuestionMark(ref pt);
return IsPointerOrDims(ref pt);
} else {
return true;
}
} else if (pt.kind == Tokens.Void) { } else if (pt.kind == Tokens.Void) {
pt = lexer.Peek(); pt = lexer.Peek();
return IsPointerOrDims(ref pt); return IsPointerOrDims(ref pt);
@ -103,7 +99,7 @@ bool IsTypeNameOrKWForTypeCast(ref Token pt)
return IsTypeNameForTypeCast(ref pt); return IsTypeNameForTypeCast(ref pt);
} }
// TypeName = ident [ "::" ident ] { "." ident } ["<" TypeNameOrKW { "," TypeNameOrKW } ">" ] PointerOrDims // TypeName = ident [ "::" ident ] { ["<" TypeNameOrKW { "," TypeNameOrKW } ">" ] "." ident } ["?"] PointerOrDims
/* !!! Proceeds from current peek position !!! */ /* !!! Proceeds from current peek position !!! */
bool IsTypeNameForTypeCast(ref Token pt) bool IsTypeNameForTypeCast(ref Token pt)
{ {
@ -120,26 +116,29 @@ bool IsTypeNameForTypeCast(ref Token pt)
} }
pt = Peek(); pt = Peek();
} }
// { "." ident } // { ["<" TypeNameOrKW { "," TypeNameOrKW } ">" ] "." ident }
while (pt.kind == Tokens.Dot) { while (true) {
pt = Peek(); if (pt.kind == Tokens.LessThan) {
if (pt.kind != Tokens.Identifier) { do {
return false; pt = Peek();
} if (!IsTypeNameOrKWForTypeCast(ref pt)) {
pt = Peek(); return false;
} }
if (pt.kind == Tokens.LessThan) { } while (pt.kind == Tokens.Comma);
do { if (pt.kind != Tokens.GreaterThan) {
pt = Peek();
if (!IsTypeNameOrKWForTypeCast(ref pt)) {
return false; return false;
} }
} while (pt.kind == Tokens.Comma); pt = Peek();
if (pt.kind != Tokens.GreaterThan) { }
if (pt.kind != Tokens.Dot)
break;
pt = Peek();
if (pt.kind != Tokens.Identifier) {
return false; return false;
} }
pt = Peek(); pt = Peek();
} }
// ["?"]
if (pt.kind == Tokens.Question) { if (pt.kind == Tokens.Question) {
pt = Peek(); pt = Peek();
} }
@ -328,21 +327,11 @@ bool IsPointer () { return la.kind == Tokens.Times; }
bool SkipGeneric(ref Token pt) bool SkipGeneric(ref Token pt)
{ {
if (pt.kind == Tokens.LessThan) { if (pt.kind == Tokens.LessThan) {
int braces = 1; do {
while (braces != 0) {
pt = Peek(); pt = Peek();
if (pt.kind == Tokens.GreaterThan) { if (!IsTypeNameOrKWForTypeCast(ref pt)) return false;
--braces; } while (pt.kind == Tokens.Comma);
} else if (pt.kind == Tokens.LessThan) { if (pt.kind != Tokens.GreaterThan) return false;
++braces;
} else if (pt.kind != Tokens.Identifier && pt.kind != Tokens.Comma
&& pt.kind != Tokens.OpenSquareBracket && pt.kind != Tokens.CloseSquareBracket
&& pt.kind != Tokens.Question
&& !Tokens.TypeKW[pt.kind])
{
return false;
}
}
pt = Peek(); pt = Peek();
} }
return true; return true;
@ -366,16 +355,8 @@ bool IsLocalVarDecl () {
} }
StartPeek(); StartPeek();
Token pt = la ; Token pt = la;
string ignore; return IsTypeNameOrKWForTypeCast(ref pt) && pt.kind == Tokens.Identifier;
if (!IsQualident(ref pt, out ignore)) return false;
if (!SkipGeneric(ref pt)) return false;
while (pt.kind == Tokens.Dot) {
pt = Peek();
if (!IsQualident(ref pt, out ignore)) return false;
if (!SkipGeneric(ref pt)) return false;
}
return SkipQuestionMark(ref pt) && IsPointerOrDims(ref pt) && pt.kind == Tokens.Identifier;
} }
/* True if lookahead is type parameters (<...>) followed by the specified token */ /* True if lookahead is type parameters (<...>) followed by the specified token */

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

@ -32,13 +32,13 @@ namespace ICSharpCode.NRefactory.Tests.AST
[Test] [Test]
public void CSharpComplexGenericLocalVariableDeclarationTest() public void CSharpComplexGenericLocalVariableDeclarationTest()
{ {
LocalVariableDeclaration lvd = ParseUtilCSharp.ParseStatement<LocalVariableDeclaration>("Generic<Printable, G<Printable[]> > where = new Generic<Printable, G<Printable[]>>();"); LocalVariableDeclaration lvd = ParseUtilCSharp.ParseStatement<LocalVariableDeclaration>("Generic<Namespace.Printable, G<Printable[]> > where = new Generic<Namespace.Printable, G<Printable[]>>();");
Assert.AreEqual(1, lvd.Variables.Count); Assert.AreEqual(1, lvd.Variables.Count);
Assert.AreEqual("where", ((VariableDeclaration)lvd.Variables[0]).Name); Assert.AreEqual("where", ((VariableDeclaration)lvd.Variables[0]).Name);
TypeReference type = lvd.GetTypeForVariable(0); TypeReference type = lvd.GetTypeForVariable(0);
Assert.AreEqual("Generic", type.Type); Assert.AreEqual("Generic", type.Type);
Assert.AreEqual(2, type.GenericTypes.Count); Assert.AreEqual(2, type.GenericTypes.Count);
Assert.AreEqual("Printable", type.GenericTypes[0].Type); Assert.AreEqual("Namespace.Printable", type.GenericTypes[0].Type);
Assert.AreEqual(0, type.GenericTypes[0].GenericTypes.Count); Assert.AreEqual(0, type.GenericTypes[0].GenericTypes.Count);
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);

Loading…
Cancel
Save