Browse Source

Code completion: fixed some context detection bugs.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2720 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 19 years ago
parent
commit
6e385b8ff4
  1. 81
      src/Main/Base/Test/CSharpExpressionFinderTests.cs
  2. 64
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CSharp/ExpressionFinder.cs
  3. 3
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Refactoring/CodeGenerator.cs

81
src/Main/Base/Test/CSharpExpressionFinderTests.cs

@ -717,6 +717,87 @@ public class X { }"; @@ -717,6 +717,87 @@ public class X { }";
FindFull(program, "stFix", "TestFixture", ExpressionContext.Attribute);
}
[Test]
public void Indexer1()
{
const string program = @"using System;
class Main {
public int this[";
ExpressionResult result = ef.FindExpression(program, program.Length);
Assert.AreEqual(ExpressionContext.ParameterType, result.Context);
}
[Test]
public void Indexer2()
{
const string program = @"using System;
class Main {
public int this[int index] { ";
ExpressionResult result = ef.FindExpression(program, program.Length);
Assert.AreEqual(ExpressionContext.PropertyDeclaration, result.Context);
}
[Test]
public void IndexerAccessInObjectInitializer()
{
const string program = @"using System;
class Main {
void M() {
a = new SomeObject { b = c[ ";
ExpressionResult result = ef.FindExpression(program, program.Length);
Assert.AreEqual(ExpressionContext.Default, result.Context);
}
[Test]
public void ContextInCondition()
{
const string program = @"using System;
class Main {
void M() {
if ( ";
ExpressionResult result = ef.FindExpression(program, program.Length);
Assert.AreEqual(ExpressionContext.Default, result.Context);
}
[Test]
public void ContextInCall()
{
const string program = @"using System;
class Main {
void M() {
MethodCall( ";
ExpressionResult result = ef.FindExpression(program, program.Length);
Assert.AreEqual(ExpressionContext.Default, result.Context);
}
[Test]
public void BlockLambdaInCondition()
{
const string program = @"using System;
class Main {
void M() {
if (Method(a => { ";
ExpressionResult result = ef.FindExpression(program, program.Length);
Assert.AreEqual(ExpressionContext.MethodBody, result.Context);
}
[Test]
public void BlockLambdaInField()
{
const string program = @"using System;
class Main {
Func<int, int> f = a => { ";
ExpressionResult result = ef.FindExpression(program, program.Length);
Assert.AreEqual(ExpressionContext.MethodBody, result.Context);
}
}
}

64
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CSharp/ExpressionFinder.cs

@ -124,6 +124,7 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp @@ -124,6 +124,7 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp
internal FrameType type;
internal FrameType parenthesisChildType;
internal FrameType curlyChildType;
internal FrameType squareBracketChildType;
internal FrameState state;
internal char bracketType;
internal ExpressionContext context;
@ -134,6 +135,7 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp @@ -134,6 +135,7 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp
return type == FrameType.Statements
|| type == FrameType.Expression
|| type == FrameType.AttributeArguments
|| type == FrameType.ObjectInitializer
|| state == FrameState.Initializer
|| state == FrameState.ObjectCreation;
}
@ -218,12 +220,15 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp @@ -218,12 +220,15 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp
this.type = parent.curlyChildType;
} else if (bracketType == '(') {
this.type = parent.parenthesisChildType;
} else if (bracketType == '[') {
this.type = parent.squareBracketChildType;
} else {
this.type = parent.type;
}
}
ResetCurlyChildType();
ResetParenthesisChildType();
ResetSquareBracketChildType();
SetDefaultContext();
}
@ -246,7 +251,7 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp @@ -246,7 +251,7 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp
public void ResetParenthesisChildType()
{
if (state == FrameState.Initializer || type == FrameType.ObjectInitializer) {
if (this.InExpressionMode) {
this.parenthesisChildType = FrameType.Expression;
} else if (type == FrameType.AttributeSection) {
this.parenthesisChildType = FrameType.AttributeArguments;
@ -254,6 +259,14 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp @@ -254,6 +259,14 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp
this.parenthesisChildType = this.type;
}
}
public void ResetSquareBracketChildType()
{
if (InExpressionMode)
this.squareBracketChildType = FrameType.Expression;
else
this.squareBracketChildType = FrameType.AttributeSection;
}
}
void Init(string text, int offset)
@ -350,20 +363,18 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp @@ -350,20 +363,18 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp
}
break;
case Tokens.OpenParenthesis:
case Tokens.OpenSquareBracket:
if (frame.lastExpressionStart.IsEmpty && token.kind == Tokens.OpenParenthesis)
if (frame.lastExpressionStart.IsEmpty)
frame.lastExpressionStart = token.Location;
frame = new Frame(frame, '(');
frame.parent.ResetParenthesisChildType();
if (token.kind == Tokens.OpenSquareBracket && !frame.parent.InExpressionMode) {
frame.type = FrameType.AttributeSection;
frame.ResetParenthesisChildType();
frame.SetDefaultContext();
}
break;
case Tokens.OpenSquareBracket:
frame = new Frame(frame, '[');
frame.parent.ResetSquareBracketChildType();
break;
case Tokens.CloseParenthesis:
case Tokens.CloseSquareBracket:
if (frame.parent != null && frame.bracketType == '(') {
if (frame.parent != null && (frame.bracketType == '(' || frame.bracketType == '[')) {
frame.type = FrameType.Popped;
frame = frame.parent;
}
@ -437,6 +448,16 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp @@ -437,6 +448,16 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp
case Tokens.Using:
if (frame.type == FrameType.Global) {
frame.SetContext(ExpressionContext.Namespace);
break;
} else {
goto case Tokens.For;
}
case Tokens.For:
case Tokens.Foreach:
case Tokens.Fixed:
case Tokens.Catch:
if (frame.type == FrameType.Statements) {
frame.parenthesisChildType = FrameType.Statements;
}
break;
case Tokens.Throw:
@ -463,6 +484,7 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp @@ -463,6 +484,7 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp
frame.SetContext(ExpressionContext.Default);
frame.state = FrameState.Initializer;
frame.ResetParenthesisChildType();
frame.ResetSquareBracketChildType();
frame.ResetCurlyChildType();
break;
} else if (frame.type == FrameType.ObjectInitializer) {
@ -509,11 +531,17 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp @@ -509,11 +531,17 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp
}
break;
case Tokens.Delegate:
if (frame.type == FrameType.Global || frame.type == FrameType.TypeDecl) {
if (frame.InExpressionMode) {
frame.parenthesisChildType = FrameType.ParameterList;
frame.curlyChildType = FrameType.Statements;
} else if (frame.type == FrameType.Global || frame.type == FrameType.TypeDecl) {
frame.parenthesisChildType = FrameType.ParameterList;
frame.SetContext(ExpressionContext.Type);
}
break;
case Tokens.LambdaArrow:
frame.curlyChildType = FrameType.Statements;
break;
case Tokens.Event:
frame.SetContext(ExpressionContext.DelegateType);
frame.curlyChildType = FrameType.Event;
@ -544,19 +572,21 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp @@ -544,19 +572,21 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp
frame.parent.curlyChildType = FrameType.Statements;
}
break;
case Tokens.If:
case Tokens.While:
case Tokens.Switch:
if (frame.type == FrameType.Statements) {
frame.parenthesisChildType = FrameType.Expression;
}
break;
case Tokens.Question:
// IdentifierExpected = this is after a type name = the ? was a nullable marker
if (frame.context != ExpressionContext.IdentifierExpected) {
frame.SetDefaultContext();
}
break;
case Tokens.This:
if (frame.state == FrameState.FieldDecl) {
// this is an indexer declaration
frame.squareBracketChildType = FrameType.ParameterList;
}
break;
case Tokens.Goto:
frame.SetContext(ExpressionContext.IdentifierExpected);
break;
default:
if (Tokens.SimpleTypeName[token.kind]) {
if (frame.type == FrameType.Interface || frame.type == FrameType.TypeDecl) {

3
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Refactoring/CodeGenerator.cs

@ -538,6 +538,7 @@ namespace ICSharpCode.SharpDevelop.Dom.Refactoring @@ -538,6 +538,7 @@ namespace ICSharpCode.SharpDevelop.Dom.Refactoring
foreach (IEvent e in interf.GetEvents()) {
if (!InterfaceMemberAlreadyImplemented(targetClassEvents, e, out requireAlternativeImplementation)) {
EventDeclaration ed = ConvertMember(e, context);
ed.Attributes.Clear();
if (explicitImpl || requireAlternativeImplementation) {
ed.InterfaceImplementations.Add(CreateInterfaceImplementation(e, context));
@ -561,6 +562,7 @@ namespace ICSharpCode.SharpDevelop.Dom.Refactoring @@ -561,6 +562,7 @@ namespace ICSharpCode.SharpDevelop.Dom.Refactoring
foreach (IProperty p in interf.GetProperties()) {
if (!InterfaceMemberAlreadyImplemented(targetClassProperties, p, out requireAlternativeImplementation)) {
AttributedNode pd = ConvertMember(p, context);
pd.Attributes.Clear();
if (explicitImpl || requireAlternativeImplementation) {
InterfaceImplementation impl = CreateInterfaceImplementation(p, context);
if (pd is IndexerDeclaration) {
@ -581,6 +583,7 @@ namespace ICSharpCode.SharpDevelop.Dom.Refactoring @@ -581,6 +583,7 @@ namespace ICSharpCode.SharpDevelop.Dom.Refactoring
foreach (IMethod m in interf.GetMethods()) {
if (!InterfaceMemberAlreadyImplemented(targetClassMethods, m, out requireAlternativeImplementation)) {
MethodDeclaration md = ConvertMember(m, context) as MethodDeclaration;
md.Attributes.Clear();
if (md != null) {
if (explicitImpl || requireAlternativeImplementation) {
md.InterfaceImplementations.Add(CreateInterfaceImplementation(m, context));

Loading…
Cancel
Save