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> @@ -906,8 +906,10 @@ Type<out TypeReference type>
| "[" { "," (. ++i; .) } "]" (. r.Add(i); .)
)
}
(. type.RankSpecifier = r.ToArray();
type.PointerNestingLevel = pointer;
(. if (type != null) {
type.RankSpecifier = r.ToArray();
type.PointerNestingLevel = pointer;
}
.)
.
@ -1303,11 +1305,16 @@ InterfaceMemberDecl @@ -1303,11 +1305,16 @@ InterfaceMemberDecl
(
/*--- interface void method (procedure) declaration: */
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);
md.StartLocation = startLocation;
md.EndLocation = t.EndLocation;
compilationUnit.AddChild(md);
.)
[ TypeParameterList<templates> ]
"(" [ FormalParameterList<parameters> ] ")"
{ IF (IdentIsWhere()) TypeParameterConstraintsClause<templates> }
";"
(. 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; .)
(
@ -1319,11 +1326,12 @@ InterfaceMemberDecl @@ -1319,11 +1326,12 @@ InterfaceMemberDecl
"(" [ FormalParameterList<parameters> ] ")"
/* .NET 2.0 */
{ IF (IdentIsWhere()) TypeParameterConstraintsClause<templates> }
";" (. MethodDeclaration md = new MethodDeclaration(name, mod, type, parameters, attributes);
md.StartLocation = startLocation;
md.EndLocation = t.EndLocation;
compilationUnit.AddChild(md);
.)
";" (. MethodDeclaration md = new MethodDeclaration(name, mod, type, parameters, attributes);
md.StartLocation = startLocation;
md.EndLocation = t.EndLocation;
md.Templates = templates;
compilationUnit.AddChild(md);
.)
/*--- interface property declaration: */
| (. 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; .)

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

@ -111,6 +111,46 @@ namespace ICSharpCode.NRefactory.Tests.AST @@ -111,6 +111,46 @@ namespace ICSharpCode.NRefactory.Tests.AST
Assert.AreEqual(1, md.Templates[0].Bases.Count);
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
#region VB.NET

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

@ -11,15 +11,52 @@ using ICSharpCode.Core; @@ -11,15 +11,52 @@ using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop.Dom
{
/// <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
/// can also be used as a kind of enumeration for special behaviour in the resolver.
/// </summary>
public abstract class ExpressionContext
{
#region Instance members
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>
public static ExpressionContext Default = new DefaultExpressionContext();
@ -29,31 +66,32 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -29,31 +66,32 @@ namespace ICSharpCode.SharpDevelop.Dom
/// <summary>Context expects a type name</summary>
/// <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>
/// <example>new *expr*();</example>
/// <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>
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>
/// <example>[*expr*()]</example>
/// <remarks>When using this context, a resolver should try resolving typenames with an
/// appended "Attribute" suffix and treat "invocations" of the attribute type as
/// 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>
/// <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>
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();
#endregion
@ -92,12 +130,13 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -92,12 +130,13 @@ namespace ICSharpCode.SharpDevelop.Dom
class TypeExpressionContext : ExpressionContext
{
IClass baseClass;
bool mustBeConstructable;
bool isObjectCreation;
public TypeExpressionContext(IClass baseClass, bool mustBeConstructable)
public TypeExpressionContext(IClass baseClass, bool isObjectCreation, bool readOnly)
{
this.baseClass = baseClass;
this.mustBeConstructable = mustBeConstructable;
this.isObjectCreation = isObjectCreation;
this.readOnly = readOnly;
}
public override bool ShowEntry(object o)
@ -107,7 +146,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -107,7 +146,7 @@ namespace ICSharpCode.SharpDevelop.Dom
IClass c = o as IClass;
if (c == null)
return false;
if (mustBeConstructable) {
if (isObjectCreation) {
if (c.IsAbstract || c.IsStatic) return false;
if (c.ClassType == ClassType.Enum) return false;
}
@ -116,13 +155,24 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -116,13 +155,24 @@ namespace ICSharpCode.SharpDevelop.Dom
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()
{
if (baseClass != null)
return "[" + GetType().Name + ": " + baseClass.FullyQualifiedName
+ " mustBeConstructable=" + mustBeConstructable + "]";
+ " IsObjectCreation=" + IsObjectCreation + "]";
else
return "[" + GetType().Name + " mustBeConstructable=" + mustBeConstructable + "]";
return "[" + GetType().Name + " IsObjectCreation=" + IsObjectCreation + "]";
}
}
#endregion
@ -184,8 +234,6 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -184,8 +234,6 @@ namespace ICSharpCode.SharpDevelop.Dom
#region InterfaceExpressionContext
public class InterfaceExpressionContext : ExpressionContext
{
IClass baseClass;
public InterfaceExpressionContext()
{
}

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

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

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

@ -72,7 +72,8 @@ namespace ICSharpCode.Core @@ -72,7 +72,8 @@ namespace ICSharpCode.Core
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)

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

@ -23,6 +23,11 @@ namespace ICSharpCode.SharpDevelop.Bookmarks @@ -23,6 +23,11 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
[TypeConverter(typeof(BookmarkConverter))]
public class SDBookmark : Bookmark
{
public SDBookmark(string fileName, IDocument document, int lineNumber) : base(document, lineNumber)
{
this.fileName = fileName;
}
string fileName;
public string FileName {
@ -34,9 +39,40 @@ namespace ICSharpCode.SharpDevelop.Bookmarks @@ -34,9 +39,40 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
}
}
public SDBookmark(string fileName, IDocument document, int lineNumber) : base(document, lineNumber)
{
this.fileName = fileName;
bool isSaved = true;
/// <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 @@ -71,7 +71,7 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
{
List<SDBookmark> projectBookmarks = new List<SDBookmark>();
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);
}
}

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

@ -69,6 +69,8 @@ namespace ICSharpCode.SharpDevelop.Bookmarks @@ -69,6 +69,8 @@ namespace ICSharpCode.SharpDevelop.Bookmarks
void AddMark(SDBookmark mark)
{
if (!mark.IsVisibleInBookmarkPad)
return;
if (!fileNodes.ContainsKey(mark.FileName)) {
BookmarkFolderNode folderNode = new BookmarkFolderNode(mark.FileName);
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 @@ -119,9 +119,9 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
protected virtual void SetupDataProvider(string fileName, IDocument document, ExpressionResult expressionResult, int caretLineNumber, int caretColumn)
{
bool constructorInsight = false;
if (expressionResult.Context == ExpressionContext.ObjectCreation) {
if (expressionResult.Context.IsObjectCreation) {
constructorInsight = true;
expressionResult.Context = ExpressionContext.Default;
expressionResult.Context = ExpressionContext.Type;
} else if (expressionResult.Context == ExpressionContext.Attribute) {
constructorInsight = true;
}

Loading…
Cancel
Save