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 21 years ago
parent
commit
39e4a95f2d
  1. 1644
      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. 9
      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

1644
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;
} }

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

@ -23,7 +23,7 @@ namespace ICSharpCode.Core
public class CurrentLineBookmark: SDMarkerBookmark public class CurrentLineBookmark: SDMarkerBookmark
{ {
static CurrentLineBookmark instance; static CurrentLineBookmark instance;
static int startLine; static int startLine;
static int startColumn; static int startColumn;
static int endLine; static int endLine;
@ -41,12 +41,12 @@ namespace ICSharpCode.Core
public static void SetPosition(string fileName, IDocument document, int makerStartLine, int makerStartColumn, int makerEndLine, int makerEndColumn) public static void SetPosition(string fileName, IDocument document, int makerStartLine, int makerStartColumn, int makerEndLine, int makerEndColumn)
{ {
Remove(); Remove();
startLine = makerStartLine; startLine = makerStartLine;
startColumn = makerStartColumn; startColumn = makerStartColumn;
endLine = makerEndLine; endLine = makerEndLine;
endColumn = makerEndColumn; endColumn = makerEndColumn;
LineSegment line = document.GetLineSegment(startLine - 1); LineSegment line = document.GetLineSegment(startLine - 1);
int offset = line.Offset + startColumn; int offset = line.Offset + startColumn;
instance = new CurrentLineBookmark(fileName, document, startLine - 1); instance = new CurrentLineBookmark(fileName, document, startLine - 1);
@ -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