Browse Source

Fixed C# parser (added support for generic methods inside interfaces).

Changed CurrentLineBookmark to be invisible in BookmarkPad and not saved.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@245 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 20 years ago
parent
commit
39e4a95f2d
  1. 1642
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/Parser.cs
  2. 32
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/cs.ATG
  3. 40
      src/Libraries/NRefactory/Test/Parser/TypeLevel/MethodDeclarationTests.cs
  4. 82
      src/Main/Base/Project/Src/Dom/ExpressionContext.cs
  5. 2
      src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs
  6. 3
      src/Main/Base/Project/Src/Services/Debugger/CurrentLineBookmark.cs
  7. 42
      src/Main/Base/Project/Src/TextEditor/Bookmarks/Bookmark.cs
  8. 2
      src/Main/Base/Project/Src/TextEditor/Bookmarks/BookmarkManager.cs
  9. 2
      src/Main/Base/Project/Src/TextEditor/Bookmarks/Pad/BookmarkPad.cs
  10. 4
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/InsightWindow/MethodInsightDataProvider.cs

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

File diff suppressed because it is too large Load Diff

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

@ -906,8 +906,10 @@ Type<out TypeReference type>
| "[" { "," (. ++i; .) } "]" (. r.Add(i); .) | "[" { "," (. ++i; .) } "]" (. r.Add(i); .)
) )
} }
(. type.RankSpecifier = r.ToArray(); (. if (type != null) {
type.PointerNestingLevel = pointer; type.RankSpecifier = r.ToArray();
type.PointerNestingLevel = pointer;
}
.) .)
. .
@ -1303,11 +1305,16 @@ InterfaceMemberDecl
( (
/*--- interface void method (procedure) declaration: */ /*--- interface void method (procedure) declaration: */
IF (NotVoidPointer()) "void" (. if (startLocation.X == -1) startLocation = t.Location; .) ident (. name = t.val; .) IF (NotVoidPointer()) "void" (. if (startLocation.X == -1) startLocation = t.Location; .) ident (. name = t.val; .)
"(" [ FormalParameterList<parameters> ] ")" ";" (. MethodDeclaration md = new MethodDeclaration(name, mod, new TypeReference("void"), parameters, attributes); [ TypeParameterList<templates> ]
md.StartLocation = startLocation; "(" [ FormalParameterList<parameters> ] ")"
md.EndLocation = t.EndLocation; { IF (IdentIsWhere()) TypeParameterConstraintsClause<templates> }
compilationUnit.AddChild(md); ";"
.) (. MethodDeclaration md = new MethodDeclaration(name, mod, new TypeReference("void"), parameters, attributes);
md.StartLocation = startLocation;
md.EndLocation = t.EndLocation;
md.Templates = templates;
compilationUnit.AddChild(md);
.)
| ( | (
Type<out type> (. if (startLocation.X == -1) startLocation = t.Location; .) Type<out type> (. if (startLocation.X == -1) startLocation = t.Location; .)
( (
@ -1319,11 +1326,12 @@ InterfaceMemberDecl
"(" [ FormalParameterList<parameters> ] ")" "(" [ FormalParameterList<parameters> ] ")"
/* .NET 2.0 */ /* .NET 2.0 */
{ IF (IdentIsWhere()) TypeParameterConstraintsClause<templates> } { IF (IdentIsWhere()) TypeParameterConstraintsClause<templates> }
";" (. MethodDeclaration md = new MethodDeclaration(name, mod, type, parameters, attributes); ";" (. MethodDeclaration md = new MethodDeclaration(name, mod, type, parameters, attributes);
md.StartLocation = startLocation; md.StartLocation = startLocation;
md.EndLocation = t.EndLocation; md.EndLocation = t.EndLocation;
compilationUnit.AddChild(md); md.Templates = templates;
.) compilationUnit.AddChild(md);
.)
/*--- interface property declaration: */ /*--- interface property declaration: */
| (. PropertyDeclaration pd = new PropertyDeclaration(name, type, mod, attributes); compilationUnit.AddChild(pd); .) | (. PropertyDeclaration pd = new PropertyDeclaration(name, type, mod, attributes); compilationUnit.AddChild(pd); .)
"{" (. Point bodyStart = t.Location;.) InterfaceAccessors<out getBlock, out setBlock> "}" (. pd.GetRegion = getBlock; pd.SetRegion = setBlock; pd.StartLocation = startLocation; pd.EndLocation = qualIdentEndLocation; pd.BodyStart = bodyStart; pd.BodyEnd = t.EndLocation; .) "{" (. Point bodyStart = t.Location;.) InterfaceAccessors<out getBlock, out setBlock> "}" (. pd.GetRegion = getBlock; pd.SetRegion = setBlock; pd.StartLocation = startLocation; pd.EndLocation = qualIdentEndLocation; pd.BodyStart = bodyStart; pd.BodyEnd = t.EndLocation; .)

40
src/Libraries/NRefactory/Test/Parser/TypeLevel/MethodDeclarationTests.cs

@ -111,6 +111,46 @@ namespace ICSharpCode.NRefactory.Tests.AST
Assert.AreEqual(1, md.Templates[0].Bases.Count); Assert.AreEqual(1, md.Templates[0].Bases.Count);
Assert.AreEqual("ISomeInterface", md.Templates[0].Bases[0].Type); Assert.AreEqual("ISomeInterface", md.Templates[0].Bases[0].Type);
} }
[Test]
public void CSharpGenericMethodInInterface()
{
const string program = @"interface MyInterface {
T MyMethod<T>(T a) where T : ISomeInterface;
}
";
TypeDeclaration td = (TypeDeclaration)ParseUtilCSharp.ParseGlobal(program, typeof(TypeDeclaration));
MethodDeclaration md = (MethodDeclaration)td.Children[0];
Assert.AreEqual("T", md.TypeReference.Type);
Assert.AreEqual(1, md.Parameters.Count);
Assert.AreEqual("T", ((ParameterDeclarationExpression)md.Parameters[0]).TypeReference.Type);
Assert.AreEqual("a", ((ParameterDeclarationExpression)md.Parameters[0]).ParameterName);
Assert.AreEqual(1, md.Templates.Count);
Assert.AreEqual("T", md.Templates[0].Name);
Assert.AreEqual(1, md.Templates[0].Bases.Count);
Assert.AreEqual("ISomeInterface", md.Templates[0].Bases[0].Type);
}
[Test]
public void CSharpGenericVoidMethodInInterface()
{
const string program = @"interface MyInterface {
void MyMethod<T>(T a) where T : ISomeInterface;
}
";
TypeDeclaration td = (TypeDeclaration)ParseUtilCSharp.ParseGlobal(program, typeof(TypeDeclaration));
MethodDeclaration md = (MethodDeclaration)td.Children[0];
Assert.AreEqual("void", md.TypeReference.Type);
Assert.AreEqual(1, md.Parameters.Count);
Assert.AreEqual("T", ((ParameterDeclarationExpression)md.Parameters[0]).TypeReference.Type);
Assert.AreEqual("a", ((ParameterDeclarationExpression)md.Parameters[0]).ParameterName);
Assert.AreEqual(1, md.Templates.Count);
Assert.AreEqual("T", md.Templates[0].Name);
Assert.AreEqual(1, md.Templates[0].Bases.Count);
Assert.AreEqual("ISomeInterface", md.Templates[0].Bases[0].Type);
}
#endregion #endregion
#region VB.NET #region VB.NET

82
src/Main/Base/Project/Src/Dom/ExpressionContext.cs

@ -11,15 +11,52 @@ using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop.Dom namespace ICSharpCode.SharpDevelop.Dom
{ {
/// <summary> /// <summary>
/// Class describing a contexts in which an expressions can be. /// Class describing a context in which an expression can be.
/// Serves as filter for code completion results, but the contexts exposed as static fields /// Serves as filter for code completion results, but the contexts exposed as static fields
/// can also be used as a kind of enumeration for special behaviour in the resolver. /// can also be used as a kind of enumeration for special behaviour in the resolver.
/// </summary> /// </summary>
public abstract class ExpressionContext public abstract class ExpressionContext
{ {
#region Instance members
public abstract bool ShowEntry(object o); public abstract bool ShowEntry(object o);
#region Default contexts (public fields) protected bool readOnly = true;
object suggestedItem;
/// <summary>
/// Gets if the expression is in the context of an object creation.
/// </summary>
public virtual bool IsObjectCreation {
get {
return false;
}
set {
if (value)
throw new NotSupportedException();
}
}
/// <summary>
/// Gets/Sets the default item that should be included in a code completion popup
/// in this context and selected as default value.
/// </summary>
/// <example>
/// "List&lt;TypeName&gt; var = new *expr*();" has as suggested item the pseudo-class
/// "List&lt;TypeName&gt;".
/// </example>
public object SuggestedItem {
get {
return suggestedItem;
}
set {
if (readOnly)
throw new NotSupportedException();
suggestedItem = value;
}
}
#endregion
#region Default contexts (public static fields)
/// <summary>Default/unknown context</summary> /// <summary>Default/unknown context</summary>
public static ExpressionContext Default = new DefaultExpressionContext(); public static ExpressionContext Default = new DefaultExpressionContext();
@ -29,31 +66,32 @@ namespace ICSharpCode.SharpDevelop.Dom
/// <summary>Context expects a type name</summary> /// <summary>Context expects a type name</summary>
/// <example>typeof(*expr*), is *expr*, using(*expr* ...)</example> /// <example>typeof(*expr*), is *expr*, using(*expr* ...)</example>
public static ExpressionContext Type = new TypeExpressionContext(null, false); public static ExpressionContext Type = new TypeExpressionContext(null, false, true);
/// <summary>Context expects a non-abstract type that has accessible constructors</summary> /// <summary>Context expects a non-abstract type that has accessible constructors</summary>
/// <example>new *expr*();</example> /// <example>new *expr*();</example>
/// <remarks>When using this context, a resolver should treat the expression as object creation, /// <remarks>When using this context, a resolver should treat the expression as object creation,
/// even when the keyword "new" is not part of the expression.</remarks> /// even when the keyword "new" is not part of the expression.</remarks>
public static ExpressionContext ObjectCreation = new TypeExpressionContext(null, true); public static ExpressionContext ObjectCreation = new TypeExpressionContext(null, true, true);
/// <summary>Context expects a non-abstract type deriving from System.Attribute.</summary> /// <summary>Context expects a non-abstract type deriving from System.Attribute.</summary>
/// <example>[*expr*()]</example> /// <example>[*expr*()]</example>
/// <remarks>When using this context, a resolver should try resolving typenames with an /// <remarks>When using this context, a resolver should try resolving typenames with an
/// appended "Attribute" suffix and treat "invocations" of the attribute type as /// appended "Attribute" suffix and treat "invocations" of the attribute type as
/// object creation.</remarks> /// object creation.</remarks>
public static ExpressionContext Attribute = new TypeExpressionContext(ProjectContentRegistry.Mscorlib.GetClass("System.Attribute"), true); public static ExpressionContext Attribute = new TypeExpressionContext(ProjectContentRegistry.Mscorlib.GetClass("System.Attribute"), true, true);
/// <summary>Context expects a type name which has special base type</summary> /// <summary>Context expects a type name which has special base type</summary>
/// <param name="baseClass">The class the expression must derive from.</param> /// <param name="baseClass">The class the expression must derive from.</param>
/// <param name="allowAbstract">Specifies whether classes must be constructable.</param> /// <param name="isObjectCreation">Specifies whether classes must be constructable.</param>
/// <example>catch(*expr* ...), using(*expr* ...), throw new ***</example> /// <example>catch(*expr* ...), using(*expr* ...), throw new ***</example>
public static ExpressionContext TypeDerivingFrom(IClass baseClass, bool mustBeConstructable) public static ExpressionContext TypeDerivingFrom(IClass baseClass, bool isObjectCreation)
{ {
return new TypeExpressionContext(baseClass, mustBeConstructable); return new TypeExpressionContext(baseClass, isObjectCreation, false);
} }
/// <summary>Context expeacts an interface</summary> /// <summary>Context expects an interface</summary>
/// <example>Implements *expr*</example>
public static InterfaceExpressionContext Interface = new InterfaceExpressionContext(); public static InterfaceExpressionContext Interface = new InterfaceExpressionContext();
#endregion #endregion
@ -92,12 +130,13 @@ namespace ICSharpCode.SharpDevelop.Dom
class TypeExpressionContext : ExpressionContext class TypeExpressionContext : ExpressionContext
{ {
IClass baseClass; IClass baseClass;
bool mustBeConstructable; bool isObjectCreation;
public TypeExpressionContext(IClass baseClass, bool mustBeConstructable) public TypeExpressionContext(IClass baseClass, bool isObjectCreation, bool readOnly)
{ {
this.baseClass = baseClass; this.baseClass = baseClass;
this.mustBeConstructable = mustBeConstructable; this.isObjectCreation = isObjectCreation;
this.readOnly = readOnly;
} }
public override bool ShowEntry(object o) public override bool ShowEntry(object o)
@ -107,7 +146,7 @@ namespace ICSharpCode.SharpDevelop.Dom
IClass c = o as IClass; IClass c = o as IClass;
if (c == null) if (c == null)
return false; return false;
if (mustBeConstructable) { if (isObjectCreation) {
if (c.IsAbstract || c.IsStatic) return false; if (c.IsAbstract || c.IsStatic) return false;
if (c.ClassType == ClassType.Enum) return false; if (c.ClassType == ClassType.Enum) return false;
} }
@ -116,13 +155,24 @@ namespace ICSharpCode.SharpDevelop.Dom
return c.IsTypeInInheritanceTree(baseClass); return c.IsTypeInInheritanceTree(baseClass);
} }
public override bool IsObjectCreation {
get {
return isObjectCreation;
}
set {
if (readOnly && value != isObjectCreation)
throw new NotSupportedException();
isObjectCreation = value;
}
}
public override string ToString() public override string ToString()
{ {
if (baseClass != null) if (baseClass != null)
return "[" + GetType().Name + ": " + baseClass.FullyQualifiedName return "[" + GetType().Name + ": " + baseClass.FullyQualifiedName
+ " mustBeConstructable=" + mustBeConstructable + "]"; + " IsObjectCreation=" + IsObjectCreation + "]";
else else
return "[" + GetType().Name + " mustBeConstructable=" + mustBeConstructable + "]"; return "[" + GetType().Name + " IsObjectCreation=" + IsObjectCreation + "]";
} }
} }
#endregion #endregion
@ -184,8 +234,6 @@ namespace ICSharpCode.SharpDevelop.Dom
#region InterfaceExpressionContext #region InterfaceExpressionContext
public class InterfaceExpressionContext : ExpressionContext public class InterfaceExpressionContext : ExpressionContext
{ {
IClass baseClass;
public InterfaceExpressionContext() public InterfaceExpressionContext()
{ {
} }

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

@ -118,7 +118,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
} }
expression = expression.TrimStart(); expression = expression.TrimStart();
if (expressionResult.Context == ExpressionContext.ObjectCreation) { if (expressionResult.Context.IsObjectCreation) {
expression = "new " + expression; expression = "new " + expression;
} }

3
src/Main/Base/Project/Src/Services/Debugger/CurrentLineBookmark.cs

@ -72,7 +72,8 @@ namespace ICSharpCode.Core
public CurrentLineBookmark(string fileName, IDocument document, int startLine) : base(fileName, document, startLine) public CurrentLineBookmark(string fileName, IDocument document, int startLine) : base(fileName, document, startLine)
{ {
this.IsSaved = false;
this.IsVisibleInBookmarkPad = false;
} }
public override void Draw(IconBarMargin margin, Graphics g, Point p) public override void Draw(IconBarMargin margin, Graphics g, Point p)

42
src/Main/Base/Project/Src/TextEditor/Bookmarks/Bookmark.cs

@ -23,6 +23,11 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
[TypeConverter(typeof(BookmarkConverter))] [TypeConverter(typeof(BookmarkConverter))]
public class SDBookmark : Bookmark public class SDBookmark : Bookmark
{ {
public SDBookmark(string fileName, IDocument document, int lineNumber) : base(document, lineNumber)
{
this.fileName = fileName;
}
string fileName; string fileName;
public string FileName { public string FileName {
@ -34,9 +39,40 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
} }
} }
public SDBookmark(string fileName, IDocument document, int lineNumber) : base(document, lineNumber) bool isSaved = true;
{
this.fileName = fileName; /// <summary>
/// Gets/Sets if the bookmark should be saved to the project memento file.
/// </summary>
/// <remarks>
/// Default is true, set this property to false if you are using the bookmark for
/// something special like like "CurrentLineBookmark" in the debugger.
/// </remarks>
public bool IsSaved {
get {
return isSaved;
}
set {
isSaved = value;
}
}
bool isVisibleInBookmarkPad = true;
/// <summary>
/// Gets/Sets if the bookmark is shown in the bookmark pad.
/// </summary>
/// <remarks>
/// Default is true, set this property to false if you are using the bookmark for
/// something special like like "CurrentLineBookmark" in the debugger.
/// </remarks>
public bool IsVisibleInBookmarkPad {
get {
return isVisibleInBookmarkPad;
}
set {
isVisibleInBookmarkPad = value;
}
} }
} }

2
src/Main/Base/Project/Src/TextEditor/Bookmarks/BookmarkManager.cs

@ -71,7 +71,7 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
{ {
List<SDBookmark> projectBookmarks = new List<SDBookmark>(); List<SDBookmark> projectBookmarks = new List<SDBookmark>();
foreach (SDBookmark mark in bookmarks) { foreach (SDBookmark mark in bookmarks) {
if (mark.FileName != null && project.IsFileInProject(mark.FileName)) { if (mark.IsSaved && mark.FileName != null && project.IsFileInProject(mark.FileName)) {
projectBookmarks.Add(mark); projectBookmarks.Add(mark);
} }
} }

2
src/Main/Base/Project/Src/TextEditor/Bookmarks/Pad/BookmarkPad.cs

@ -69,6 +69,8 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
void AddMark(SDBookmark mark) void AddMark(SDBookmark mark)
{ {
if (!mark.IsVisibleInBookmarkPad)
return;
if (!fileNodes.ContainsKey(mark.FileName)) { if (!fileNodes.ContainsKey(mark.FileName)) {
BookmarkFolderNode folderNode = new BookmarkFolderNode(mark.FileName); BookmarkFolderNode folderNode = new BookmarkFolderNode(mark.FileName);
fileNodes.Add(mark.FileName, folderNode); fileNodes.Add(mark.FileName, folderNode);

4
src/Main/Base/Project/Src/TextEditor/Gui/Editor/InsightWindow/MethodInsightDataProvider.cs

@ -119,9 +119,9 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
protected virtual void SetupDataProvider(string fileName, IDocument document, ExpressionResult expressionResult, int caretLineNumber, int caretColumn) protected virtual void SetupDataProvider(string fileName, IDocument document, ExpressionResult expressionResult, int caretLineNumber, int caretColumn)
{ {
bool constructorInsight = false; bool constructorInsight = false;
if (expressionResult.Context == ExpressionContext.ObjectCreation) { if (expressionResult.Context.IsObjectCreation) {
constructorInsight = true; constructorInsight = true;
expressionResult.Context = ExpressionContext.Default; expressionResult.Context = ExpressionContext.Type;
} else if (expressionResult.Context == ExpressionContext.Attribute) { } else if (expressionResult.Context == ExpressionContext.Attribute) {
constructorInsight = true; constructorInsight = true;
} }

Loading…
Cancel
Save