Browse Source

Fixed parsing of some statements, improved "foreach" context in code

completion.
newNRvisualizers
Mike Krüger 14 years ago
parent
commit
37795e43a1
  1. 39
      ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs
  2. 4
      ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs
  3. 4239
      ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs
  4. 21
      ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.jay
  5. 8
      ICSharpCode.NRefactory.CSharp/Parser/mcs/statement.cs
  6. 18
      ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/KeywordTests.cs
  7. 17
      ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/VariableDeclarationStatementTests.cs

39
ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs

@ -445,6 +445,24 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -445,6 +445,24 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
CSharpResolver csResolver;
AstNode n = identifierStart.Item2;
// Handle foreach (type name _
if (n is IdentifierExpression) {
var prev = n.GetPrevNode () as ForeachStatement;
if (prev != null && prev.InExpression.IsNull) {
if (controlSpace) {
contextList.AddCustom ("in");
return contextList.Result;
}
return null;
}
}
if (n is Identifier && n.Parent is ForeachStatement) {
if (controlSpace)
return DefaultControlSpaceItems ();
return null;
}
if (n is ArrayInitializerExpression) {
var initalizerResult = ResolveExpression (identifierStart.Item1, n.Parent, identifierStart.Item3);
@ -638,6 +656,18 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -638,6 +656,18 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
node = Unit.GetNodeAt (location);
rr = ResolveExpression (CSharpParsedFile, node, Unit);
}
if (node is Identifier && node.Parent is ForeachStatement) {
var foreachStmt = (ForeachStatement)node.Parent;
foreach (var possibleName in GenerateNameProposals (foreachStmt.VariableType)) {
if (possibleName.Length > 0)
wrapper.Result.Add (factory.CreateLiteralCompletionData (possibleName.ToString ()));
}
AutoSelect = false;
AutoCompleteEmptyMatch = false;
return wrapper.Result;
}
AddContextCompletion (wrapper, rr != null && (node is Expression) ? rr.Item2 : GetState (), node);
@ -1830,6 +1860,15 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1830,6 +1860,15 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
}
if (expr == null) {
var forStmt = tmpUnit.GetNodeAt<ForeachStatement> (location.Line, location.Column - 3);
if (forStmt != null && forStmt.EmbeddedStatement.IsNull) {
forStmt.VariableNameToken = Identifier.Create ("stub");
expr = forStmt.VariableNameToken;
baseUnit = tmpUnit;
}
}
if (expr == null) {
expr = tmpUnit.GetNodeAt<VariableInitializer> (location.Line, location.Column - 1);

4
ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs

@ -1894,13 +1894,13 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1894,13 +1894,13 @@ namespace ICSharpCode.NRefactory.CSharp
if (foreachStatement.Variable != null)
result.AddChild (Identifier.Create (foreachStatement.Variable.Name, Convert (foreachStatement.Variable.Location)), ForeachStatement.Roles.Identifier);
if (location != null)
if (location != null && location.Count > 1)
result.AddChild (new CSharpTokenNode (Convert (location [1]), "in".Length), ForeachStatement.Roles.InKeyword);
if (foreachStatement.Expr != null)
result.AddChild ((Expression)foreachStatement.Expr.Accept (this), ForeachStatement.Roles.Expression);
if (location != null)
if (location != null && location.Count > 2)
result.AddChild (new CSharpTokenNode (Convert (location [2]), 1), ForeachStatement.Roles.RPar);
if (foreachStatement.Statement != null)
result.AddChild ((Statement)foreachStatement.Statement.Accept (this), ForeachStatement.Roles.EmbeddedStatement);

4239
ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs

File diff suppressed because it is too large Load Diff

21
ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.jay

@ -5408,6 +5408,27 @@ foreach_statement @@ -5408,6 +5408,27 @@ foreach_statement
lbag.AddStatement (f, GetLocation ($2), GetLocation ($5), GetLocation ($7));
$$ = end_block (GetLocation ($7));
}
| FOREACH open_parens_any type identifier_inside_body error
{
start_block (GetLocation ($2));
current_block.IsCompilerGenerated = true;
var lt = $4 as Tokenizer.LocatedToken;
var li = lt != null ? new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ForeachVariable | LocalVariable.Flags.Used, lt.Location) : null;
Foreach f = new Foreach ((Expression) $3, li, null, null, GetLocation ($1));
current_block.AddStatement (f);
lbag.AddStatement (f, GetLocation ($2));
$$ = end_block (GetLocation ($5));
}
| FOREACH open_parens_any type error
{
Foreach f = new Foreach ((Expression) $3, null, null, null, GetLocation ($1));
current_block.AddStatement (f);
lbag.AddStatement (f, GetLocation ($2));
$$ = f;
}
;
jump_statement

8
ICSharpCode.NRefactory.CSharp/Parser/mcs/statement.cs

@ -691,6 +691,11 @@ namespace Mono.CSharp { @@ -691,6 +691,11 @@ namespace Mono.CSharp {
{
throw new NotImplementedException ();
}
public override object Accept (StructuralVisitor visitor)
{
return visitor.Visit (this);
}
}
//
@ -5207,10 +5212,11 @@ namespace Mono.CSharp { @@ -5207,10 +5212,11 @@ namespace Mono.CSharp {
this.Block = block;
this.Specific = catch_clauses;
this.inside_try_finally = inside_try_finally;
if (catch_clauses != null) {
Catch c = catch_clauses [0];
if (c.IsGeneral) {
this.General = c;
this.General = c;
catch_clauses.RemoveAt (0);
}
}

18
ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/KeywordTests.cs

@ -287,6 +287,24 @@ class Test @@ -287,6 +287,24 @@ class Test
});
}
[Test()]
public void ForeachInKeywordTest ()
{
CodeCompletionBugTests.CombinedProviderTest (
@"using System;
class Test
{
public void Method ()
{
$foreach (var o i$
}
}
", (provider) => {
// Either empty list or in - both behaviours are ok.
if (provider.Count > 0)
Assert.IsNotNull (provider.Find ("in"), "keyword 'in' not found.");
});
}
}
}

17
ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/VariableDeclarationStatementTests.cs

@ -97,6 +97,23 @@ class MyTest @@ -97,6 +97,23 @@ class MyTest
Assert.IsNotNull (provider.Find ("test"), "name proposal 'test' not found.");
}
[Test()]
public void TestNameProposalForeach ()
{
var provider = CodeCompletionBugTests.CreateCtrlSpaceProvider (
@"
class MyTest
{
public void Test ()
{
$foreach (MyTest $
}
}
");
Assert.IsNotNull (provider.Find ("myTest"), "name proposal 'myTest' not found.");
Assert.IsNotNull (provider.Find ("test"), "name proposal 'test' not found.");
}
/// <summary>
/// Bug 1799 - [New Resolver] Invalid code completion when typing name of variable
/// </summary>

Loading…
Cancel
Save