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 @@ @@ -186,7 +186,7 @@
<xsd:element name="End" minOccurs="0" type="End" />
</xsd:sequence>
<!-- 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. -->
<xsd:attribute name="rule" type="xsd:string" />
<!-- 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 @@ -63,7 +63,7 @@ namespace ICSharpCode.TextEditor.Document
}
public HighlightColor BeginColor {
get {
get {
if(beginColor != null) {
return beginColor;
} else {
@ -112,16 +112,19 @@ namespace ICSharpCode.TextEditor.Document @@ -112,16 +112,19 @@ namespace ICSharpCode.TextEditor.Document
{
color = new HighlightColor(span);
if (span.Attributes["rule"] != null) {
rule = span.Attributes["rule"].InnerText;
if (span.HasAttribute("rule")) {
rule = span.GetAttribute("rule");
}
if (span.HasAttribute("noescapesequences")) {
noEscapeSequences = Boolean.Parse(span.GetAttribute("noescapesequences"));
}
if (span.Attributes["noescapesequences"] != null) {
noEscapeSequences = Boolean.Parse(span.Attributes["noescapesequences"].InnerText);
name = span.GetAttribute("name");
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();
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) @@ -82,11 +82,7 @@ bool IsTypeKWForTypeCast(ref Token pt)
{
if (Tokens.TypeKW[pt.kind]) {
pt = lexer.Peek();
if (pt.kind == Tokens.Times || pt.kind == Tokens.OpenSquareBracket) {
return IsPointerOrDims(ref pt);
} else {
return true;
}
return IsPointerOrDims(ref pt) && SkipQuestionMark(ref pt);
} else if (pt.kind == Tokens.Void) {
pt = lexer.Peek();
return IsPointerOrDims(ref pt);
@ -103,7 +99,7 @@ bool IsTypeNameOrKWForTypeCast(ref Token pt) @@ -103,7 +99,7 @@ bool IsTypeNameOrKWForTypeCast(ref Token pt)
return IsTypeNameForTypeCast(ref pt);
}
// TypeName = ident [ "::" ident ] { "." ident } ["<" TypeNameOrKW { "," TypeNameOrKW } ">" ] PointerOrDims
// TypeName = ident [ "::" ident ] { ["<" TypeNameOrKW { "," TypeNameOrKW } ">" ] "." ident } ["?"] PointerOrDims
/* !!! Proceeds from current peek position !!! */
bool IsTypeNameForTypeCast(ref Token pt)
{
@ -120,26 +116,29 @@ bool IsTypeNameForTypeCast(ref Token pt) @@ -120,26 +116,29 @@ bool IsTypeNameForTypeCast(ref Token pt)
}
pt = Peek();
}
// { "." ident }
while (pt.kind == Tokens.Dot) {
pt = Peek();
if (pt.kind != Tokens.Identifier) {
return false;
}
pt = Peek();
}
if (pt.kind == Tokens.LessThan) {
do {
pt = Peek();
if (!IsTypeNameOrKWForTypeCast(ref pt)) {
// { ["<" TypeNameOrKW { "," TypeNameOrKW } ">" ] "." ident }
while (true) {
if (pt.kind == Tokens.LessThan) {
do {
pt = Peek();
if (!IsTypeNameOrKWForTypeCast(ref pt)) {
return false;
}
} while (pt.kind == Tokens.Comma);
if (pt.kind != Tokens.GreaterThan) {
return false;
}
} while (pt.kind == Tokens.Comma);
if (pt.kind != Tokens.GreaterThan) {
pt = Peek();
}
if (pt.kind != Tokens.Dot)
break;
pt = Peek();
if (pt.kind != Tokens.Identifier) {
return false;
}
pt = Peek();
}
// ["?"]
if (pt.kind == Tokens.Question) {
pt = Peek();
}
@ -328,21 +327,11 @@ bool IsPointer () { return la.kind == Tokens.Times; } @@ -328,21 +327,11 @@ bool IsPointer () { return la.kind == Tokens.Times; }
bool SkipGeneric(ref Token pt)
{
if (pt.kind == Tokens.LessThan) {
int braces = 1;
while (braces != 0) {
do {
pt = Peek();
if (pt.kind == Tokens.GreaterThan) {
--braces;
} else if (pt.kind == Tokens.LessThan) {
++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;
}
}
if (!IsTypeNameOrKWForTypeCast(ref pt)) return false;
} while (pt.kind == Tokens.Comma);
if (pt.kind != Tokens.GreaterThan) return false;
pt = Peek();
}
return true;
@ -366,16 +355,8 @@ bool IsLocalVarDecl () { @@ -366,16 +355,8 @@ bool IsLocalVarDecl () {
}
StartPeek();
Token pt = la ;
string ignore;
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;
Token pt = la;
return IsTypeNameOrKWForTypeCast(ref pt) && pt.kind == Tokens.Identifier;
}
/* 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 @@ -32,13 +32,13 @@ namespace ICSharpCode.NRefactory.Tests.AST
[Test]
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("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("Namespace.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);

Loading…
Cancel
Save