Browse Source

Merge NRefactory commit '180a690f373354796520d9468138d95f193f8156' into SharpDevelop newNR branch.

newNRvisualizers
Daniel Grunwald 13 years ago
parent
commit
311ab03c15
  1. 5
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs
  2. 108
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstNode.cs
  3. 51
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/DepthFirstAstVisitor.cs
  4. 132
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/NewLineNode.cs
  5. 94
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/TextNode.cs
  6. 91
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/WhitespaceNode.cs
  7. 9
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/IAstVisitor.cs
  8. 33
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/ObservableAstVisitor.cs
  9. 3
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Roles.cs
  10. 7
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/ParameterDeclaration.cs
  11. 407
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs
  12. 286
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs
  13. 74
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs
  14. 69
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs
  15. 159
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/CSharpFormattingOptions.cs
  16. 339
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingOptionsFactory.cs
  17. 216
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/GeneratedCodeSettings.cs
  18. 15
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj
  19. 4
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpAmbience.cs
  20. 34
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs
  21. 21
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs
  22. 347
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/anonymous.cs
  23. 12
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/argument.cs
  24. 4
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/assembly.cs
  25. 12
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/assign.cs
  26. 502
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/async.cs
  27. 14
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/attribute.cs
  28. 8
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cfold.cs
  29. 97
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs
  30. 42
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/codegen.cs
  31. 2
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/const.cs
  32. 39
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/constant.cs
  33. 2
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/context.cs
  34. 13
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/convert.cs
  35. 8809
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs
  36. 130
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.jay
  37. 22
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs
  38. 17
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/decl.cs
  39. 8
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/delegate.cs
  40. 112
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/doc.cs
  41. 6
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/driver.cs
  42. 2
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/dynamic.cs
  43. 146
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/ecore.cs
  44. 6
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/enum.cs
  45. 136
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs
  46. 2
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/field.cs
  47. 152
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/iterators.cs
  48. 6
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/lambda.cs
  49. 20
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/linq.cs
  50. 8
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/literal.cs
  51. 10
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/membercache.cs
  52. 30
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/method.cs
  53. 5
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/module.cs
  54. 4
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/nullable.cs
  55. 126
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/parameter.cs
  56. 10
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/pending.cs
  57. 3
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/report.cs
  58. 567
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/statement.cs
  59. 153
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/typemanager.cs
  60. 3
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/typespec.cs
  61. 9
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/visit.cs
  62. 27
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/BaseRefactoringContext.cs
  63. 18
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeAction.cs
  64. 29
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CheckIfParameterIsNullAction.cs
  65. 13
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertDecToHexAction.cs
  66. 105
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateClassDeclarationAction.cs
  67. 52
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateFieldAction.cs
  68. 2
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateIndexerAction.cs
  69. 136
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateMethodDeclarationAction.cs
  70. 11
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreatePropertyAction.cs
  71. 186
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ExtractMethod/ExtractMethodAction.cs
  72. 85
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ExtractMethod/StaticVisitor.cs
  73. 97
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ExtractMethod/VariableLookupVisitor.cs
  74. 7
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/GeneratePropertyAction.cs
  75. 89
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/IntroduceConstantAction.cs
  76. 2
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/RemoveBackingStoreAction.cs
  77. 10
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/RemoveBracesAction.cs
  78. 38
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/SpecializedCodeAction.cs
  79. 49
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssue.cs
  80. 6
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ConditionalToNullCoalescingIssue.cs
  81. 71
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ExplicitConversionInForEachIssue.cs
  82. 23
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/GatherVisitorBase.cs
  83. 14
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/InconsistentNamingIssue/DefaultRules.cs
  84. 22
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/InconsistentNamingIssue/NamingConventionService.cs
  85. 6
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/NotImplementedExceptionIssue.cs
  86. 10
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantInternalIssue.cs
  87. 52
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantNamespaceUsageIssue.cs
  88. 6
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantPrivateIssue.cs
  89. 6
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantThisIssue.cs
  90. 76
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantUsingIssue.cs
  91. 6
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/StringIsNullOrEmptyIssue.cs
  92. 6
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/UseVarKeywordIssue.cs
  93. 9
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/ICodeIssueProvider.cs
  94. 2
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/RefactoringContext.cs
  95. 1
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/Script.cs
  96. 1
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Resolver/ResolveAtLocation.cs
  97. 15
      src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs
  98. 4
      src/Libraries/NRefactory/ICSharpCode.NRefactory.ConsistencyCheck/RoundtripTest.cs
  99. 32
      src/Libraries/NRefactory/ICSharpCode.NRefactory.ConsistencyCheck/Xml/IncrementalXmlParserTests.cs
  100. 7
      src/Libraries/NRefactory/ICSharpCode.NRefactory.GtkDemo/gtk-gui/ICSharpCode.NRefactory.GtkDemo.MainWindow.cs
  101. Some files were not shown because too many files have changed in this diff Show More

5
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
@ -420,7 +420,8 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis @@ -420,7 +420,8 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis
falseEnd = ifElseStatement.FalseStatement.AcceptVisitor(this, falseBegin);
}
ControlFlowNode end = builder.CreateEndNode(ifElseStatement);
Connect(trueEnd, end);
if (trueEnd != null)
Connect(trueEnd, end);
if (falseEnd != null) {
Connect(falseEnd, end);
} else if (cond != true) {

108
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstNode.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
//
//
// AstNode.cs
//
// Author:
@ -366,6 +366,13 @@ namespace ICSharpCode.NRefactory.CSharp @@ -366,6 +366,13 @@ namespace ICSharpCode.NRefactory.CSharp
lastChild = child;
}
}
public void InsertChildsBefore<T>(AstNode nextSibling, Role<T> role, params T[] child) where T : AstNode
{
foreach (var cur in child) {
InsertChildBefore(nextSibling, cur, role);
}
}
public void InsertChildBefore<T> (AstNode nextSibling, T child, Role<T> role) where T : AstNode
{
@ -606,7 +613,6 @@ namespace ICSharpCode.NRefactory.CSharp @@ -606,7 +613,6 @@ namespace ICSharpCode.NRefactory.CSharp
return Parent.GetPrevNode ();
return null;
}
// filters all non c# nodes (comments, white spaces or pre processor directives)
public AstNode GetCSharpNodeBefore (AstNode node)
{
@ -619,11 +625,22 @@ namespace ICSharpCode.NRefactory.CSharp @@ -619,11 +625,22 @@ namespace ICSharpCode.NRefactory.CSharp
return null;
}
#region GetNodeAt
/// <summary>
/// Gets the node specified by T at the location line, column. This is useful for getting a specific node from the tree. For example searching
/// the current method declaration.
/// (End exclusive)
/// </summary>
public AstNode GetNodeAt (int line, int column, Predicate<AstNode> pred = null)
{
return GetNodeAt (new TextLocation (line, column), pred);
}
/// <summary>
/// Gets the node specified by pred at location. This is useful for getting a specific node from the tree. For example searching
/// the current method declaration.
/// (End exclusive)
/// </summary>
public AstNode GetNodeAt (TextLocation location, Predicate<AstNode> pred = null)
{
AstNode result = null;
@ -646,6 +663,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -646,6 +663,11 @@ namespace ICSharpCode.NRefactory.CSharp
return result;
}
/// <summary>
/// Gets the node specified by T at the location line, column. This is useful for getting a specific node from the tree. For example searching
/// the current method declaration.
/// (End exclusive)
/// </summary>
public T GetNodeAt<T> (int line, int column) where T : AstNode
{
return GetNodeAt<T> (new TextLocation (line, column));
@ -654,6 +676,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -654,6 +676,7 @@ namespace ICSharpCode.NRefactory.CSharp
/// <summary>
/// Gets the node specified by T at location. This is useful for getting a specific node from the tree. For example searching
/// the current method declaration.
/// (End exclusive)
/// </summary>
public T GetNodeAt<T> (TextLocation location) where T : AstNode
{
@ -676,7 +699,86 @@ namespace ICSharpCode.NRefactory.CSharp @@ -676,7 +699,86 @@ namespace ICSharpCode.NRefactory.CSharp
}
return result;
}
#endregion
#region GetAdjacentNodeAt
/// <summary>
/// Gets the node specified by pred at the location line, column. This is useful for getting a specific node from the tree. For example searching
/// the current method declaration.
/// (End inclusive)
/// </summary>
public AstNode GetAdjacentNodeAt(int line, int column, Predicate<AstNode> pred = null)
{
return GetAdjacentNodeAt (new TextLocation (line, column), pred);
}
/// <summary>
/// Gets the node specified by pred at location. This is useful for getting a specific node from the tree. For example searching
/// the current method declaration.
/// (End inclusive)
/// </summary>
public AstNode GetAdjacentNodeAt (TextLocation location, Predicate<AstNode> pred = null)
{
AstNode result = null;
AstNode node = this;
while (node.FirstChild != null) {
var child = node.FirstChild;
while (child != null) {
if (child.StartLocation <= location && location <= child.EndLocation) {
if (pred == null || pred (child))
result = child;
node = child;
break;
}
child = child.NextSibling;
}
// found no better child node - therefore the parent is the right one.
if (child == null)
break;
}
return result;
}
/// <summary>
/// Gets the node specified by T at the location line, column. This is useful for getting a specific node from the tree. For example searching
/// the current method declaration.
/// (End inclusive)
/// </summary>
public T GetAdjacentNodeAt<T>(int line, int column) where T : AstNode
{
return GetAdjacentNodeAt<T> (new TextLocation (line, column));
}
/// <summary>
/// Gets the node specified by T at location. This is useful for getting a specific node from the tree. For example searching
/// the current method declaration.
/// (End inclusive)
/// </summary>
public T GetAdjacentNodeAt<T> (TextLocation location) where T : AstNode
{
T result = null;
AstNode node = this;
while (node.FirstChild != null) {
var child = node.FirstChild;
while (child != null) {
if (child.StartLocation <= location && location < child.EndLocation) {
if (child is T)
result = (T)child;
node = child;
break;
}
child = child.NextSibling;
}
// found no better child node - therefore the parent is the right one.
if (child == null)
break;
}
return result;
}
#endregion
/// <summary>
/// Gets the node that fully contains the range from startLocation to endLocation.
/// </summary>
@ -729,7 +831,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -729,7 +831,7 @@ namespace ICSharpCode.NRefactory.CSharp
if (IsNull)
return "";
var w = new StringWriter ();
AcceptVisitor (new CSharpOutputVisitor (w, formattingOptions ?? new CSharpFormattingOptions ()));
AcceptVisitor (new CSharpOutputVisitor (w, formattingOptions ?? FormattingOptionsFactory.CreateMono ()));
return w.ToString ();
}

51
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/DepthFirstAstVisitor.cs

@ -49,11 +49,26 @@ namespace ICSharpCode.NRefactory.CSharp @@ -49,11 +49,26 @@ namespace ICSharpCode.NRefactory.CSharp
VisitChildren (unit);
}
public virtual void VisitComment (Comment comment)
public virtual void VisitComment(Comment comment)
{
VisitChildren (comment);
VisitChildren(comment);
}
public virtual void VisitNewLine(NewLineNode newLineNode)
{
VisitChildren(newLineNode);
}
public virtual void VisitWhitespace(WhitespaceNode whitespaceNode)
{
VisitChildren(whitespaceNode);
}
public virtual void VisitText(TextNode textNode)
{
VisitChildren(textNode);
}
public virtual void VisitDocumentationReference (DocumentationReference documentationReference)
{
VisitChildren (documentationReference);
@ -637,6 +652,21 @@ namespace ICSharpCode.NRefactory.CSharp @@ -637,6 +652,21 @@ namespace ICSharpCode.NRefactory.CSharp
return VisitChildren (comment);
}
public virtual T VisitNewLine(NewLineNode newLineNode)
{
return VisitChildren(newLineNode);
}
public virtual T VisitWhitespace(WhitespaceNode whitespaceNode)
{
return VisitChildren(whitespaceNode);
}
public virtual T VisitText(TextNode textNode)
{
return VisitChildren(textNode);
}
public virtual T VisitDocumentationReference (DocumentationReference documentationReference)
{
return VisitChildren (documentationReference);
@ -1220,6 +1250,21 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1220,6 +1250,21 @@ namespace ICSharpCode.NRefactory.CSharp
return VisitChildren (comment, data);
}
public virtual S VisitNewLine(NewLineNode newLineNode, T data)
{
return VisitChildren(newLineNode, data);
}
public virtual S VisitWhitespace(WhitespaceNode whitespaceNode, T data)
{
return VisitChildren(whitespaceNode, data);
}
public virtual S VisitText(TextNode textNode, T data)
{
return VisitChildren(textNode, data);
}
public virtual S VisitDocumentationReference (DocumentationReference documentationReference, T data)
{
return VisitChildren (documentationReference, data);

132
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/NewLineNode.cs

@ -0,0 +1,132 @@ @@ -0,0 +1,132 @@
using System;
namespace ICSharpCode.NRefactory.CSharp
{
public enum NewLineType {
Unix,
Windows,
Mac
}
/// <summary>
/// A New line node represents a line break in the text.
/// </summary>
public abstract class NewLineNode : AstNode
{
public override NodeType NodeType {
get {
return NodeType.Whitespace;
}
}
public abstract NewLineType NewLineType {
get;
}
TextLocation startLocation;
public override TextLocation StartLocation {
get {
return startLocation;
}
}
public override TextLocation EndLocation {
get {
return new TextLocation (startLocation.Line + 1, 1);
}
}
public NewLineNode() : this (TextLocation.Empty)
{
}
public NewLineNode(TextLocation startLocation)
{
this.startLocation = startLocation;
}
public override void AcceptVisitor(IAstVisitor visitor)
{
visitor.VisitNewLine (this);
}
public override T AcceptVisitor<T>(IAstVisitor<T> visitor)
{
return visitor.VisitNewLine (this);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitNewLine (this, data);
}
}
public class UnixNewLine : NewLineNode
{
public override NewLineType NewLineType {
get {
return NewLineType.Unix;
}
}
public UnixNewLine()
{
}
public UnixNewLine(TextLocation startLocation) : base (startLocation)
{
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
var o = other as UnixNewLine;
return o != null;
}
}
public class WindowsNewLine : NewLineNode
{
public override NewLineType NewLineType {
get {
return NewLineType.Windows;
}
}
public WindowsNewLine()
{
}
public WindowsNewLine(TextLocation startLocation) : base (startLocation)
{
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
var o = other as WindowsNewLine;
return o != null;
}
}
public class MacNewLine : NewLineNode
{
public override NewLineType NewLineType {
get {
return NewLineType.Mac;
}
}
public MacNewLine()
{
}
public MacNewLine(TextLocation startLocation) : base (startLocation)
{
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
var o = other as MacNewLine;
return o != null;
}
}
}

94
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/TextNode.cs

@ -0,0 +1,94 @@ @@ -0,0 +1,94 @@
//
// TextNode.cs
//
// Author:
// Mike Krüger <mkrueger@xamarin.com>
//
// Copyright (c) 2012 Xamarin Inc. (http://xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
namespace ICSharpCode.NRefactory.CSharp
{
/// <summary>
/// A text node contains text without syntactic or semantic information.
/// (non parseable part of a text)
/// </summary>
public class TextNode : AstNode
{
public override NodeType NodeType {
get {
return NodeType.Whitespace;
}
}
public string Text {
get;
set;
}
TextLocation startLocation;
public override TextLocation StartLocation {
get {
return startLocation;
}
}
TextLocation endLocation;
public override TextLocation EndLocation {
get {
return endLocation;
}
}
public TextNode(string text) : this (text, TextLocation.Empty, TextLocation.Empty)
{
}
public TextNode(string text, TextLocation startLocation, TextLocation endLocation)
{
this.Text = text;
this.startLocation = startLocation;
this.endLocation = endLocation;
}
public override void AcceptVisitor(IAstVisitor visitor)
{
visitor.VisitText (this);
}
public override T AcceptVisitor<T>(IAstVisitor<T> visitor)
{
return visitor.VisitText (this);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitText (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
var o = other as TextNode;
return o != null && o.Text == Text;
}
}
}

91
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/WhitespaceNode.cs

@ -0,0 +1,91 @@ @@ -0,0 +1,91 @@
//
// WhitespaceNode.cs
//
// Author:
// Mike Krüger <mkrueger@xamarin.com>
//
// Copyright (c) 2012 Xamarin Inc. (http://xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
namespace ICSharpCode.NRefactory.CSharp
{
/// <summary>
/// A Whitespace node contains only whitespaces.
/// </summary>
public class WhitespaceNode : AstNode
{
public override NodeType NodeType {
get {
return NodeType.Whitespace;
}
}
public string WhiteSpaceText {
get;
set;
}
TextLocation startLocation;
public override TextLocation StartLocation {
get {
return startLocation;
}
}
public override TextLocation EndLocation {
get {
return new TextLocation (startLocation.Line, startLocation.Column + WhiteSpaceText.Length);
}
}
public WhitespaceNode(string whiteSpaceText) : this (whiteSpaceText, TextLocation.Empty)
{
}
public WhitespaceNode(string whiteSpaceText, TextLocation startLocation)
{
this.WhiteSpaceText = WhiteSpaceText;
this.startLocation = startLocation;
}
public override void AcceptVisitor(IAstVisitor visitor)
{
visitor.VisitWhitespace (this);
}
public override T AcceptVisitor<T>(IAstVisitor<T> visitor)
{
return visitor.VisitWhitespace (this);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitWhitespace (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
var o = other as WhitespaceNode;
return o != null && o.WhiteSpaceText == WhiteSpaceText;
}
}
}

9
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/IAstVisitor.cs

@ -137,6 +137,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -137,6 +137,9 @@ namespace ICSharpCode.NRefactory.CSharp
void VisitPrimitiveType(PrimitiveType primitiveType);
void VisitComment(Comment comment);
void VisitNewLine(NewLineNode newLineNode);
void VisitWhitespace(WhitespaceNode whitespaceNode);
void VisitText(TextNode textNode);
void VisitPreProcessorDirective(PreProcessorDirective preProcessorDirective);
void VisitDocumentationReference(DocumentationReference documentationReference);
@ -265,6 +268,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -265,6 +268,9 @@ namespace ICSharpCode.NRefactory.CSharp
S VisitPrimitiveType(PrimitiveType primitiveType);
S VisitComment(Comment comment);
S VisitWhitespace(WhitespaceNode whitespaceNode);
S VisitText(TextNode textNode);
S VisitNewLine(NewLineNode newLineNode);
S VisitPreProcessorDirective(PreProcessorDirective preProcessorDirective);
S VisitDocumentationReference(DocumentationReference documentationReference);
@ -393,6 +399,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -393,6 +399,9 @@ namespace ICSharpCode.NRefactory.CSharp
S VisitPrimitiveType(PrimitiveType primitiveType, T data);
S VisitComment(Comment comment, T data);
S VisitNewLine(NewLineNode newLineNode, T data);
S VisitWhitespace(WhitespaceNode whitespaceNode, T data);
S VisitText(TextNode textNode, T data);
S VisitPreProcessorDirective(PreProcessorDirective preProcessorDirective, T data);
S VisitDocumentationReference(DocumentationReference documentationReference, T data);

33
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/ObservableAstVisitor.cs

@ -60,9 +60,38 @@ namespace ICSharpCode.NRefactory.CSharp @@ -60,9 +60,38 @@ namespace ICSharpCode.NRefactory.CSharp
handler (comment, data);
return VisitChildren (comment, data);
}
public event Action<PreProcessorDirective, T> PreProcessorDirectiveVisited;
public event Action<NewLineNode, T> NewLineVisited;
S IAstVisitor<T, S>.VisitNewLine(NewLineNode newLineNode, T data)
{
var handler = NewLineVisited;
if (handler != null)
handler(newLineNode, data);
return VisitChildren(newLineNode, data);
}
public event Action<WhitespaceNode, T> WhitespaceVisited;
S IAstVisitor<T, S>.VisitWhitespace(WhitespaceNode whitespace, T data)
{
var handler = WhitespaceVisited;
if (handler != null)
handler(whitespace, data);
return VisitChildren(whitespace, data);
}
public event Action<TextNode, T> TextVisited;
S IAstVisitor<T, S>.VisitText(TextNode textNode, T data)
{
var handler = TextVisited;
if (handler != null)
handler(textNode, data);
return VisitChildren(textNode, data);
}
public event Action<PreProcessorDirective, T> PreProcessorDirectiveVisited;
S IAstVisitor<T, S>.VisitPreProcessorDirective (PreProcessorDirective preProcessorDirective, T data)
{
var handler = PreProcessorDirectiveVisited;

3
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Roles.cs

@ -68,6 +68,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -68,6 +68,9 @@ namespace ICSharpCode.NRefactory.CSharp
public static readonly TokenRole Colon = new TokenRole (":");
public static readonly TokenRole DoubleColon = new TokenRole ("::");
public static readonly Role<Comment> Comment = new Role<Comment> ("Comment");
public static readonly Role<NewLineNode> NewLine = new Role<NewLineNode> ("NewLine");
public static readonly Role<WhitespaceNode> Whitespace = new Role<WhitespaceNode> ("Whitespace");
public static readonly Role<TextNode> Text = new Role<TextNode> ("Text");
public static readonly Role<PreProcessorDirective> PreProcessorDirective = new Role<PreProcessorDirective> ("PreProcessorDirective");
public static readonly Role<ErrorNode> Error = new Role<ErrorNode> ("Error");

7
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/ParameterDeclaration.cs

@ -121,10 +121,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -121,10 +121,11 @@ namespace ICSharpCode.NRefactory.CSharp
{
}
public ParameterDeclaration(AstType type, string name)
public ParameterDeclaration(AstType type, string name, ParameterModifier modifier = ParameterModifier.None)
{
this.Type = type;
this.Name = name;
Type = type;
Name = name;
ParameterModifier = modifier;
}
}
}

407
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
//
//
// CSharpCompletionEngine.cs
//
// Author:
@ -68,7 +68,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -68,7 +68,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
this.document = document;
this.factory = factory;
// Set defaults for additional input properties
this.FormattingPolicy = new CSharpFormattingOptions ();
this.FormattingPolicy = FormattingOptionsFactory.CreateMono ();
this.EolMarker = Environment.NewLine;
this.IndentString = "\t";
}
@ -207,26 +207,55 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -207,26 +207,55 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return CreateCompletionData(location, resolveResult.Item1, expr.Node, resolveResult.Item2);
}
bool IsInPreprocessorDirective()
{
var text = GetMemberTextToCaret().Item1;
var miniLexer = new MiniLexer(text);
miniLexer.Parse();
return miniLexer.IsInPreprocessorDirective;
}
IEnumerable<ICompletionData> HandleObjectInitializer(CompilationUnit unit, AstNode n)
{
var p = n.Parent;
while (p != null && !(p is ObjectCreateExpression)) {
p = p.Parent;
}
if (p != null) {
var contextList = new CompletionDataWrapper(this);
var initializerResult = ResolveExpression(p, unit);
if (initializerResult != null && initializerResult.Item1.Type.Kind != TypeKind.Unknown) {
foreach (var m in initializerResult.Item1.Type.GetMembers (m => m.IsPublic && (m.EntityType == EntityType.Property || m.EntityType == EntityType.Field))) {
contextList.AddMember(m);
}
var enumerableType = typeof(IEnumerable<>).ToTypeReference().Resolve(ctx);
// check if we may be in a collection initializer, or enumerable initializer
if (enumerableType.Kind == TypeKind.Unknown || !initializerResult.Item1.Type.GetDefinition().IsDerivedFrom(enumerableType.GetDefinition())) {
return contextList.Result;
}
}
}
return null;
}
IEnumerable<ICompletionData> MagicKeyCompletion(char completionChar, bool controlSpace)
{
ExpressionResult expr;
Tuple<ResolveResult, CSharpResolver> resolveResult;
switch (completionChar) {
// Magic key completion
case ':':
case '.':
if (IsInsideCommentOrString()) {
if (IsInsideCommentStringOrDirective()) {
return Enumerable.Empty<ICompletionData>();
}
return HandleMemberReferenceCompletion(GetExpressionBeforeCursor());
case '#':
if (IsInsideCommentOrString()) {
if (!IsInPreprocessorDirective())
return null;
}
return GetDirectiveCompletionData();
// XML doc completion
// XML doc completion
case '<':
if (IsInsideDocComment()) {
return GetXmlDocumentationCompletionData();
@ -265,11 +294,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -265,11 +294,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
// Parameter completion
case '(':
if (IsInsideCommentOrString()) {
if (IsInsideCommentStringOrDirective()) {
return null;
}
var invoke = GetInvocationBeforeCursor(true);
if (invoke == null) {
if (controlSpace)
return DefaultControlSpaceItems(invoke);
return null;
}
if (invoke.Node is TypeOfExpression) {
@ -287,7 +318,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -287,7 +318,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
if (controlSpace) {
return DefaultControlSpaceItems(invoke);
}
return null;
case '=':
return controlSpace ? DefaultControlSpaceItems() : null;
@ -303,12 +333,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -303,12 +333,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
// Completion on space:
case ' ':
if (IsInsideCommentOrString()) {
return null;
}
int tokenIndex = offset;
string token = GetPreviousToken(ref tokenIndex, false);
if (IsInsideCommentStringOrDirective()) {
if (IsInPreprocessorDirective())
return HandleKeywordCompletion(tokenIndex, token);
return null;
}
// check propose name, for context <variable name> <ctrl+space> (but only in control space context)
//IType isAsType = null;
var isAsExpression = GetExpressionAt(offset);
@ -461,8 +492,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -461,8 +492,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return null;
case ":":
if (currentMember == null) {
token = GetPreviousToken(ref tokenIndex, false);
token = GetPreviousToken(ref tokenIndex, false);
if (token == "enum")
return HandleEnumContext();
var wrapper = new CompletionDataWrapper(this);
AddTypesAndNamespaces(wrapper, GetState(), null, t => currentType != null ? !currentType.ReflectionName.Equals(t.ReflectionName) : true);
AddTypesAndNamespaces(wrapper, GetState(), null, t => currentType != null && !currentType.ReflectionName.Equals(t.ReflectionName) ? t : null);
return wrapper.Result;
}
return null;
@ -475,7 +511,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -475,7 +511,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return keywordCompletion;
// Automatic completion
default:
if (IsInsideCommentOrString()) {
if (IsInsideCommentStringOrDirective()) {
return null;
}
if (IsInLinqContext(offset)) {
@ -565,7 +601,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -565,7 +601,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return null;
}
if (identifierStart == null && !string.IsNullOrEmpty(token) && !IsInsideCommentOrString() && (prevToken2 == ";" || prevToken2 == "{" || prevToken2 == "}")) {
if (identifierStart == null && !string.IsNullOrEmpty(token) && !IsInsideCommentStringOrDirective() && (prevToken2 == ";" || prevToken2 == "{" || prevToken2 == "}")) {
char last = token [token.Length - 1];
if (char.IsLetterOrDigit(last) || last == '_' || token == ">") {
return HandleKeywordCompletion(tokenIndex, token);
@ -599,24 +635,9 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -599,24 +635,9 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
// Handle object/enumerable initialzer expressions: "new O () { P$"
if (n is IdentifierExpression && n.Parent is ArrayInitializerExpression) {
var p = n.Parent;
while (p != null && !(p is ObjectCreateExpression)) {
p = p.Parent;
}
if (p != null) {
var initializerResult = ResolveExpression(p, identifierStart.Unit);
if (initializerResult != null && initializerResult.Item1.Type.Kind != TypeKind.Unknown) {
foreach (var m in initializerResult.Item1.Type.GetMembers (m => m.IsPublic && (m.EntityType == EntityType.Property || m.EntityType == EntityType.Field))) {
contextList.AddMember(m);
}
var enumerableType = typeof(IEnumerable<>).ToTypeReference().Resolve(ctx);
// check if we may be in a collection initializer, or enumerable initializer
if (enumerableType.Kind == TypeKind.Unknown || !initializerResult.Item1.Type.GetDefinition().IsDerivedFrom(enumerableType.GetDefinition())) {
return contextList.Result;
}
}
}
var result = HandleObjectInitializer(identifierStart.Unit, n);
if (result != null)
return result;
}
if (n != null && n.Parent is InvocationExpression) {
@ -845,13 +866,26 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -845,13 +866,26 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
return null;
}
string[] validEnumBaseTypes = { "byte", "sbyte", "short", "int", "long", "ushort", "uint", "ulong" };
IEnumerable<ICompletionData> HandleEnumContext()
{
var cu = ParseStub("a", false);
if (cu == null) {
return null;
}
var curType = cu.GetNodeAt<TypeDeclaration> (location);
if (curType == null || curType.ClassType != ClassType.Enum) {
cu = ParseStub("a {}", false);
var node = cu.GetNodeAt<AstType>(location);
if (node != null) {
var wrapper = new CompletionDataWrapper(this);
AddKeywords(wrapper, validEnumBaseTypes);
return wrapper.Result;
}
}
var member = cu.GetNodeAt<EnumMemberDeclaration>(location);
if (member != null && member.NameToken.EndLocation < location) {
return DefaultControlSpaceItems();
@ -862,7 +896,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -862,7 +896,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
bool IsInLinqContext(int offset)
{
string token;
while (null != (token = GetPreviousToken (ref offset, true)) && !IsInsideCommentOrString ()) {
while (null != (token = GetPreviousToken (ref offset, true)) && !IsInsideCommentStringOrDirective ()) {
if (token == "from") {
return true;
}
@ -880,7 +914,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -880,7 +914,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
if (node is Accessor) {
node = node.Parent;
}
var contextList = new CompletionDataWrapper (this);
var contextList = new CompletionDataWrapper(this);
if (node is PropertyDeclaration) {
contextList.AddCustom("get");
contextList.AddCustom("set");
@ -897,7 +931,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -897,7 +931,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
IEnumerable<ICompletionData> DefaultControlSpaceItems(ExpressionResult xp = null, bool controlSpace = true)
{
var wrapper = new CompletionDataWrapper (this);
var wrapper = new CompletionDataWrapper(this);
if (offset >= document.TextLength) {
offset = document.TextLength - 1;
}
@ -917,10 +951,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -917,10 +951,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
rr = ResolveExpression(node, xp.Unit);
unit = xp.Unit;
} else {
unit = ParseStub("a");
unit = ParseStub("a", false);
node = unit.GetNodeAt(location);
rr = ResolveExpression(node, unit);
}
if (node is Identifier && node.Parent is ForeachStatement) {
var foreachStmt = (ForeachStatement)node.Parent;
foreach (var possibleName in GenerateNameProposals (foreachStmt.VariableType)) {
@ -933,7 +968,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -933,7 +968,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
AutoCompleteEmptyMatch = false;
return wrapper.Result;
}
if (node is Identifier && node.Parent is ParameterDeclaration) {
if (!controlSpace) {
return null;
@ -959,6 +994,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -959,6 +994,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return wrapper.Result;
}
}
var initializer = node != null ? node.Parent as ArrayInitializerExpression : null;
if (initializer != null) {
var result = HandleObjectInitializer(unit, initializer);
if (result != null)
return result;
}
CSharpResolver csResolver = null;
if (rr != null) {
csResolver = rr.Item2;
@ -1010,11 +1052,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1010,11 +1052,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
}
Predicate<IType> typePred = null;
Func<IType, IType> typePred = null;
if (IsAttributeContext(node)) {
var attribute = Compilation.FindType(KnownTypeCode.Attribute);
typePred = t => {
return t.GetAllBaseTypeDefinitions().Any(bt => bt.Equals(attribute));
return t.GetAllBaseTypeDefinitions().Any(bt => bt.Equals(attribute)) ? t : null;
};
}
AddTypesAndNamespaces(wrapper, state, node, typePred);
@ -1088,18 +1130,22 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1088,18 +1130,22 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return false;
}
void AddTypesAndNamespaces(CompletionDataWrapper wrapper, CSharpResolver state, AstNode node, Predicate<IType> typePred = null, Predicate<IMember> memberPred = null)
void AddTypesAndNamespaces(CompletionDataWrapper wrapper, CSharpResolver state, AstNode node, Func<IType, IType> typePred = null, Predicate<IMember> memberPred = null)
{
if (currentType != null) {
for (var ct = currentType; ct != null; ct = ct.DeclaringTypeDefinition) {
foreach (var nestedType in ct.NestedTypes) {
if (typePred == null || typePred(nestedType.Resolve(ctx))) {
string name = nestedType.Name;
if (IsAttributeContext(node) && name.EndsWith("Attribute") && name.Length > "Attribute".Length) {
name = name.Substring(0, name.Length - "Attribute".Length);
}
string name = nestedType.Name;
if (IsAttributeContext(node) && name.EndsWith("Attribute") && name.Length > "Attribute".Length)
name = name.Substring(0, name.Length - "Attribute".Length);
if (typePred == null) {
wrapper.AddType(nestedType, name);
continue;
}
wrapper.AddType(typePred(nestedType.Resolve(ctx)), name);
continue;
}
}
if (this.currentMember != null && !(node is AstType)) {
@ -1142,19 +1188,21 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1142,19 +1188,21 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
foreach (var u in n.Usings) {
foreach (var type in u.Types) {
if (typePred == null || typePred(type)) {
IType addType = typePred != null ? typePred(type) : type;
if (addType != null) {
string name = type.Name;
if (IsAttributeContext(node) && name.EndsWith("Attribute") && name.Length > "Attribute".Length) {
name = name.Substring(0, name.Length - "Attribute".Length);
}
wrapper.AddType(type, name);
wrapper.AddType(addType, name);
}
}
}
foreach (var type in n.Namespace.Types) {
if (typePred == null || typePred(type)) {
wrapper.AddType(type, type.Name);
IType addType = typePred != null ? typePred(type) : type;
if (addType != null) {
wrapper.AddType(addType, addType.Name);
}
}
@ -1166,7 +1214,14 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1166,7 +1214,14 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
IEnumerable<ICompletionData> HandleKeywordCompletion(int wordStart, string word)
{
if (IsInsideCommentOrString()) {
if (IsInsideCommentStringOrDirective()) {
if (IsInPreprocessorDirective()) {
if (word == "if" || word == "elif") {
if (wordStart > 0 && document.GetCharAt(wordStart - 1) == '#') {
return factory.CreatePreProcessorDefinesCompletionData();
}
}
}
return null;
}
switch (word) {
@ -1176,7 +1231,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1176,7 +1231,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return null;
}
var wrapper = new CompletionDataWrapper(this);
AddTypesAndNamespaces(wrapper, GetState(), null, t => false);
AddTypesAndNamespaces(wrapper, GetState(), null, t => null);
return wrapper.Result;
case "case":
return CreateCaseCompletionData(location);
@ -1260,7 +1315,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1260,7 +1315,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
var isAsWrapper = new CompletionDataWrapper(this);
var def = isAsType != null ? isAsType.GetDefinition() : null;
AddTypesAndNamespaces(isAsWrapper, GetState(), null, t => t.GetDefinition() == null || def == null || t.GetDefinition().IsDerivedFrom(def), m => false);
AddTypesAndNamespaces(isAsWrapper, GetState(), null, t => t.GetDefinition() == null || def == null || t.GetDefinition().IsDerivedFrom(def) ? t : null, m => false);
return isAsWrapper.Result;
// {
// CompletionDataList completionList = new ProjectDomCompletionDataList ();
@ -1466,31 +1521,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1466,31 +1521,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
return CreateTypeCompletionData(hintType, hintTypeAst);
// IType callingType = NRefactoryResolver.GetTypeAtCursor (Document.CompilationUnit, Document.FileName, new TextLocation (document.Caret.Line, document.Caret.Column));
// ExpressionContext newExactContext = new NewCSharpExpressionFinder (dom).FindExactContextForNewCompletion (document, Document.CompilationUnit, Document.FileName, callingType);
// if (newExactContext is ExpressionContext.TypeExpressionContext)
// return CreateTypeCompletionData (location, callingType, newExactContext, ((ExpressionContext.TypeExpressionContext)newExactContext).Type, ((ExpressionContext.TypeExpressionContext)newExactContext).UnresolvedType);
// if (newExactContext == null) {
// int j = offset - 4;
//
// string yieldToken = GetPreviousToken (ref j, true);
// if (token == "return") {
// NRefactoryResolver resolver = CreateResolver ();
// resolver.SetupResolver (new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
// IReturnType returnType = resolver.CallingMember.ReturnType;
// if (yieldToken == "yield" && returnType.GenericArguments.Count > 0)
// returnType = returnType.GenericArguments [0];
// if (resolver.CallingMember != null)
// return CreateTypeCompletionData (location, callingType, newExactContext, null, returnType);
// }
// }
// return CreateCtrlSpaceCompletionData (completionContext, null);
case "if":
case "elif":
if (wordStart > 0 && document.GetCharAt(wordStart - 1) == '#') {
return factory.CreatePreProcessorDefinesCompletionData();
}
return null;
case "yield":
var yieldDataList = new CompletionDataWrapper(this);
DefaultCompletionString = "return";
@ -1505,38 +1535,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1505,38 +1535,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
AddContextCompletion(inList, rr != null ? rr.Item2 : GetState(), expr.Node, Unit);
return inList.Result;
// case "where":
// CompletionDataList whereDataList = new CompletionDataList ();
// NRefactoryResolver constraintResolver = CreateResolver ();
// constraintResolver.SetupResolver (new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
// if (constraintResolver.CallingMember is IMethod) {
// foreach (ITypeParameter tp in ((IMethod)constraintResolver.CallingMember).TypeParameters) {
// whereDataList.Add (tp.Name, "md-keyword");
// }
// } else {
// if (constraintResolver.CallingType != null) {
// foreach (ITypeParameter tp in constraintResolver.CallingType.TypeParameters) {
// whereDataList.Add (tp.Name, "md-keyword");
// }
// }
// }
//
// return whereDataList;
}
// if (IsInLinqContext (result)) {
// if (linqKeywords.Contains (word)) {
// if (word == "from") // after from no auto code completion.
// return null;
// result.Expression = "";
// return CreateCtrlSpaceCompletionData (completionContext, result);
// }
// CompletionDataList dataList = new ProjectDomCompletionDataList ();
// CompletionDataCollector col = new CompletionDataCollector (this, dom, dataList, Document.CompilationUnit, null, new TextLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset));
// foreach (string kw in linqKeywords) {
// col.Add (kw, "md-keyword");
// }
// return dataList;
// }
}
return null;
}
@ -1563,42 +1562,55 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1563,42 +1562,55 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
return "";
}
static CSharpAmbience amb = new CSharpAmbience ();
IEnumerable<ICompletionData> CreateTypeCompletionData(IType hintType, AstType hintTypeAst)
{
var wrapper = new CompletionDataWrapper (this);
var wrapper = new CompletionDataWrapper(this);
var state = GetState();
Predicate<IType> pred = null;
Func<IType, IType> pred = null;
if (hintType != null) {
if (hintType.Kind != TypeKind.Unknown) {
var lookup = new MemberLookup (ctx.CurrentTypeDefinition, Compilation.MainAssembly);
var lookup = new MemberLookup(ctx.CurrentTypeDefinition, Compilation.MainAssembly);
pred = t => {
// check if type is in inheritance tree.
if (hintType.GetDefinition() != null && !t.GetDefinition().IsDerivedFrom(hintType.GetDefinition())) {
return false;
return null;
}
if (t.Kind == TypeKind.Interface && hintType.Kind != TypeKind.Array) {
return false;
return null;
}
// check for valid constructors
if (t.GetConstructors().Count() == 0) {
return true;
if (t.GetConstructors().Count() > 0) {
bool isProtectedAllowed = currentType != null ? currentType.Resolve(ctx).GetDefinition().IsDerivedFrom(t.GetDefinition()) : false;
if (!t.GetConstructors().Any(m => lookup.IsAccessible(m, isProtectedAllowed)))
return null;
}
bool isProtectedAllowed = currentType != null ? currentType.Resolve(ctx).GetDefinition().IsDerivedFrom(t.GetDefinition()) : false;
return t.GetConstructors().Any(m => lookup.IsAccessible(m, isProtectedAllowed));
var typeInference = new TypeInference(Compilation);
typeInference.Algorithm = TypeInferenceAlgorithm.ImprovedReturnAllResults;
var inferedType = typeInference.FindTypeInBounds(new [] { t }, new [] { hintType });
wrapper.AddType(inferedType, amb.ConvertType(inferedType));
return null;
};
if (!(hintType.Kind == TypeKind.Interface && hintType.Kind != TypeKind.Array)) {
DefaultCompletionString = GetShortType(hintType, GetState());
wrapper.AddType(hintType, DefaultCompletionString);
}
if (hintType is ParameterizedType && hintType.TypeParameterCount == 1 && hintType.FullName == "System.Collections.Generic.IEnumerable") {
var arg = ((ParameterizedType)hintType).TypeArguments.FirstOrDefault();
var array = new ArrayTypeReference(arg.ToTypeReference(), 1).Resolve(ctx);
wrapper.AddType(array, amb.ConvertType(array));
}
} else {
DefaultCompletionString = hintTypeAst.ToString();
wrapper.AddType(hintType, DefaultCompletionString);
}
}
AddTypesAndNamespaces(wrapper, state, null, pred, m => false);
AddKeywords(wrapper, primitiveTypesKeywords.Where(k => k != "void"));
if (hintType == null || hintType == SpecialType.UnknownType)
AddKeywords(wrapper, primitiveTypesKeywords.Where(k => k != "void"));
CloseOnSquareBrackets = true;
AutoCompleteEmptyMatch = true;
return wrapper.Result;
@ -1712,7 +1724,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1712,7 +1724,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
if (alreadyInserted.Any(cm => SignatureComparer.Ordinal.Equals(cm, m)))
continue;
alreadyInserted.Add (m);
data.CompletionCategory = col.GetCompletionCategory(curType);
data.CompletionCategory = col.GetCompletionCategory(m.DeclaringTypeDefinition);
col.Add(data);
}
}
@ -1942,9 +1954,9 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1942,9 +1954,9 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
IEnumerable<ICompletionData> CreateParameterCompletion(MethodGroupResolveResult resolveResult, CSharpResolver state, AstNode invocation, CompilationUnit unit, int parameter, bool controlSpace)
{
var result = new CompletionDataWrapper (this);
var addedEnums = new HashSet<string> ();
var addedDelegates = new HashSet<string> ();
var result = new CompletionDataWrapper(this);
var addedEnums = new HashSet<string>();
var addedDelegates = new HashSet<string>();
foreach (var method in resolveResult.Methods) {
if (method.Parameters.Count <= parameter) {
@ -1958,13 +1970,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1958,13 +1970,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
addedEnums.Add(resolvedType.ReflectionName);
AddEnumMembers(result, resolvedType, state);
} else if (resolvedType.Kind == TypeKind.Delegate) {
// if (addedDelegates.Contains (resolvedType.DecoratedFullName))
// continue;
// addedDelegates.Add (resolvedType.DecoratedFullName);
// string parameterDefinition = AddDelegateHandlers (completionList, resolvedType, false, addedDelegates.Count == 1);
// string varName = "Handle" + method.Parameters [parameter].ReturnType.Name + method.Parameters [parameter].Name;
// result.Add (new EventCreationCompletionData (document, varName, resolvedType, null, parameterDefinition, resolver.Unit.GetMemberAt (location), resolvedType) { AddSemicolon = false });
if (addedDelegates.Contains(resolvedType.ReflectionName))
continue;
string parameterDefinition = AddDelegateHandlers(result, resolvedType);
string varName = "Handle" + method.Parameters [parameter].Type.Name + method.Parameters [parameter].Name;
result.Result.Add(factory.CreateEventCreationCompletionData(varName, resolvedType, null, parameterDefinition, currentMember, currentType));
}
}
if (!controlSpace) {
@ -2515,132 +2525,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -2515,132 +2525,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return document.GetText(i, endOffset - i);
}
bool GetParameterCompletionCommandOffset(out int cpos)
{
// Start calculating the parameter offset from the beginning of the
// current member, instead of the beginning of the file.
cpos = offset - 1;
var mem = currentMember;
if (mem == null || (mem is IType)) {
return false;
}
int startPos = document.GetOffset(mem.Region.BeginLine, mem.Region.BeginColumn);
int parenDepth = 0;
int chevronDepth = 0;
while (cpos > startPos) {
char c = document.GetCharAt(cpos);
if (c == ')') {
parenDepth++;
}
if (c == '>') {
chevronDepth++;
}
if (parenDepth == 0 && c == '(' || chevronDepth == 0 && c == '<') {
int p = GetCurrentParameterIndex(cpos + 1, startPos);
if (p != -1) {
cpos++;
return true;
} else {
return false;
}
}
if (c == '(') {
parenDepth--;
}
if (c == '<') {
chevronDepth--;
}
cpos--;
}
return false;
}
int GetCurrentParameterIndex(int offset, int memberStart)
{
int cursor = this.offset;
int i = offset;
if (i > cursor) {
return -1;
}
if (i == cursor) {
return 1;
}
// parameters are 1 based
int index = memberStart + 1;
int parentheses = 0;
int bracket = 0;
bool insideQuote = false, insideString = false, insideSingleLineComment = false, insideMultiLineComment = false;
do {
char c = document.GetCharAt(i - 1);
switch (c) {
case '\\':
if (insideString || insideQuote) {
i++;
}
break;
case '\'':
if (!insideString && !insideSingleLineComment && !insideMultiLineComment) {
insideQuote = !insideQuote;
}
break;
case '"':
if (!insideQuote && !insideSingleLineComment && !insideMultiLineComment) {
insideString = !insideString;
}
break;
case '/':
if (!insideQuote && !insideString && !insideMultiLineComment) {
if (document.GetCharAt(i) == '/') {
insideSingleLineComment = true;
}
if (document.GetCharAt(i) == '*') {
insideMultiLineComment = true;
}
}
break;
case '*':
if (insideMultiLineComment && document.GetCharAt(i) == '/') {
insideMultiLineComment = false;
}
break;
case '\n':
case '\r':
insideSingleLineComment = false;
break;
case '{':
if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment) {
bracket++;
}
break;
case '}':
if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment) {
bracket--;
}
break;
case '(':
if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment) {
parentheses++;
}
break;
case ')':
if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment) {
parentheses--;
}
break;
case ',':
if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment && parentheses == 1 && bracket == 0) {
index++;
}
break;
}
i++;
} while (i <= cursor && parentheses >= 0);
return parentheses != 1 || bracket > 0 ? -1 : index;
}
#endregion
#region Preprocessor

286
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs

@ -100,76 +100,258 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -100,76 +100,258 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
var provider = MemberProvider ?? new DefaultMemberProvider (this);
provider.GetCurrentMembers (offset, out currentType, out currentMember);
}
protected bool GetParameterCompletionCommandOffset(out int cpos)
{
// Start calculating the parameter offset from the beginning of the
// current member, instead of the beginning of the file.
cpos = offset - 1;
var mem = currentMember;
if (mem == null || (mem is IType)) {
return false;
}
int startPos = document.GetOffset(mem.Region.BeginLine, mem.Region.BeginColumn);
int parenDepth = 0;
int chevronDepth = 0;
Stack<int> indexStack = new Stack<int>();
while (cpos > startPos) {
char c = document.GetCharAt(cpos);
if (c == ')') {
parenDepth++;
}
if (c == '>') {
chevronDepth++;
}
if (c == '}') {
if (indexStack.Count > 0) {
parenDepth = indexStack.Pop();
} else {
parenDepth = 0;
}
chevronDepth = 0;
}
if (indexStack.Count == 0 && (parenDepth == 0 && c == '(' || chevronDepth == 0 && c == '<')) {
int p = GetCurrentParameterIndex (cpos + 1, startPos);
if (p != -1) {
cpos++;
return true;
} else {
return false;
}
}
if (c == '(') {
parenDepth--;
}
if (c == '<') {
chevronDepth--;
}
if (c == '{') {
indexStack.Push (parenDepth);
chevronDepth = 0;
}
cpos--;
}
return false;
}
#region Context helper methods
protected bool IsInsideCommentOrString ()
protected int GetCurrentParameterIndex (int offset, int memberStart)
{
var text = GetMemberTextToCaret ();
bool inSingleComment = false, inString = false, inVerbatimString = false, inChar = false, inMultiLineComment = false;
int cursor = this.offset;
int i = offset;
for (int i = 0; i < text.Item1.Length - 1; i++) {
char ch = text.Item1 [i];
char nextCh = text.Item1 [i + 1];
switch (ch) {
case '/':
if (inString || inChar || inVerbatimString)
break;
if (nextCh == '/') {
if (i > cursor) {
return -1;
}
if (i == cursor) {
return 1;
}
// parameters are 1 based
int index = memberStart + 1;
int parentheses = 0;
int bracket = 0;
bool insideQuote = false, insideString = false, insideSingleLineComment = false, insideMultiLineComment = false;
Stack<int> indexStack = new Stack<int> ();
do {
char c = document.GetCharAt (i - 1);
switch (c) {
case '\\':
if (insideString || insideQuote) {
i++;
inSingleComment = true;
}
if (nextCh == '*')
inMultiLineComment = true;
break;
case '*':
if (inString || inChar || inVerbatimString || inSingleComment)
break;
if (nextCh == '/') {
i++;
inMultiLineComment = false;
case '\'':
if (!insideString && !insideSingleLineComment && !insideMultiLineComment) {
insideQuote = !insideQuote;
}
break;
case '@':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment)
break;
if (nextCh == '"') {
i++;
inVerbatimString = true;
case '"':
if (!insideQuote && !insideSingleLineComment && !insideMultiLineComment) {
insideString = !insideString;
}
break;
case '/':
if (!insideQuote && !insideString && !insideMultiLineComment) {
if (document.GetCharAt (i) == '/') {
insideSingleLineComment = true;
}
if (document.GetCharAt (i) == '*') {
insideMultiLineComment = true;
}
}
break;
case '*':
if (insideMultiLineComment && document.GetCharAt (i) == '/') {
insideMultiLineComment = false;
}
break;
case '\n':
case '\r':
inSingleComment = false;
inString = false;
inChar = false;
insideSingleLineComment = false;
break;
case '\\':
if (inString || inChar)
i++;
case '{':
if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment) {
bracket++;
indexStack.Push (index);
}
break;
case '"':
if (inSingleComment || inMultiLineComment || inChar)
break;
if (inVerbatimString) {
if (nextCh == '"') {
i++;
break;
}
inVerbatimString = false;
break;
case '}':
if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment) {
bracket--;
if (indexStack.Count > 0)
index = indexStack.Pop ();
}
inString = !inString;
break;
case '\'':
if (inSingleComment || inMultiLineComment || inString || inVerbatimString)
break;
inChar = !inChar;
case '(':
if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment) {
parentheses++;
}
break;
case ')':
if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment) {
parentheses--;
}
break;
case ',':
if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment && parentheses == 1 && bracket == 0) {
index++;
}
break;
}
i++;
} while (i <= cursor && parentheses >= 0);
Console.WriteLine (indexStack.Count >= 0 || parentheses != 1 || bracket > 0 ? -1 : index);
return indexStack.Count >= 0 || parentheses != 1 || bracket > 0 ? -1 : index;
}
#region Context helper methods
public class MiniLexer
{
readonly string text;
public bool IsFistNonWs = true;
public bool IsInSingleComment = false;
public bool IsInString = false;
public bool IsInVerbatimString = false;
public bool IsInChar = false;
public bool IsInMultiLineComment = false;
public bool IsInPreprocessorDirective = false;
public MiniLexer(string text)
{
this.text = text;
}
public void Parse(Action<char> act = null)
{
Parse(0, text.Length, act);
}
public void Parse(int start, int length, Action<char> act = null)
{
for (int i = start; i < length; i++) {
char ch = text [i];
char nextCh = i + 1 < text.Length ? text [i + 1] : '\0';
switch (ch) {
case '#':
if (IsFistNonWs)
IsInPreprocessorDirective = true;
break;
case '/':
if (IsInString || IsInChar || IsInVerbatimString)
break;
if (nextCh == '/') {
i++;
IsInSingleComment = true;
}
if (nextCh == '*')
IsInMultiLineComment = true;
break;
case '*':
if (IsInString || IsInChar || IsInVerbatimString || IsInSingleComment)
break;
if (nextCh == '/') {
i++;
IsInMultiLineComment = false;
}
break;
case '@':
if (IsInString || IsInChar || IsInVerbatimString || IsInSingleComment || IsInMultiLineComment)
break;
if (nextCh == '"') {
i++;
IsInVerbatimString = true;
}
break;
case '\n':
case '\r':
IsInSingleComment = false;
IsInString = false;
IsInChar = false;
IsFistNonWs = true;
break;
case '\\':
if (IsInString || IsInChar)
i++;
break;
case '"':
if (IsInSingleComment || IsInMultiLineComment || IsInChar)
break;
if (IsInVerbatimString) {
if (nextCh == '"') {
i++;
break;
}
IsInVerbatimString = false;
break;
}
IsInString = !IsInString;
break;
case '\'':
if (IsInSingleComment || IsInMultiLineComment || IsInString || IsInVerbatimString)
break;
IsInChar = !IsInChar;
break;
}
if (act != null)
act(ch);
IsFistNonWs &= ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r';
}
}
return inSingleComment || inString || inVerbatimString || inChar || inMultiLineComment;
}
protected bool IsInsideCommentStringOrDirective()
{
var text = GetMemberTextToCaret();
var lexer = new MiniLexer(text.Item1);
lexer.Parse();
return
lexer.IsInSingleComment ||
lexer.IsInString ||
lexer.IsInVerbatimString ||
lexer.IsInChar ||
lexer.IsInMultiLineComment ||
lexer.IsInPreprocessorDirective;
}
protected bool IsInsideDocComment ()
@ -439,7 +621,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -439,7 +621,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
AppendMissingClosingBrackets(wrapper, memberText, appendSemicolon);
wrapper.Append(afterContinuation);
if (closingBrackets > 0) {
wrapper.Append(new string ('}', closingBrackets));
wrapper.Append(new string('}', closingBrackets));
}
using (var stream = new System.IO.StringReader (wrapper.ToString ())) {
try {

74
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
//
//
// CSharpParameterCompletionEngine.cs
//
// Author:
@ -105,6 +105,8 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -105,6 +105,8 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
//var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin;
var expr = baseUnit.GetNodeAt<AstType>(location.Line, location.Column + 1);
if (expr == null)
return null;
// '>' position
return new ExpressionResult((AstNode)expr, baseUnit);
}
@ -146,7 +148,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -146,7 +148,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
SetOffset(offset);
if (IsInsideCommentOrString()) {
if (IsInsideCommentStringOrDirective()) {
return null;
}
@ -171,6 +173,8 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -171,6 +173,8 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
if (invoke.Node is ObjectCreateExpression) {
var createType = ResolveExpression(((ObjectCreateExpression)invoke.Node).Type, invoke.Unit);
if (createType.Item1.Type.Kind == TypeKind.Unknown)
return null;
return factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), createType.Item1.Type);
}
@ -217,6 +221,8 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -217,6 +221,8 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
if (invoke == null) {
invoke = GetTypeBeforeCursor();
if (invoke != null) {
if (GetCurrentParameterIndex(document.GetOffset(invoke.Node.StartLocation), offset) < 0)
return null;
var typeExpression = ResolveExpression(invoke);
if (typeExpression == null || typeExpression.Item1 == null || typeExpression.Item1.IsError) {
return null;
@ -226,6 +232,8 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -226,6 +232,8 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
return null;
}
if (GetCurrentParameterIndex(document.GetOffset(invoke.Node.StartLocation), offset) < 0)
return null;
if (invoke.Node is ObjectCreateExpression) {
var createType = ResolveExpression(((ObjectCreateExpression)invoke.Node).Type, invoke.Unit);
return factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), createType.Item1.Type);
@ -334,17 +342,37 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -334,17 +342,37 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return 0;
}
var parameter = new Stack<int>();
var bracketStack = new Stack<Stack<int>>();
bool inSingleComment = false, inString = false, inVerbatimString = false, inChar = false, inMultiLineComment = false;
for (int i = triggerOffset; i < endOffset; i++) {
char ch = document.GetCharAt(i);
char nextCh = i + 1 < document.TextLength ? document.GetCharAt(i + 1) : '\0';
switch (ch) {
case '{':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
bracketStack.Push(parameter);
parameter = new Stack<int>();
break;
case '[':
case '(':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
parameter.Push(0);
break;
case '}':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
if (bracketStack.Count > 0) {
parameter = bracketStack.Pop();
} else {
return -1;
}
break;
case ']':
case ')':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
@ -440,51 +468,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -440,51 +468,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
break;
}
}
if (parameter.Count == 0) {
if (parameter.Count == 0 || bracketStack.Count > 0) {
return -1;
}
return parameter.Pop() + 1;
}
/*
public override bool GetParameterCompletionCommandOffset (out int cpos)
{
// Start calculating the parameter offset from the beginning of the
// current member, instead of the beginning of the file.
cpos = textEditorData.Caret.Offset - 1;
var parsedDocument = Document.ParsedDocument;
if (parsedDocument == null)
return false;
IMember mem = currentMember;
if (mem == null || (mem is IType))
return false;
int startPos = textEditorData.LocationToOffset (mem.Region.BeginLine, mem.Region.BeginColumn);
int parenDepth = 0;
int chevronDepth = 0;
while (cpos > startPos) {
char c = textEditorData.GetCharAt (cpos);
if (c == ')')
parenDepth++;
if (c == '>')
chevronDepth++;
if (parenDepth == 0 && c == '(' || chevronDepth == 0 && c == '<') {
int p = MethodParameterDataProvider.GetCurrentParameterIndex (CompletionWidget, cpos + 1, startPos);
if (p != -1) {
cpos++;
return true;
} else {
return false;
}
}
if (c == '(')
parenDepth--;
if (c == '<')
chevronDepth--;
cpos--;
}
return false;
}*/
}
}

69
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
//
//
// AstFormattingVisitor.cs
//
// Author:
@ -445,6 +445,24 @@ namespace ICSharpCode.NRefactory.CSharp @@ -445,6 +445,24 @@ namespace ICSharpCode.NRefactory.CSharp
return i;
}
int ForceSpacesBeforeRemoveNewLines(AstNode n)
{
if (n == null || n.IsNull) {
return 0;
}
int offset = document.GetOffset(n.StartLocation);
int i = offset - 1;
while (i >= 0) {
char ch = document.GetCharAt(i);
if (!IsSpacing(ch) && ch != '\r' && ch != '\n')
break;
i--;
}
var length = System.Math.Max(0, (offset - 1) - i);
AddChange(i + 1, length, " ");
return i;
}
public override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)
{
FormatAttributedNode(propertyDeclaration);
@ -870,8 +888,16 @@ namespace ICSharpCode.NRefactory.CSharp @@ -870,8 +888,16 @@ namespace ICSharpCode.NRefactory.CSharp
if (child.Role == Roles.LBrace || child.Role == Roles.RBrace) {
continue;
}
FixStatementIndentation(child.StartLocation);
child.AcceptVisitor(this);
if (child is Statement) {
FixStatementIndentation(child.StartLocation);
child.AcceptVisitor(this);
} else if (child is Comment) {
child.AcceptVisitor(this);
} else {
// pre processor directives at line start, if they are there.
if (child.StartLocation.Column > 1)
FixStatementIndentation(child.StartLocation);
}
}
if (indent) {
curIndent.Pop ();
@ -887,7 +913,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -887,7 +913,7 @@ namespace ICSharpCode.NRefactory.CSharp
public override void VisitComment(Comment comment)
{
if (comment.StartsLine && !HadErrors && comment.StartLocation.Column > 1) {
if (comment.StartsLine && !HadErrors && (!policy.KeepCommentsAtFirstColumn || comment.StartLocation.Column > 1)) {
FixIndentation(comment.StartLocation);
}
}
@ -1404,18 +1430,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1404,18 +1430,11 @@ namespace ICSharpCode.NRefactory.CSharp
}
var lastLoc = variableDeclarationStatement.StartLocation;
foreach (var initializer in variableDeclarationStatement.Variables) {
var indent = !(initializer.Initializer is AnonymousMethodExpression);
if (indent) {
curIndent.Push(IndentType.Block);
}
if (lastLoc.Line != initializer.StartLocation.Line) {
FixStatementIndentation(initializer.StartLocation);
lastLoc = initializer.StartLocation;
}
initializer.AcceptVisitor(this);
if (indent) {
curIndent.Pop ();
}
}
FormatCommas(variableDeclarationStatement, policy.SpaceBeforeLocalVariableDeclarationComma, policy.SpaceAfterLocalVariableDeclarationComma);
@ -1673,6 +1692,28 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1673,6 +1692,28 @@ namespace ICSharpCode.NRefactory.CSharp
base.VisitArrayCreateExpression(arrayObjectCreateExpression);
}
public override void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression)
{
if (policy.ArrayInitializerWrapping == Wrapping.WrapAlways) {
EnforceBraceStyle(policy.ArrayInitializerBraceStyle, arrayInitializerExpression.LBraceToken, arrayInitializerExpression.RBraceToken);
curIndent.Push(IndentType.Block);
foreach (var init in arrayInitializerExpression.Elements) {
FixStatementIndentation(init.StartLocation);
init.AcceptVisitor(this);
}
curIndent.Pop();
} else if (policy.ArrayInitializerWrapping == Wrapping.DoNotWrap) {
ForceSpacesBeforeRemoveNewLines(arrayInitializerExpression.LBraceToken);
ForceSpacesBeforeRemoveNewLines(arrayInitializerExpression.RBraceToken);
foreach (var init in arrayInitializerExpression.Elements) {
ForceSpacesBeforeRemoveNewLines(init);
init.AcceptVisitor(this);
}
} else {
base.VisitArrayInitializerExpression(arrayInitializerExpression);
}
}
public override void VisitLambdaExpression(LambdaExpression lambdaExpression)
{
ForceSpacesAfter(lambdaExpression.ArrowToken, true);
@ -1681,6 +1722,12 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1681,6 +1722,12 @@ namespace ICSharpCode.NRefactory.CSharp
base.VisitLambdaExpression(lambdaExpression);
}
public override void VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression)
{
ForceSpacesAfter(namedArgumentExpression.ColonToken, policy.SpaceInNamedArgumentAfterDoubleColon);
base.VisitNamedArgumentExpression(namedArgumentExpression);
}
#endregion
void ForceSpaceBefore(int offset, bool forceSpace)

159
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/CSharpFormattingOptions.cs

@ -48,12 +48,6 @@ namespace ICSharpCode.NRefactory.CSharp @@ -48,12 +48,6 @@ namespace ICSharpCode.NRefactory.CSharp
AddBraces
}
public enum ArrayInitializerPlacement
{
AlwaysNewLine,
AlwaysSameLine
}
public enum PropertyFormatting
{
AllowOneLine,
@ -61,6 +55,12 @@ namespace ICSharpCode.NRefactory.CSharp @@ -61,6 +55,12 @@ namespace ICSharpCode.NRefactory.CSharp
ForceNewLine
}
public enum Wrapping {
DoNotWrap,
WrapAlways,
WrapIfTooLong
}
public class CSharpFormattingOptions
{
public string Name {
@ -322,11 +322,6 @@ namespace ICSharpCode.NRefactory.CSharp @@ -322,11 +322,6 @@ namespace ICSharpCode.NRefactory.CSharp
get;
set;
}
public ArrayInitializerPlacement PlaceArrayInitializersOnNewLine {
get;
set;
}
#endregion
#region Spaces
@ -727,6 +722,10 @@ namespace ICSharpCode.NRefactory.CSharp @@ -727,6 +722,10 @@ namespace ICSharpCode.NRefactory.CSharp
set;
}
public bool SpaceInNamedArgumentAfterDoubleColon {
get;
set;
}
#endregion
#region Blank Lines
@ -766,119 +765,31 @@ namespace ICSharpCode.NRefactory.CSharp @@ -766,119 +765,31 @@ namespace ICSharpCode.NRefactory.CSharp
}
#endregion
public CSharpFormattingOptions ()
#region Keep formatting
public bool KeepCommentsAtFirstColumn {
get;
set;
}
#endregion
#region Wrapping
public Wrapping ArrayInitializerWrapping {
get;
set;
}
public BraceStyle ArrayInitializerBraceStyle {
get;
set;
}
#endregion
internal CSharpFormattingOptions()
{
IndentNamespaceBody = true;
IndentClassBody = IndentInterfaceBody = IndentStructBody = IndentEnumBody = true;
IndentMethodBody = IndentPropertyBody = IndentEventBody = true;
IndentBlocks = true;
IndentSwitchBody = false;
IndentCaseBody = true;
IndentBreakStatements = true;
NamespaceBraceStyle = BraceStyle.NextLine;
ClassBraceStyle = InterfaceBraceStyle = StructBraceStyle = EnumBraceStyle = BraceStyle.NextLine;
MethodBraceStyle = ConstructorBraceStyle = DestructorBraceStyle = BraceStyle.NextLine;
AnonymousMethodBraceStyle = BraceStyle.EndOfLine;
PropertyBraceStyle = PropertyGetBraceStyle = PropertySetBraceStyle = BraceStyle.EndOfLine;
AllowPropertyGetBlockInline = AllowPropertySetBlockInline = true;
EventBraceStyle = EventAddBraceStyle = EventRemoveBraceStyle = BraceStyle.EndOfLine;
AllowEventAddBlockInline = AllowEventRemoveBlockInline = true;
StatementBraceStyle = BraceStyle.EndOfLine;
PlaceElseOnNewLine = false;
PlaceCatchOnNewLine = false;
PlaceFinallyOnNewLine = false;
PlaceWhileOnNewLine = false;
PlaceArrayInitializersOnNewLine = ArrayInitializerPlacement.AlwaysSameLine;
SpaceBeforeMethodCallParentheses = true;
SpaceBeforeMethodDeclarationParentheses = true;
SpaceBeforeConstructorDeclarationParentheses = true;
SpaceBeforeDelegateDeclarationParentheses = true;
SpaceAfterMethodCallParameterComma = true;
SpaceAfterConstructorDeclarationParameterComma = true;
SpaceBeforeNewParentheses = true;
SpacesWithinNewParentheses = false;
SpacesBetweenEmptyNewParentheses = false;
SpaceBeforeNewParameterComma = false;
SpaceAfterNewParameterComma = true;
SpaceBeforeIfParentheses = true;
SpaceBeforeWhileParentheses = true;
SpaceBeforeForParentheses = true;
SpaceBeforeForeachParentheses = true;
SpaceBeforeCatchParentheses = true;
SpaceBeforeSwitchParentheses = true;
SpaceBeforeLockParentheses = true;
SpaceBeforeUsingParentheses = true;
SpaceAroundAssignment = true;
SpaceAroundLogicalOperator = true;
SpaceAroundEqualityOperator = true;
SpaceAroundRelationalOperator = true;
SpaceAroundBitwiseOperator = true;
SpaceAroundAdditiveOperator = true;
SpaceAroundMultiplicativeOperator = true;
SpaceAroundShiftOperator = true;
SpaceAroundNullCoalescingOperator = true;
SpacesWithinParentheses = false;
SpaceWithinMethodCallParentheses = false;
SpaceWithinMethodDeclarationParentheses = false;
SpacesWithinIfParentheses = false;
SpacesWithinWhileParentheses = false;
SpacesWithinForParentheses = false;
SpacesWithinForeachParentheses = false;
SpacesWithinCatchParentheses = false;
SpacesWithinSwitchParentheses = false;
SpacesWithinLockParentheses = false;
SpacesWithinUsingParentheses = false;
SpacesWithinCastParentheses = false;
SpacesWithinSizeOfParentheses = false;
SpacesWithinTypeOfParentheses = false;
SpacesWithinCheckedExpressionParantheses = false;
SpaceBeforeConditionalOperatorCondition = true;
SpaceAfterConditionalOperatorCondition = true;
SpaceBeforeConditionalOperatorSeparator = true;
SpaceAfterConditionalOperatorSeparator = true;
SpacesWithinBrackets = false;
SpacesBeforeBrackets = true;
SpaceBeforeBracketComma = false;
SpaceAfterBracketComma = true;
SpaceBeforeForSemicolon = false;
SpaceAfterForSemicolon = true;
SpaceAfterTypecast = false;
AlignEmbeddedIfStatements = true;
AlignEmbeddedUsingStatements = true;
PropertyFormatting = PropertyFormatting.AllowOneLine;
SpaceBeforeMethodDeclarationParameterComma = false;
SpaceAfterMethodDeclarationParameterComma = true;
SpaceBeforeFieldDeclarationComma = false;
SpaceAfterFieldDeclarationComma = true;
SpaceBeforeLocalVariableDeclarationComma = false;
SpaceAfterLocalVariableDeclarationComma = true;
SpaceBeforeIndexerDeclarationBracket = true;
SpaceWithinIndexerDeclarationBracket = false;
SpaceBeforeIndexerDeclarationParameterComma = false;
SpaceAfterIndexerDeclarationParameterComma = true;
BlankLinesBeforeUsings = 0;
BlankLinesAfterUsings = 1;
BlankLinesBeforeFirstDeclaration = 0;
BlankLinesBetweenTypes = 1;
BlankLinesBetweenFields = 0;
BlankLinesBetweenEventFields = 0;
BlankLinesBetweenMembers = 1;
}
/*public static CSharpFormattingOptions Load (FilePath selectedFile)
@ -890,7 +801,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -890,7 +801,7 @@ namespace ICSharpCode.NRefactory.CSharp
public static CSharpFormattingOptions Load (System.IO.Stream input)
{
CSharpFormattingOptions result = new CSharpFormattingOptions ();
CSharpFormattingOptions result = FormattingOptionsFactory.CreateMonoOptions ();
result.Name = "noname";
using (XmlTextReader reader = new XmlTextReader (input)) {
while (reader.Read ()) {

339
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingOptionsFactory.cs

@ -0,0 +1,339 @@ @@ -0,0 +1,339 @@
//
// FormattingOptionsFactory.cs
//
// Author:
// Mike Krüger <mkrueger@xamarin.com>
//
// Copyright (c) 2012 Xamarin Inc. (http://xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
namespace ICSharpCode.NRefactory.CSharp
{
/// <summary>
/// The formatting options factory creates pre defined formatting option styles.
/// </summary>
public static class FormattingOptionsFactory
{
/// <summary>
/// Creates empty CSharpFormatting options.
/// </summary>
public static CSharpFormattingOptions CreateEmpty()
{
return new CSharpFormattingOptions();
}
/// <summary>
/// Creates mono indent style CSharpFormatting options.
/// </summary>
public static CSharpFormattingOptions CreateMono()
{
return new CSharpFormattingOptions() {
IndentNamespaceBody = true,
IndentClassBody = true,
IndentInterfaceBody = true,
IndentStructBody = true,
IndentEnumBody = true,
IndentMethodBody = true,
IndentPropertyBody = true,
IndentEventBody = true,
IndentBlocks = true,
IndentSwitchBody = false,
IndentCaseBody = true,
IndentBreakStatements = true,
NamespaceBraceStyle = BraceStyle.NextLine,
ClassBraceStyle = BraceStyle.NextLine,
InterfaceBraceStyle = BraceStyle.NextLine,
StructBraceStyle = BraceStyle.NextLine,
EnumBraceStyle = BraceStyle.NextLine,
MethodBraceStyle = BraceStyle.NextLine,
ConstructorBraceStyle = BraceStyle.NextLine,
DestructorBraceStyle = BraceStyle.NextLine,
AnonymousMethodBraceStyle = BraceStyle.EndOfLine,
PropertyBraceStyle = BraceStyle.EndOfLine,
PropertyGetBraceStyle = BraceStyle.EndOfLine,
PropertySetBraceStyle = BraceStyle.EndOfLine,
AllowPropertyGetBlockInline = true,
AllowPropertySetBlockInline = true,
EventBraceStyle = BraceStyle.EndOfLine,
EventAddBraceStyle = BraceStyle.EndOfLine,
EventRemoveBraceStyle = BraceStyle.EndOfLine,
AllowEventAddBlockInline = true,
AllowEventRemoveBlockInline = true,
StatementBraceStyle = BraceStyle.EndOfLine,
PlaceElseOnNewLine = false,
PlaceCatchOnNewLine = false,
PlaceFinallyOnNewLine = false,
PlaceWhileOnNewLine = false,
ArrayInitializerWrapping = Wrapping.WrapIfTooLong,
ArrayInitializerBraceStyle = BraceStyle.EndOfLine,
SpaceBeforeMethodCallParentheses = true,
SpaceBeforeMethodDeclarationParentheses = true,
SpaceBeforeConstructorDeclarationParentheses = true,
SpaceBeforeDelegateDeclarationParentheses = true,
SpaceAfterMethodCallParameterComma = true,
SpaceAfterConstructorDeclarationParameterComma = true,
SpaceBeforeNewParentheses = true,
SpacesWithinNewParentheses = false,
SpacesBetweenEmptyNewParentheses = false,
SpaceBeforeNewParameterComma = false,
SpaceAfterNewParameterComma = true,
SpaceBeforeIfParentheses = true,
SpaceBeforeWhileParentheses = true,
SpaceBeforeForParentheses = true,
SpaceBeforeForeachParentheses = true,
SpaceBeforeCatchParentheses = true,
SpaceBeforeSwitchParentheses = true,
SpaceBeforeLockParentheses = true,
SpaceBeforeUsingParentheses = true,
SpaceAroundAssignment = true,
SpaceAroundLogicalOperator = true,
SpaceAroundEqualityOperator = true,
SpaceAroundRelationalOperator = true,
SpaceAroundBitwiseOperator = true,
SpaceAroundAdditiveOperator = true,
SpaceAroundMultiplicativeOperator = true,
SpaceAroundShiftOperator = true,
SpaceAroundNullCoalescingOperator = true,
SpacesWithinParentheses = false,
SpaceWithinMethodCallParentheses = false,
SpaceWithinMethodDeclarationParentheses = false,
SpacesWithinIfParentheses = false,
SpacesWithinWhileParentheses = false,
SpacesWithinForParentheses = false,
SpacesWithinForeachParentheses = false,
SpacesWithinCatchParentheses = false,
SpacesWithinSwitchParentheses = false,
SpacesWithinLockParentheses = false,
SpacesWithinUsingParentheses = false,
SpacesWithinCastParentheses = false,
SpacesWithinSizeOfParentheses = false,
SpacesWithinTypeOfParentheses = false,
SpacesWithinCheckedExpressionParantheses = false,
SpaceBeforeConditionalOperatorCondition = true,
SpaceAfterConditionalOperatorCondition = true,
SpaceBeforeConditionalOperatorSeparator = true,
SpaceAfterConditionalOperatorSeparator = true,
SpacesWithinBrackets = false,
SpacesBeforeBrackets = true,
SpaceBeforeBracketComma = false,
SpaceAfterBracketComma = true,
SpaceBeforeForSemicolon = false,
SpaceAfterForSemicolon = true,
SpaceAfterTypecast = false,
AlignEmbeddedIfStatements = true,
AlignEmbeddedUsingStatements = true,
PropertyFormatting = PropertyFormatting.AllowOneLine,
SpaceBeforeMethodDeclarationParameterComma = false,
SpaceAfterMethodDeclarationParameterComma = true,
SpaceBeforeFieldDeclarationComma = false,
SpaceAfterFieldDeclarationComma = true,
SpaceBeforeLocalVariableDeclarationComma = false,
SpaceAfterLocalVariableDeclarationComma = true,
SpaceBeforeIndexerDeclarationBracket = true,
SpaceWithinIndexerDeclarationBracket = false,
SpaceBeforeIndexerDeclarationParameterComma = false,
SpaceInNamedArgumentAfterDoubleColon = true,
SpaceAfterIndexerDeclarationParameterComma = true,
BlankLinesBeforeUsings = 0,
BlankLinesAfterUsings = 1,
BlankLinesBeforeFirstDeclaration = 0,
BlankLinesBetweenTypes = 1,
BlankLinesBetweenFields = 0,
BlankLinesBetweenEventFields = 0,
BlankLinesBetweenMembers = 1,
KeepCommentsAtFirstColumn = true,
};
}
/// <summary>
/// Creates sharp develop indent style CSharpFormatting options.
/// </summary>
public static CSharpFormattingOptions CreateSharpDevelop()
{
return new CSharpFormattingOptions() {
IndentNamespaceBody = true,
IndentClassBody = true,
IndentInterfaceBody = true,
IndentStructBody = true,
IndentEnumBody = true,
IndentMethodBody = true,
IndentPropertyBody = true,
IndentEventBody = true,
IndentBlocks = true,
IndentSwitchBody = true,
IndentCaseBody = true,
IndentBreakStatements = true,
NamespaceBraceStyle = BraceStyle.NextLine,
ClassBraceStyle = BraceStyle.NextLine,
InterfaceBraceStyle = BraceStyle.NextLine,
StructBraceStyle = BraceStyle.NextLine,
EnumBraceStyle = BraceStyle.NextLine,
MethodBraceStyle = BraceStyle.NextLine,
ConstructorBraceStyle = BraceStyle.NextLine,
DestructorBraceStyle = BraceStyle.NextLine,
AnonymousMethodBraceStyle = BraceStyle.EndOfLine,
PropertyBraceStyle = BraceStyle.EndOfLine,
PropertyGetBraceStyle = BraceStyle.EndOfLine,
PropertySetBraceStyle = BraceStyle.EndOfLine,
AllowPropertyGetBlockInline = true,
AllowPropertySetBlockInline = true,
EventBraceStyle = BraceStyle.EndOfLine,
EventAddBraceStyle = BraceStyle.EndOfLine,
EventRemoveBraceStyle = BraceStyle.EndOfLine,
AllowEventAddBlockInline = true,
AllowEventRemoveBlockInline = true,
StatementBraceStyle = BraceStyle.EndOfLine,
PlaceElseOnNewLine = false,
PlaceCatchOnNewLine = false,
PlaceFinallyOnNewLine = false,
PlaceWhileOnNewLine = false,
ArrayInitializerWrapping = Wrapping.WrapIfTooLong,
ArrayInitializerBraceStyle = BraceStyle.EndOfLine,
SpaceBeforeMethodCallParentheses = false,
SpaceBeforeMethodDeclarationParentheses = false,
SpaceBeforeConstructorDeclarationParentheses = false,
SpaceBeforeDelegateDeclarationParentheses = false,
SpaceAfterMethodCallParameterComma = true,
SpaceAfterConstructorDeclarationParameterComma = true,
SpaceBeforeNewParentheses = false,
SpacesWithinNewParentheses = false,
SpacesBetweenEmptyNewParentheses = false,
SpaceBeforeNewParameterComma = false,
SpaceAfterNewParameterComma = true,
SpaceBeforeIfParentheses = true,
SpaceBeforeWhileParentheses = true,
SpaceBeforeForParentheses = true,
SpaceBeforeForeachParentheses = true,
SpaceBeforeCatchParentheses = true,
SpaceBeforeSwitchParentheses = true,
SpaceBeforeLockParentheses = true,
SpaceBeforeUsingParentheses = true,
SpaceAroundAssignment = true,
SpaceAroundLogicalOperator = true,
SpaceAroundEqualityOperator = true,
SpaceAroundRelationalOperator = true,
SpaceAroundBitwiseOperator = true,
SpaceAroundAdditiveOperator = true,
SpaceAroundMultiplicativeOperator = true,
SpaceAroundShiftOperator = true,
SpaceAroundNullCoalescingOperator = true,
SpacesWithinParentheses = false,
SpaceWithinMethodCallParentheses = false,
SpaceWithinMethodDeclarationParentheses = false,
SpacesWithinIfParentheses = false,
SpacesWithinWhileParentheses = false,
SpacesWithinForParentheses = false,
SpacesWithinForeachParentheses = false,
SpacesWithinCatchParentheses = false,
SpacesWithinSwitchParentheses = false,
SpacesWithinLockParentheses = false,
SpacesWithinUsingParentheses = false,
SpacesWithinCastParentheses = false,
SpacesWithinSizeOfParentheses = false,
SpacesWithinTypeOfParentheses = false,
SpacesWithinCheckedExpressionParantheses = false,
SpaceBeforeConditionalOperatorCondition = true,
SpaceAfterConditionalOperatorCondition = true,
SpaceBeforeConditionalOperatorSeparator = true,
SpaceAfterConditionalOperatorSeparator = true,
SpacesWithinBrackets = false,
SpacesBeforeBrackets = true,
SpaceBeforeBracketComma = false,
SpaceAfterBracketComma = true,
SpaceBeforeForSemicolon = false,
SpaceAfterForSemicolon = true,
SpaceAfterTypecast = false,
AlignEmbeddedIfStatements = true,
AlignEmbeddedUsingStatements = true,
PropertyFormatting = PropertyFormatting.AllowOneLine,
SpaceBeforeMethodDeclarationParameterComma = false,
SpaceAfterMethodDeclarationParameterComma = true,
SpaceBeforeFieldDeclarationComma = false,
SpaceAfterFieldDeclarationComma = true,
SpaceBeforeLocalVariableDeclarationComma = false,
SpaceAfterLocalVariableDeclarationComma = true,
SpaceBeforeIndexerDeclarationBracket = true,
SpaceWithinIndexerDeclarationBracket = false,
SpaceBeforeIndexerDeclarationParameterComma = false,
SpaceInNamedArgumentAfterDoubleColon = true,
SpaceAfterIndexerDeclarationParameterComma = true,
BlankLinesBeforeUsings = 0,
BlankLinesAfterUsings = 1,
BlankLinesBeforeFirstDeclaration = 0,
BlankLinesBetweenTypes = 1,
BlankLinesBetweenFields = 0,
BlankLinesBetweenEventFields = 0,
BlankLinesBetweenMembers = 1,
KeepCommentsAtFirstColumn = true,
};
}
/// <summary>
/// Creates allman indent style CSharpFormatting options used in Visual Studio.
/// </summary>
public static CSharpFormattingOptions CreateAllman()
{
var baseOptions = CreateSharpDevelop();
baseOptions.AnonymousMethodBraceStyle = BraceStyle.EndOfLine;
baseOptions.PropertyBraceStyle = BraceStyle.EndOfLine;
baseOptions.PropertyGetBraceStyle = BraceStyle.EndOfLine;
baseOptions.PropertySetBraceStyle = BraceStyle.EndOfLine;
baseOptions.EventBraceStyle = BraceStyle.EndOfLine;
baseOptions.EventAddBraceStyle = BraceStyle.EndOfLine;
baseOptions.EventRemoveBraceStyle = BraceStyle.EndOfLine;
baseOptions.StatementBraceStyle = BraceStyle.EndOfLine;
baseOptions.ArrayInitializerBraceStyle = BraceStyle.EndOfLine;
return baseOptions;
}
}
}

216
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/GeneratedCodeSettings.cs

@ -0,0 +1,216 @@ @@ -0,0 +1,216 @@
//
// GeneratedCodeSettings.cs
//
// Author:
// Mike Krüger <mkrueger@xamarin.com>
//
// Copyright (c) 2012 Xamarin Inc. (http://xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections.Generic;
namespace ICSharpCode.NRefactory.CSharp
{
public enum GeneratedCodeMember
{
Unknown,
StaticFields,
InstanceFields,
StaticProperties,
InstanceProperties,
Indexer,
Constructors,
StaticMethods,
InstanceMethods,
StaticEvents,
InstanceEvents,
Operators,
NestedTypes
}
public class GeneratedCodeSettings
{
List<GeneratedCodeMember> codeMemberOrder;
public List<GeneratedCodeMember> CodeMemberOrder {
get {
return codeMemberOrder;
}
set {
codeMemberOrder = value;
}
}
public bool GenerateCategoryComments {
get;
set;
}
public bool SubOrderAlphabetical {
get;
set;
}
public void Apply (AstNode rootNode)
{
if (rootNode == null)
throw new ArgumentNullException ("rootNode");
rootNode.AcceptVisitor (new GenerateCodeVisitior (this));
}
public virtual string GetCategoryLabel(GeneratedCodeMember memberCategory)
{
switch (memberCategory) {
case GeneratedCodeMember.StaticFields:
return "Static Fields";
case GeneratedCodeMember.InstanceFields:
return "Fields";
case GeneratedCodeMember.StaticProperties:
return "Static Properties";
case GeneratedCodeMember.InstanceProperties:
return "Properties";
case GeneratedCodeMember.Indexer:
return "Indexer";
case GeneratedCodeMember.Constructors:
return "Constructors";
case GeneratedCodeMember.StaticMethods:
return "Static Methods";
case GeneratedCodeMember.InstanceMethods:
return "Methods";
case GeneratedCodeMember.StaticEvents:
return "Static Events";
case GeneratedCodeMember.InstanceEvents:
return "Events";
case GeneratedCodeMember.Operators:
return "Operators";
case GeneratedCodeMember.NestedTypes:
return "Nested Types";
}
return null;
}
class GenerateCodeVisitior : DepthFirstAstVisitor
{
GeneratedCodeSettings settings;
public GenerateCodeVisitior(GeneratedCodeSettings settings)
{
if (settings == null)
throw new ArgumentNullException("settings");
this.settings = settings;
}
GeneratedCodeMember GetCodeMemberCategory(EntityDeclaration x)
{
bool isStatic = x.HasModifier(Modifiers.Static) || x.HasModifier(Modifiers.Const);
if (x is FieldDeclaration)
return isStatic ? GeneratedCodeMember.StaticFields : GeneratedCodeMember.InstanceFields;
if (x is IndexerDeclaration)
return GeneratedCodeMember.Indexer;
if (x is PropertyDeclaration)
return isStatic ? GeneratedCodeMember.StaticProperties : GeneratedCodeMember.InstanceProperties;
if (x is ConstructorDeclaration || x is DestructorDeclaration)
return GeneratedCodeMember.Constructors;
if (x is MethodDeclaration)
return isStatic ? GeneratedCodeMember.StaticMethods : GeneratedCodeMember.InstanceMethods;
if (x is OperatorDeclaration)
return GeneratedCodeMember.Operators;
if (x is EventDeclaration || x is CustomEventDeclaration)
return isStatic ? GeneratedCodeMember.StaticEvents : GeneratedCodeMember.InstanceEvents;
if (x is TypeDeclaration)
return GeneratedCodeMember.NestedTypes;
return GeneratedCodeMember.Unknown;
}
public override void VisitTypeDeclaration (TypeDeclaration typeDeclaration)
{
if (typeDeclaration.ClassType == ClassType.Enum)
return;
var entities = new List<EntityDeclaration> (typeDeclaration.Members);
entities.Sort ((x, y) => {
int i1 = settings.CodeMemberOrder.IndexOf (GetCodeMemberCategory (x));
int i2 = settings.CodeMemberOrder.IndexOf (GetCodeMemberCategory (y));
if (i1 != i2)
return i1.CompareTo (i2);
if (settings.SubOrderAlphabetical)
return (x.Name ?? "").CompareTo ((y.Name ?? ""));
return entities.IndexOf (x).CompareTo (entities.IndexOf (y));
});
typeDeclaration.Members.Clear ();
typeDeclaration.Members.AddRange (entities);
if (settings.GenerateCategoryComments) {
var curCat = GeneratedCodeMember.Unknown;
foreach (var mem in entities) {
if (mem.NextSibling is EntityDeclaration)
mem.Parent.InsertChildAfter (mem, new UnixNewLine (), Roles.NewLine);
var cat = GetCodeMemberCategory (mem);
if (cat == curCat)
continue;
curCat = cat;
var label = settings.GetCategoryLabel (curCat);
if (string.IsNullOrEmpty (label))
continue;
var cmt = new Comment ("", CommentType.SingleLine);
var cmt2 = new Comment (" " + label, CommentType.SingleLine);
var cmt3 = new Comment ("", CommentType.SingleLine);
mem.Parent.InsertChildsBefore (mem, Roles.Comment, cmt, cmt2, cmt3);
if (cmt.PrevSibling is EntityDeclaration)
mem.Parent.InsertChildBefore (cmt, new UnixNewLine (), Roles.NewLine);
mem.Parent.InsertChildAfter (cmt3, new UnixNewLine (), Roles.NewLine);
}
}
}
}
static Lazy<GeneratedCodeSettings> defaultSettings = new Lazy<GeneratedCodeSettings>(
() => new GeneratedCodeSettings() {
CodeMemberOrder = new List<GeneratedCodeMember>() {
GeneratedCodeMember.StaticFields,
GeneratedCodeMember.InstanceFields,
GeneratedCodeMember.StaticProperties,
GeneratedCodeMember.InstanceProperties,
GeneratedCodeMember.Indexer,
GeneratedCodeMember.Constructors,
GeneratedCodeMember.StaticMethods,
GeneratedCodeMember.InstanceMethods,
GeneratedCodeMember.StaticEvents,
GeneratedCodeMember.InstanceEvents,
GeneratedCodeMember.Operators,
GeneratedCodeMember.NestedTypes
},
GenerateCategoryComments = true,
SubOrderAlphabetical = true
});
public static GeneratedCodeSettings Default {
get {
return defaultSettings.Value;
}
}
}
}

15
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj

@ -41,7 +41,8 @@ @@ -41,7 +41,8 @@
<DefineConstants>TRACE;FULL_AST</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<DebugType>PdbOnly</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugType>full</DebugType>
@ -240,6 +241,7 @@ @@ -240,6 +241,7 @@
<Compile Include="Parser\mcs\typespec.cs" />
<Compile Include="Parser\mcs\visit.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Refactoring\CodeIssues\ExplicitConversionInForEachIssue.cs" />
<Compile Include="Refactoring\DocumentScript.cs" />
<Compile Include="Refactoring\PatternHelper.cs" />
<Compile Include="Refactoring\RefactoringAstHelper.cs" />
@ -358,6 +360,16 @@ @@ -358,6 +360,16 @@
<Compile Include="Refactoring\CodeActions\CreateClassDeclarationAction.cs" />
<Compile Include="Refactoring\CodeActions\CreateDelegateAction.cs" />
<Compile Include="Formatter\TextEditorOptions.cs" />
<Compile Include="Refactoring\CodeActions\IntroduceConstantAction.cs" />
<Compile Include="Refactoring\CodeActions\ExtractMethod\ExtractMethodAction.cs" />
<Compile Include="Refactoring\CodeActions\ExtractMethod\StaticVisitor.cs" />
<Compile Include="Refactoring\CodeActions\ExtractMethod\VariableLookupVisitor.cs" />
<Compile Include="Refactoring\CodeActions\SpecializedCodeAction.cs" />
<Compile Include="Formatter\GeneratedCodeSettings.cs" />
<Compile Include="Ast\GeneralScope\NewLineNode.cs" />
<Compile Include="Ast\GeneralScope\WhitespaceNode.cs" />
<Compile Include="Ast\GeneralScope\TextNode.cs" />
<Compile Include="Formatter\FormattingOptionsFactory.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj">
@ -370,6 +382,7 @@ @@ -370,6 +382,7 @@
<Folder Include="Completion\" />
<Folder Include="Refactoring\CodeIssues\" />
<Folder Include="Refactoring\CodeIssues\InconsistentNamingIssue\" />
<Folder Include="Refactoring\CodeActions\ExtractMethod\" />
</ItemGroup>
<ProjectExtensions>
<MonoDevelop>

4
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpAmbience.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
@ -38,7 +38,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -38,7 +38,7 @@ namespace ICSharpCode.NRefactory.CSharp
throw new ArgumentNullException("entity");
StringWriter writer = new StringWriter();
ConvertEntity(entity, new TextWriterOutputFormatter(writer), new CSharpFormattingOptions());
ConvertEntity(entity, new TextWriterOutputFormatter(writer), FormattingOptionsFactory.CreateMono ());
return writer.ToString();
}

34
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs

@ -111,7 +111,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -111,7 +111,7 @@ namespace ICSharpCode.NRefactory.CSharp
void WriteSpecials(AstNode start, AstNode end)
{
for (AstNode pos = start; pos != end; pos = pos.NextSibling) {
if (pos.Role == Roles.Comment || pos.Role == Roles.PreProcessorDirective) {
if (pos.Role == Roles.Comment || pos.Role == Roles.NewLine || pos.Role == Roles.PreProcessorDirective) {
pos.AcceptVisitor(this);
}
}
@ -519,6 +519,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -519,6 +519,7 @@ namespace ICSharpCode.NRefactory.CSharp
void WriteEmbeddedStatement(Statement embeddedStatement)
{
if (embeddedStatement.IsNull) {
NewLine();
return;
}
BlockStatement block = embeddedStatement as BlockStatement;
@ -659,7 +660,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -659,7 +660,7 @@ namespace ICSharpCode.NRefactory.CSharp
void PrintInitializerElements(AstNodeCollection<Expression> elements)
{
BraceStyle style;
if (policy.PlaceArrayInitializersOnNewLine == ArrayInitializerPlacement.AlwaysNewLine) {
if (policy.ArrayInitializerWrapping == Wrapping.WrapAlways) {
style = BraceStyle.NextLine;
} else {
style = BraceStyle.EndOfLine;
@ -1584,7 +1585,8 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1584,7 +1585,8 @@ namespace ICSharpCode.NRefactory.CSharp
node.AcceptVisitor(this);
}
CloseBrace(style);
NewLine();
if (!(blockStatement.Parent is Expression))
NewLine();
EndNode(blockStatement);
}
@ -1694,9 +1696,10 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1694,9 +1696,10 @@ namespace ICSharpCode.NRefactory.CSharp
forStatement.Condition.AcceptVisitor(this);
Space(policy.SpaceBeforeForSemicolon);
WriteToken(Roles.Semicolon);
Space(policy.SpaceAfterForSemicolon);
WriteCommaSeparatedList(forStatement.Iterators);
if (forStatement.Iterators.Any()) {
Space(policy.SpaceAfterForSemicolon);
WriteCommaSeparatedList(forStatement.Iterators);
}
Space(policy.SpacesWithinForParentheses);
RPar();
@ -2373,7 +2376,24 @@ namespace ICSharpCode.NRefactory.CSharp @@ -2373,7 +2376,24 @@ namespace ICSharpCode.NRefactory.CSharp
formatter.EndNode(comment);
lastWritten = LastWritten.Whitespace;
}
public void VisitNewLine(NewLineNode newLineNode)
{
formatter.StartNode(newLineNode);
formatter.NewLine();
formatter.EndNode(newLineNode);
}
public void VisitWhitespace(WhitespaceNode whitespaceNode)
{
// unused
}
public void VisitText(TextNode textNode)
{
// unused
}
public void VisitPreProcessorDirective(PreProcessorDirective preProcessorDirective)
{
formatter.StartNode(preProcessorDirective);

21
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
@ -171,7 +171,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -171,7 +171,7 @@ namespace ICSharpCode.NRefactory.CSharp
string MakeSnippet(AstNode node)
{
StringWriter w = new StringWriter();
CSharpOutputVisitor v = new CSharpOutputVisitor(w, new CSharpFormattingOptions());
CSharpOutputVisitor v = new CSharpOutputVisitor(w, FormattingOptionsFactory.CreateMono ());
node.AcceptVisitor(v);
return w.ToString();
}
@ -1244,7 +1244,22 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1244,7 +1244,22 @@ namespace ICSharpCode.NRefactory.CSharp
{
return new CodeComment (comment.Content, comment.CommentType == CommentType.Documentation);
}
CodeObject IAstVisitor<CodeObject>.VisitNewLine(NewLineNode newLineNode)
{
throw new NotSupportedException();
}
CodeObject IAstVisitor<CodeObject>.VisitWhitespace(WhitespaceNode whitespaceNode)
{
throw new NotSupportedException();
}
CodeObject IAstVisitor<CodeObject>.VisitText(TextNode textNode)
{
throw new NotSupportedException();
}
CodeObject IAstVisitor<CodeObject>.VisitPreProcessorDirective (PreProcessorDirective preProcessorDirective)
{
return new CodeComment ("#" + preProcessorDirective.Type.ToString ().ToLower ());

347
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/anonymous.cs

@ -13,6 +13,7 @@ @@ -13,6 +13,7 @@
using System;
using System.Collections.Generic;
using Mono.CompilerServices.SymbolWriter;
using System.Diagnostics;
#if STATIC
using IKVM.Reflection;
@ -25,11 +26,20 @@ using System.Reflection.Emit; @@ -25,11 +26,20 @@ using System.Reflection.Emit;
namespace Mono.CSharp {
public abstract class CompilerGeneratedClass : Class
public abstract class CompilerGeneratedContainer : ClassOrStruct
{
protected CompilerGeneratedClass (TypeContainer parent, MemberName name, Modifiers mod)
: base (parent, name, mod | Modifiers.COMPILER_GENERATED, null)
protected CompilerGeneratedContainer (TypeContainer parent, MemberName name, Modifiers mod)
: this (parent, name, mod, MemberKind.Class)
{
}
protected CompilerGeneratedContainer (TypeContainer parent, MemberName name, Modifiers mod, MemberKind kind)
: base (parent, name, null, kind)
{
Debug.Assert ((mod & Modifiers.AccessibilityMask) != 0);
ModFlags = mod | Modifiers.COMPILER_GENERATED | Modifiers.SEALED;
spec = new TypeSpec (Kind, null, this, null, ModFlags);
}
protected void CheckMembersDefined ()
@ -38,6 +48,15 @@ namespace Mono.CSharp { @@ -38,6 +48,15 @@ namespace Mono.CSharp {
throw new InternalErrorException ("Helper class already defined!");
}
protected override bool DoDefineMembers ()
{
if (Kind == MemberKind.Class && !IsStatic && !PartialContainer.HasInstanceConstructor) {
DefineDefaultConstructor (false);
}
return base.DoDefineMembers ();
}
protected static MemberName MakeMemberName (MemberBase host, string name, int unique_id, TypeParameters tparams, Location loc)
{
string host_name = host == null ? null : host is InterfaceMemberBase ? ((InterfaceMemberBase)host).GetFullName (host.MemberName) : host.MemberName.Name;
@ -59,9 +78,17 @@ namespace Mono.CSharp { @@ -59,9 +78,17 @@ namespace Mono.CSharp {
{
return "<" + host + ">" + typePrefix + "__" + name + id.ToString ("X");
}
protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
{
base_type = Compiler.BuiltinTypes.Object;
base_class = null;
return null;
}
}
public class HoistedStoreyClass : CompilerGeneratedClass
public class HoistedStoreyClass : CompilerGeneratedContainer
{
public sealed class HoistedField : Field
{
@ -86,8 +113,8 @@ namespace Mono.CSharp { @@ -86,8 +113,8 @@ namespace Mono.CSharp {
protected TypeParameterMutator mutator;
public HoistedStoreyClass (TypeDefinition parent, MemberName name, TypeParameters tparams, Modifiers mod)
: base (parent, name, mod | Modifiers.PRIVATE)
public HoistedStoreyClass (TypeDefinition parent, MemberName name, TypeParameters tparams, Modifiers mods, MemberKind kind)
: base (parent, name, mods | Modifiers.PRIVATE, kind)
{
if (tparams != null) {
@ -173,7 +200,7 @@ namespace Mono.CSharp { @@ -173,7 +200,7 @@ namespace Mono.CSharp {
protected override void DoEmit (EmitContext ec)
{
hoisted_this.EmitHoistingAssignment (ec);
hoisted_this.EmitAssign (ec, new CompilerGeneratedThis (ec.CurrentType, loc), false, false);
}
protected override void CloneTo (CloneContext clonectx, Statement target)
@ -185,7 +212,7 @@ namespace Mono.CSharp { @@ -185,7 +212,7 @@ namespace Mono.CSharp {
// Unique storey ID
public readonly int ID;
public readonly Block OriginalSourceBlock;
public readonly ExplicitBlock OriginalSourceBlock;
// A list of StoreyFieldPair with local field keeping parent storey instance
List<StoreyFieldPair> used_parent_storeys;
@ -193,6 +220,7 @@ namespace Mono.CSharp { @@ -193,6 +220,7 @@ namespace Mono.CSharp {
// A list of hoisted parameters
protected List<HoistedParameter> hoisted_params;
List<HoistedParameter> hoisted_local_params;
protected List<HoistedVariable> hoisted_locals;
// Hoisted this
@ -201,9 +229,11 @@ namespace Mono.CSharp { @@ -201,9 +229,11 @@ namespace Mono.CSharp {
// Local variable which holds this storey instance
public Expression Instance;
public AnonymousMethodStorey (Block block, TypeDefinition parent, MemberBase host, TypeParameters tparams, string name)
bool initialize_hoisted_this;
public AnonymousMethodStorey (ExplicitBlock block, TypeDefinition parent, MemberBase host, TypeParameters tparams, string name, MemberKind kind)
: base (parent, MakeMemberName (host, name, parent.Module.CounterAnonymousContainers, tparams, block.StartLocation),
tparams, Modifiers.SEALED)
tparams, 0, kind)
{
OriginalSourceBlock = block;
ID = parent.Module.CounterAnonymousContainers++;
@ -212,18 +242,10 @@ namespace Mono.CSharp { @@ -212,18 +242,10 @@ namespace Mono.CSharp {
public void AddCapturedThisField (EmitContext ec)
{
TypeExpr type_expr = new TypeExpression (ec.CurrentType, Location);
Field f = AddCompilerGeneratedField ("<>f__this", type_expr);
f.Define ();
Field f = AddCompilerGeneratedField ("$this", type_expr);
hoisted_this = new HoistedThis (this, f);
// Inflated type instance has to be updated manually
if (Instance.Type is InflatedTypeSpec) {
var inflator = new TypeParameterInflator (this, Instance.Type, TypeParameterSpec.EmptyTypes, TypeSpec.EmptyTypes);
Instance.Type.MemberCache.AddMember (f.Spec.InflateMember (inflator));
inflator = new TypeParameterInflator (this, f.Parent.CurrentType, TypeParameterSpec.EmptyTypes, TypeSpec.EmptyTypes);
f.Parent.CurrentType.MemberCache.AddMember (f.Spec.InflateMember (inflator));
}
initialize_hoisted_this = true;
}
public Field AddCapturedVariable (string name, TypeSpec type)
@ -283,38 +305,93 @@ namespace Mono.CSharp { @@ -283,38 +305,93 @@ namespace Mono.CSharp {
used_parent_storeys.Add (new StoreyFieldPair (storey, f));
}
public void CaptureLocalVariable (ResolveContext ec, LocalVariable local_info)
public void CaptureLocalVariable (ResolveContext ec, LocalVariable localVariable)
{
ec.CurrentBlock.Explicit.HasCapturedVariable = true;
if (ec.CurrentBlock.Explicit != local_info.Block.Explicit)
AddReferenceFromChildrenBlock (ec.CurrentBlock.Explicit);
if (this is StateMachine) {
if (ec.CurrentBlock.ParametersBlock != localVariable.Block.ParametersBlock)
ec.CurrentBlock.Explicit.HasCapturedVariable = true;
} else {
ec.CurrentBlock.Explicit.HasCapturedVariable = true;
}
if (local_info.HoistedVariant != null)
return;
var hoisted = localVariable.HoistedVariant;
if (hoisted != null && hoisted.Storey != this && hoisted.Storey.Kind == MemberKind.Struct) {
// TODO: It's too late the field is defined in HoistedLocalVariable ctor
hoisted.Storey.hoisted_locals.Remove (hoisted);
hoisted = null;
}
if (hoisted == null) {
hoisted = new HoistedLocalVariable (this, localVariable, GetVariableMangledName (localVariable));
localVariable.HoistedVariant = hoisted;
HoistedVariable var = new HoistedLocalVariable (this, local_info, GetVariableMangledName (local_info));
local_info.HoistedVariant = var;
if (hoisted_locals == null)
hoisted_locals = new List<HoistedVariable> ();
if (hoisted_locals == null)
hoisted_locals = new List<HoistedVariable> ();
hoisted_locals.Add (hoisted);
}
hoisted_locals.Add (var);
if (ec.CurrentBlock.Explicit != localVariable.Block.Explicit)
hoisted.Storey.AddReferenceFromChildrenBlock (ec.CurrentBlock.Explicit);
}
public void CaptureParameter (ResolveContext ec, ParameterReference param_ref)
public void CaptureParameter (ResolveContext ec, ParametersBlock.ParameterInfo parameterInfo, ParameterReference parameterReference)
{
ec.CurrentBlock.Explicit.HasCapturedVariable = true;
AddReferenceFromChildrenBlock (ec.CurrentBlock.Explicit);
if (!(this is StateMachine)) {
ec.CurrentBlock.Explicit.HasCapturedVariable = true;
}
if (param_ref.GetHoistedVariable (ec) != null)
return;
var hoisted = parameterInfo.Parameter.HoistedVariant;
if (parameterInfo.Block.StateMachine is AsyncTaskStorey) {
//
// Another storey in same block exists but state machine does not
// have parameter captured. We need to add it there as well to
// proxy parameter value correctly.
//
if (hoisted == null && parameterInfo.Block.StateMachine != this) {
var storey = parameterInfo.Block.StateMachine;
hoisted = new HoistedParameter (storey, parameterReference);
parameterInfo.Parameter.HoistedVariant = hoisted;
if (storey.hoisted_params == null)
storey.hoisted_params = new List<HoistedParameter> ();
if (hoisted_params == null)
hoisted_params = new List<HoistedParameter> (2);
storey.hoisted_params.Add (hoisted);
}
//
// Lift captured parameter from value type storey to reference type one. Otherwise
// any side effects would be done on a copy
//
if (hoisted != null && hoisted.Storey != this && hoisted.Storey.Kind == MemberKind.Struct) {
if (hoisted_local_params == null)
hoisted_local_params = new List<HoistedParameter> ();
hoisted_local_params.Add (hoisted);
hoisted = null;
}
}
if (hoisted == null) {
hoisted = new HoistedParameter (this, parameterReference);
parameterInfo.Parameter.HoistedVariant = hoisted;
var expr = new HoistedParameter (this, param_ref);
param_ref.Parameter.HoistedVariant = expr;
hoisted_params.Add (expr);
if (hoisted_params == null)
hoisted_params = new List<HoistedParameter> ();
hoisted_params.Add (hoisted);
}
//
// Register link between current block and parameter storey. It will
// be used when setting up storey definition to deploy storey reference
// when parameters are used from multiple blocks
//
if (ec.CurrentBlock.Explicit != parameterInfo.Block) {
hoisted.Storey.AddReferenceFromChildrenBlock (ec.CurrentBlock.Explicit);
}
}
TypeExpr CreateStoreyTypeExpression (EmitContext ec)
@ -429,7 +506,11 @@ namespace Mono.CSharp { @@ -429,7 +506,11 @@ namespace Mono.CSharp {
Instance = fexpr;
} else {
var local = TemporaryVariableReference.Create (source.Type, block, Location);
local.EmitAssign (ec, source);
if (source.Type.IsStruct) {
local.LocalInfo.CreateBuilder (ec);
} else {
local.EmitAssign (ec, source);
}
Instance = local;
}
@ -458,6 +539,7 @@ namespace Mono.CSharp { @@ -458,6 +539,7 @@ namespace Mono.CSharp {
FieldExpr f_set_expr = new FieldExpr (fs, Location);
f_set_expr.InstanceExpression = instace_expr;
// TODO: CompilerAssign expression
SimpleAssign a = new SimpleAssign (f_set_expr, sf.Storey.GetStoreyInstanceExpression (ec));
if (a.Resolve (rc) != null)
a.EmitStatement (ec);
@ -465,10 +547,10 @@ namespace Mono.CSharp { @@ -465,10 +547,10 @@ namespace Mono.CSharp {
}
//
// Define hoisted `this' in top-level storey only
// Initialize hoisted `this' only once, everywhere else will be
// referenced indirectly
//
if (OriginalSourceBlock.Explicit.HasCapturedThis && !(Parent is AnonymousMethodStorey)) {
AddCapturedThisField (ec);
if (initialize_hoisted_this) {
rc.CurrentBlock.AddScopeStatement (new ThisInitializer (hoisted_this));
}
@ -485,9 +567,20 @@ namespace Mono.CSharp { @@ -485,9 +567,20 @@ namespace Mono.CSharp {
ec.CurrentAnonymousMethod = ae;
}
protected virtual void EmitHoistedParameters (EmitContext ec, IList<HoistedParameter> hoisted)
protected virtual void EmitHoistedParameters (EmitContext ec, List<HoistedParameter> hoisted)
{
foreach (HoistedParameter hp in hoisted) {
//
// Parameters could be proxied via local fields for value type storey
//
if (hoisted_local_params != null) {
var local_param = hoisted_local_params.Find (l => l.Parameter.Parameter == hp.Parameter.Parameter);
var source = new FieldExpr (local_param.Field, Location);
source.InstanceExpression = new CompilerGeneratedThis (CurrentType, Location);
hp.EmitAssign (ec, source, false, false);
continue;
}
hp.EmitHoistingAssignment (ec);
}
}
@ -560,7 +653,12 @@ namespace Mono.CSharp { @@ -560,7 +653,12 @@ namespace Mono.CSharp {
}
public HoistedThis HoistedThis {
get { return hoisted_this; }
get {
return hoisted_this;
}
set {
hoisted_this = value;
}
}
public IList<ExplicitBlock> ReferencesFromChildrenBlock {
@ -628,6 +726,12 @@ namespace Mono.CSharp { @@ -628,6 +726,12 @@ namespace Mono.CSharp {
this.field = field;
}
public AnonymousMethodStorey Storey {
get {
return storey;
}
}
public void AddressOf (EmitContext ec, AddressOp mode)
{
GetFieldExpression (ec).AddressOf (ec, mode);
@ -709,7 +813,7 @@ namespace Mono.CSharp { @@ -709,7 +813,7 @@ namespace Mono.CSharp {
public class HoistedParameter : HoistedVariable
{
sealed class HoistedFieldAssign : Assign
sealed class HoistedFieldAssign : CompilerAssign
{
public HoistedFieldAssign (Expression target, Expression source)
: base (target, source, source.Location)
@ -740,23 +844,32 @@ namespace Mono.CSharp { @@ -740,23 +844,32 @@ namespace Mono.CSharp {
this.parameter = hp.parameter;
}
#region Properties
public Field Field {
get {
return field;
}
}
public ParameterReference Parameter {
get {
return parameter;
}
}
#endregion
public void EmitHoistingAssignment (EmitContext ec)
{
//
// Remove hoisted redirection to emit assignment from original parameter
//
HoistedVariable temp = parameter.Parameter.HoistedVariant;
var temp = parameter.Parameter.HoistedVariant;
parameter.Parameter.HoistedVariant = null;
Assign a = new HoistedFieldAssign (GetFieldExpression (ec), parameter);
if (a.Resolve (new ResolveContext (ec.MemberContext)) != null)
a.EmitStatement (ec);
var a = new HoistedFieldAssign (GetFieldExpression (ec), parameter);
a.EmitStatement (ec);
parameter.Parameter.HoistedVariant = temp;
}
@ -782,13 +895,6 @@ namespace Mono.CSharp { @@ -782,13 +895,6 @@ namespace Mono.CSharp {
return field;
}
}
public void EmitHoistingAssignment (EmitContext ec)
{
SimpleAssign a = new SimpleAssign (GetFieldExpression (ec), new CompilerGeneratedThis (ec.CurrentType, field.Location));
if (a.Resolve (new ResolveContext (ec.MemberContext)) != null)
a.EmitStatement (ec);
}
}
//
@ -1003,12 +1109,8 @@ namespace Mono.CSharp { @@ -1003,12 +1109,8 @@ namespace Mono.CSharp {
}
using (ec.Set (ResolveContext.Options.ProbingMode | ResolveContext.Options.InferReturnType)) {
var body = CompatibleMethodBody (ec, tic, InternalType.Arglist, delegate_type);
var body = CompatibleMethodBody (ec, tic, null, delegate_type);
if (body != null) {
if (Block.IsAsync) {
AsyncInitializer.Create (ec, body.Block, body.Parameters, ec.CurrentMemberDefinition.Parent.PartialContainer, null, loc);
}
am = body.Compatible (ec, body);
} else {
am = null;
@ -1080,6 +1182,10 @@ namespace Mono.CSharp { @@ -1080,6 +1182,10 @@ namespace Mono.CSharp {
} else {
int errors = ec.Report.Errors;
if (Block.IsAsync) {
ec.Report.Error (1989, loc, "Async lambda expressions cannot be converted to expression trees");
}
using (ec.Set (ResolveContext.Options.ExpressionTreeConversion)) {
am = body.Compatible (ec);
}
@ -1091,18 +1197,6 @@ namespace Mono.CSharp { @@ -1091,18 +1197,6 @@ namespace Mono.CSharp {
am = CreateExpressionTree (ec, delegate_type);
}
} else {
if (Block.IsAsync) {
var rt = body.ReturnType;
if (rt.Kind != MemberKind.Void &&
rt != ec.Module.PredefinedTypes.Task.TypeSpec &&
!rt.IsGenericTask) {
ec.Report.Error (4010, loc, "Cannot convert async {0} to delegate type `{1}'",
GetSignatureForError (), type.GetSignatureForError ());
}
AsyncInitializer.Create (ec, body.Block, body.Parameters, ec.CurrentMemberDefinition.Parent.PartialContainer, rt, loc);
}
am = body.Compatible (ec);
}
} catch (CompletionResult) {
@ -1143,7 +1237,7 @@ namespace Mono.CSharp { @@ -1143,7 +1237,7 @@ namespace Mono.CSharp {
for (int i = 0; i < delegate_parameters.Count; i++) {
Parameter.Modifier i_mod = delegate_parameters.FixedParameters [i].ModFlags;
if (i_mod == Parameter.Modifier.OUT) {
if ((i_mod & Parameter.Modifier.OUT) != 0) {
if (!ec.IsInProbingMode) {
ec.Report.Error (1688, loc,
"Cannot convert anonymous method block without a parameter list to delegate type `{0}' because it has one or more `out' parameters",
@ -1230,7 +1324,19 @@ namespace Mono.CSharp { @@ -1230,7 +1324,19 @@ namespace Mono.CSharp {
ParametersBlock b = ec.IsInProbingMode ? (ParametersBlock) Block.PerformClone () : Block;
return CompatibleMethodFactory (return_type, delegate_type, p, b);
if (b.IsAsync) {
var rt = return_type;
if (rt != null && rt.Kind != MemberKind.Void && rt != ec.Module.PredefinedTypes.Task.TypeSpec && !rt.IsGenericTask) {
ec.Report.Error (4010, loc, "Cannot convert async {0} to delegate type `{1}'",
GetSignatureForError (), delegate_type.GetSignatureForError ());
return null;
}
b = b.ConvertToAsyncTask (ec, ec.CurrentMemberDefinition.Parent.PartialContainer, p, return_type, loc);
}
return CompatibleMethodFactory (return_type ?? InternalType.Arglist, delegate_type, p, b);
}
protected virtual AnonymousMethodBody CompatibleMethodFactory (TypeSpec return_type, TypeSpec delegate_type, ParametersCompiled p, ParametersBlock b)
@ -1330,6 +1436,15 @@ namespace Mono.CSharp { @@ -1330,6 +1436,15 @@ namespace Mono.CSharp {
public abstract bool IsIterator { get; }
public abstract AnonymousMethodStorey Storey { get; }
//
// The block that makes up the body for the anonymous method
//
public ParametersBlock Block {
get {
return block;
}
}
public AnonymousExpression Compatible (ResolveContext ec)
{
return Compatible (ec, this);
@ -1403,16 +1518,6 @@ namespace Mono.CSharp { @@ -1403,16 +1518,6 @@ namespace Mono.CSharp {
b = b.Parent == null ? null : b.Parent.Explicit;
} while (b != null);
}
//
// The block that makes up the body for the anonymous method
//
public ParametersBlock Block {
get {
return block;
}
}
}
public class AnonymousMethodBody : AnonymousExpression
@ -1500,19 +1605,49 @@ namespace Mono.CSharp { @@ -1500,19 +1605,49 @@ namespace Mono.CSharp {
//
Modifiers modifiers;
if (Block.HasCapturedVariable || Block.HasCapturedThis) {
storey = FindBestMethodStorey ();
TypeDefinition parent = null;
var src_block = Block.Original.Explicit;
if (src_block.HasCapturedVariable || src_block.HasCapturedThis) {
parent = storey = FindBestMethodStorey ();
if (storey == null) {
var sm = src_block.ParametersBlock.TopBlock.StateMachine;
//
// Remove hoisted this demand when simple instance method is enough
//
if (src_block.HasCapturedThis) {
src_block.ParametersBlock.TopBlock.RemoveThisReferenceFromChildrenBlock (src_block);
//
// Special case where parent class is used to emit instance method
// because currect storey is of value type (async host) and we don't
// want to create another childer storey to host this reference only
//
if (sm != null && sm.Kind == MemberKind.Struct)
parent = sm.Parent.PartialContainer;
}
//
// For iterators we can host everything in one class
//
if (sm is IteratorStorey)
parent = storey = sm;
}
modifiers = storey != null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
} else {
if (ec.CurrentAnonymousMethod != null)
storey = ec.CurrentAnonymousMethod.Storey;
parent = storey = ec.CurrentAnonymousMethod.Storey;
modifiers = Modifiers.STATIC | Modifiers.PRIVATE;
}
var parent = storey != null ? storey : ec.CurrentTypeDefinition.Parent.PartialContainer;
if (parent == null)
parent = ec.CurrentTypeDefinition.Parent.PartialContainer;
string name = CompilerGeneratedClass.MakeName (parent != storey ? block_name : null,
string name = CompilerGeneratedContainer.MakeName (parent != storey ? block_name : null,
"m", null, ec.Module.CounterAnonymousMethods++);
MemberName member_name;
@ -1570,7 +1705,7 @@ namespace Mono.CSharp { @@ -1570,7 +1705,7 @@ namespace Mono.CSharp {
am_cache = new Field (parent, new TypeExpression (cache_type, loc),
Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED,
new MemberName (CompilerGeneratedClass.MakeName (null, "f", "am$cache", id), loc), null);
new MemberName (CompilerGeneratedContainer.MakeName (null, "f", "am$cache", id), loc), null);
am_cache.Define ();
parent.AddField (am_cache);
} else {
@ -1610,10 +1745,22 @@ namespace Mono.CSharp { @@ -1610,10 +1745,22 @@ namespace Mono.CSharp {
ec.EmitNull ();
} else if (storey != null) {
Expression e = storey.GetStoreyInstanceExpression (ec).Resolve (new ResolveContext (ec.MemberContext));
if (e != null)
if (e != null) {
e.Emit (ec);
}
} else {
ec.EmitThis ();
//
// Special case for value type storey where this is not lifted but
// droped off to parent class
//
for (var b = Block.Parent; b != null; b = b.Parent) {
if (b.ParametersBlock.StateMachine != null) {
ec.Emit (OpCodes.Ldfld, b.ParametersBlock.StateMachine.HoistedThis.Field.Spec);
break;
}
}
}
var delegate_method = method.Spec;
@ -1624,9 +1771,7 @@ namespace Mono.CSharp { @@ -1624,9 +1771,7 @@ namespace Mono.CSharp {
// Mutate anonymous method instance type if we are in nested
// hoisted generic anonymous method storey
//
if (ec.CurrentAnonymousMethod != null &&
ec.CurrentAnonymousMethod.Storey != null &&
ec.CurrentAnonymousMethod.Storey.Mutator != null) {
if (ec.IsAnonymousStoreyMutateRequired) {
t = storey.Mutator.Mutate (t);
}
@ -1679,7 +1824,7 @@ namespace Mono.CSharp { @@ -1679,7 +1824,7 @@ namespace Mono.CSharp {
//
// Anonymous type container
//
public class AnonymousTypeClass : CompilerGeneratedClass
public class AnonymousTypeClass : CompilerGeneratedContainer
{
public const string ClassNamePrefix = "<>__AnonType";
public const string SignatureForError = "anonymous type";
@ -1687,7 +1832,7 @@ namespace Mono.CSharp { @@ -1687,7 +1832,7 @@ namespace Mono.CSharp {
readonly IList<AnonymousTypeParameter> parameters;
private AnonymousTypeClass (ModuleContainer parent, MemberName name, IList<AnonymousTypeParameter> parameters, Location loc)
: base (parent, name, (parent.Evaluator != null ? Modifiers.PUBLIC : 0) | Modifiers.SEALED)
: base (parent, name, parent.Evaluator != null ? Modifiers.PUBLIC : Modifiers.INTERNAL)
{
this.parameters = parameters;
}
@ -1740,7 +1885,7 @@ namespace Mono.CSharp { @@ -1740,7 +1885,7 @@ namespace Mono.CSharp {
c.Block = new ToplevelBlock (parent.Module.Compiler, c.ParameterInfo, loc);
//
// Create fields and contructor body with field initialization
// Create fields and constructor body with field initialization
//
bool error = false;
for (int i = 0; i < parameters.Count; ++i) {

12
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/argument.cs

@ -120,10 +120,14 @@ namespace Mono.CSharp @@ -120,10 +120,14 @@ namespace Mono.CSharp
ml.AddressOf (ec, mode);
}
public Argument EmitToField (EmitContext ec)
public Argument EmitToField (EmitContext ec, bool cloneResult)
{
var res = Expr.EmitToField (ec);
return res == Expr ? this : new Argument (res, ArgType);
if (cloneResult && res != Expr)
return new Argument (res, ArgType);
Expr = res;
return this;
}
public string GetSignatureForError ()
@ -258,7 +262,7 @@ namespace Mono.CSharp @@ -258,7 +262,7 @@ namespace Mono.CSharp
{
foreach (var a in ordered) {
if (prepareAwait)
a.EmitToField (ec);
a.EmitToField (ec, false);
else
a.EmitToVariable (ec);
}
@ -440,7 +444,7 @@ namespace Mono.CSharp @@ -440,7 +444,7 @@ namespace Mono.CSharp
LocalTemporary lt;
foreach (Argument a in args) {
if (prepareAwait) {
dups.Add (a.EmitToField (ec));
dups.Add (a.EmitToField (ec, true));
continue;
}

4
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/assembly.cs

@ -1010,7 +1010,7 @@ namespace Mono.CSharp @@ -1010,7 +1010,7 @@ namespace Mono.CSharp
//
// A placeholder class for assembly attributes when emitting module
//
class AssemblyAttributesPlaceholder : CompilerGeneratedClass
class AssemblyAttributesPlaceholder : CompilerGeneratedContainer
{
static readonly string TypeNamePrefix = "<$AssemblyAttributes${0}>";
public static readonly string AssemblyFieldName = "attributes";
@ -1018,7 +1018,7 @@ namespace Mono.CSharp @@ -1018,7 +1018,7 @@ namespace Mono.CSharp
Field assembly;
public AssemblyAttributesPlaceholder (ModuleContainer parent, string outputName)
: base (parent, new MemberName (GetGeneratedName (outputName)), Modifiers.STATIC)
: base (parent, new MemberName (GetGeneratedName (outputName)), Modifiers.STATIC | Modifiers.INTERNAL)
{
assembly = new Field (this, new TypeExpression (parent.Compiler.BuiltinTypes.Object, Location), Modifiers.PUBLIC | Modifiers.STATIC,
new MemberName (AssemblyFieldName), null);

12
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/assign.cs

@ -343,7 +343,7 @@ namespace Mono.CSharp { @@ -343,7 +343,7 @@ namespace Mono.CSharp {
type = target_type;
if (!(target is IAssignMethod)) {
Error_ValueAssignment (ec, source);
target.Error_ValueAssignment (ec, source);
return null;
}
@ -488,6 +488,10 @@ namespace Mono.CSharp { @@ -488,6 +488,10 @@ namespace Mono.CSharp {
public CompilerAssign (Expression target, Expression source, Location loc)
: base (target, source, loc)
{
if (target.Type != null) {
type = target.Type;
eclass = ExprClass.Value;
}
}
protected override Expression DoResolve (ResolveContext ec)
@ -568,10 +572,10 @@ namespace Mono.CSharp { @@ -568,10 +572,10 @@ namespace Mono.CSharp {
//
// Emit sequence symbol info even if we are in compiler generated
// block to allow debugging filed initializers when constructor is
// block to allow debugging field initializers when constructor is
// compiler generated
//
if (ec.HasSet (BuilderContext.Options.OmitDebugInfo)) {
if (ec.HasSet (BuilderContext.Options.OmitDebugInfo) && ec.HasMethodSymbolBuilder) {
using (ec.With (BuilderContext.Options.OmitDebugInfo, false)) {
ec.Mark (loc);
}
@ -822,7 +826,7 @@ namespace Mono.CSharp { @@ -822,7 +826,7 @@ namespace Mono.CSharp {
return new SimpleAssign (target, new DynamicConversion (target_type, CSharpBinderFlags.ConvertExplicit, arg, loc), loc).Resolve (ec);
}
right.Error_ValueCannotBeConverted (ec, loc, target_type, false);
right.Error_ValueCannotBeConverted (ec, target_type, false);
return null;
}

502
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/async.cs

@ -46,6 +46,12 @@ namespace Mono.CSharp @@ -46,6 +46,12 @@ namespace Mono.CSharp
}
}
public AwaitStatement Statement {
get {
return stmt;
}
}
protected override void CloneTo (CloneContext clonectx, Expression target)
{
var t = (Await) target;
@ -70,11 +76,6 @@ namespace Mono.CSharp @@ -70,11 +76,6 @@ namespace Mono.CSharp
"The `await' operator cannot be used in the body of a lock statement");
}
if (rc.HasSet (ResolveContext.Options.ExpressionTreeConversion)) {
rc.Report.Error (1989, loc, "An expression tree cannot contain an await operator");
return null;
}
if (rc.IsUnsafe) {
rc.Report.Error (4004, loc,
"The `await' operator cannot be used in an unsafe context");
@ -124,7 +125,7 @@ namespace Mono.CSharp @@ -124,7 +125,7 @@ namespace Mono.CSharp
}
}
class AwaitStatement : YieldStatement<AsyncInitializer>
public class AwaitStatement : YieldStatement<AsyncInitializer>
{
sealed class AwaitableMemberAccess : MemberAccess
{
@ -140,7 +141,13 @@ namespace Mono.CSharp @@ -140,7 +141,13 @@ namespace Mono.CSharp
protected override void Error_OperatorCannotBeApplied (ResolveContext rc, TypeSpec type)
{
rc.Report.Error (4001, loc, "Cannot await `{0}' expression", type.GetSignatureForError ());
var invocation = LeftExpression as Invocation;
if (invocation != null && invocation.MethodGroup != null && (invocation.MethodGroup.BestCandidate.Modifiers & Modifiers.ASYNC) != 0) {
rc.Report.Error (4008, loc, "Cannot await void method `{0}'. Consider changing method return type to `Task'",
invocation.GetSignatureForError ());
} else {
rc.Report.Error (4001, loc, "Cannot await `{0}' expression", type.GetSignatureForError ());
}
}
}
@ -161,7 +168,6 @@ namespace Mono.CSharp @@ -161,7 +168,6 @@ namespace Mono.CSharp
Field awaiter;
PropertySpec is_completed;
MethodSpec on_completed;
MethodSpec get_result;
TypeSpec type;
TypeSpec result_type;
@ -213,6 +219,8 @@ namespace Mono.CSharp @@ -213,6 +219,8 @@ namespace Mono.CSharp
public void EmitPrologue (EmitContext ec)
{
awaiter = ((AsyncTaskStorey) machine_initializer.Storey).AddAwaiter (expr.Type, loc);
var fe_awaiter = new FieldExpr (awaiter, loc);
fe_awaiter.InstanceExpression = new CompilerGeneratedThis (ec.CurrentType, loc);
@ -230,6 +238,10 @@ namespace Mono.CSharp @@ -230,6 +238,10 @@ namespace Mono.CSharp
Arguments dargs = new Arguments (1);
dargs.Add (new Argument (fe_awaiter));
completed_expr = new DynamicMemberBinder ("IsCompleted", dargs, loc).Resolve (rc);
dargs = new Arguments (1);
dargs.Add (new Argument (completed_expr));
completed_expr = new DynamicConversion (ec.Module.Compiler.BuiltinTypes.Bool, 0, dargs, loc).Resolve (rc);
} else {
var pe = PropertyExpr.CreatePredefined (is_completed, loc);
pe.InstanceExpression = fe_awaiter;
@ -252,25 +264,10 @@ namespace Mono.CSharp @@ -252,25 +264,10 @@ namespace Mono.CSharp
ec.AssertEmptyStack ();
var storey = (AsyncTaskStorey) machine_initializer.Storey;
var cont_field = storey.EmitContinuationInitialization (ec);
var args = new Arguments (1);
args.Add (new Argument (cont_field));
if (IsDynamic) {
var rc = new ResolveContext (ec.MemberContext);
var mg_expr = new Invocation (new MemberAccess (fe_awaiter, "OnCompleted"), args).Resolve (rc);
ExpressionStatement es = (ExpressionStatement) mg_expr;
es.EmitStatement (ec);
storey.EmitAwaitOnCompletedDynamic (ec, fe_awaiter);
} else {
var mg_completed = MethodGroupExpr.CreatePredefined (on_completed, fe_awaiter.Type, loc);
mg_completed.InstanceExpression = fe_awaiter;
//
// awaiter.OnCompleted (continuation);
//
mg_completed.EmitCall (ec, args);
storey.EmitAwaitOnCompleted (ec, fe_awaiter);
}
// Return ok
@ -285,6 +282,8 @@ namespace Mono.CSharp @@ -285,6 +282,8 @@ namespace Mono.CSharp
EmitPrologue (ec);
DoEmit (ec);
awaiter.IsAvailableForReuse = true;
if (ResultType.Kind != MemberKind.Void) {
var storey = (AsyncTaskStorey) machine_initializer.Storey;
@ -297,12 +296,18 @@ namespace Mono.CSharp @@ -297,12 +296,18 @@ namespace Mono.CSharp
void Error_WrongAwaiterPattern (ResolveContext rc, TypeSpec awaiter)
{
rc.Report.Error (4011, loc, "The awaiter type `{0}' must have suitable IsCompleted, OnCompleted, and GetResult members",
rc.Report.Error (4011, loc, "The awaiter type `{0}' must have suitable IsCompleted and GetResult members",
awaiter.GetSignatureForError ());
}
public override bool Resolve (BlockContext bc)
{
if (bc.CurrentBlock is Linq.QueryBlock) {
bc.Report.Error (1995, loc,
"The `await' operator may only be used in a query expression within the first collection expression of the initial `from' clause or within the collection expression of a `join' clause");
return false;
}
if (!base.Resolve (bc))
return false;
@ -315,9 +320,6 @@ namespace Mono.CSharp @@ -315,9 +320,6 @@ namespace Mono.CSharp
//
if (type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
result_type = type;
awaiter = ((AsyncTaskStorey) machine_initializer.Storey).AddAwaiter (type, loc);
expr = new Invocation (new MemberAccess (expr, "GetAwaiter"), args).Resolve (bc);
return true;
}
@ -343,8 +345,6 @@ namespace Mono.CSharp @@ -343,8 +345,6 @@ namespace Mono.CSharp
}
var awaiter_type = ama.Type;
awaiter = ((AsyncTaskStorey) machine_initializer.Storey).AddAwaiter (awaiter_type, loc);
expr = ama;
//
@ -358,20 +358,6 @@ namespace Mono.CSharp @@ -358,20 +358,6 @@ namespace Mono.CSharp
return false;
}
//
// Predefined: OnCompleted (Action)
//
if (bc.Module.PredefinedTypes.Action.Define ()) {
on_completed = MemberCache.FindMember (awaiter_type, MemberFilter.Method ("OnCompleted", 0,
ParametersCompiled.CreateFullyResolved (bc.Module.PredefinedTypes.Action.TypeSpec), bc.Module.Compiler.BuiltinTypes.Void),
BindingRestriction.InstanceOnly) as MethodSpec;
if (on_completed == null) {
Error_WrongAwaiterPattern (bc, awaiter_type);
return false;
}
}
//
// Predefined: GetResult ()
//
@ -386,6 +372,16 @@ namespace Mono.CSharp @@ -386,6 +372,16 @@ namespace Mono.CSharp
return false;
}
//
// Predefined: INotifyCompletion.OnCompleted (System.Action)
//
var nc = bc.Module.PredefinedTypes.INotifyCompletion;
if (nc.Define () && !awaiter_type.ImplementsInterface (nc.TypeSpec, false)) {
bc.Report.Error (4027, loc, "The awaiter type `{0}' must implement interface `{1}'",
awaiter_type.GetSignatureForError (), nc.GetSignatureForError ());
return false;
}
result_type = get_result.ReturnType;
return true;
@ -415,12 +411,6 @@ namespace Mono.CSharp @@ -415,12 +411,6 @@ namespace Mono.CSharp
}
}
public Block OriginalBlock {
get {
return block.Parent;
}
}
public TypeInferenceContext ReturnTypeInference {
get {
return return_inference;
@ -429,38 +419,6 @@ namespace Mono.CSharp @@ -429,38 +419,6 @@ namespace Mono.CSharp
#endregion
public static void Create (IMemberContext context, ParametersBlock block, ParametersCompiled parameters, TypeDefinition host, TypeSpec returnType, Location loc)
{
for (int i = 0; i < parameters.Count; i++) {
Parameter p = parameters[i];
Parameter.Modifier mod = p.ModFlags;
if ((mod & Parameter.Modifier.ISBYREF) != 0) {
host.Compiler.Report.Error (1988, p.Location,
"Async methods cannot have ref or out parameters");
return;
}
if (p is ArglistParameter) {
host.Compiler.Report.Error (4006, p.Location,
"__arglist is not allowed in parameter list of async methods");
return;
}
if (parameters.Types[i].IsPointer) {
host.Compiler.Report.Error (4005, p.Location,
"Async methods cannot have unsafe parameters");
return;
}
}
if (!block.HasAwait) {
host.Compiler.Report.Warning (1998, 1, loc,
"Async block lacks `await' operator and will run synchronously");
}
block.WrapIntoAsyncTask (context, host, returnType);
}
protected override BlockContext CreateBlockContext (ResolveContext rc)
{
var ctx = base.CreateBlockContext (rc);
@ -491,37 +449,7 @@ namespace Mono.CSharp @@ -491,37 +449,7 @@ namespace Mono.CSharp
public override void EmitStatement (EmitContext ec)
{
var storey = (AsyncTaskStorey) Storey;
storey.Instance.Emit (ec);
var move_next_entry = storey.StateMachineMethod.Spec;
if (storey.MemberName.Arity > 0) {
move_next_entry = MemberCache.GetMember (storey.Instance.Type, move_next_entry);
}
ec.Emit (OpCodes.Call, move_next_entry);
//
// Emits return <async-storey-instance>.$builder.Task;
//
if (storey.Task != null) {
var builder_field = storey.Builder.Spec;
var task_get = storey.Task.Get;
if (storey.MemberName.Arity > 0) {
builder_field = MemberCache.GetMember (storey.Instance.Type, builder_field);
task_get = MemberCache.GetMember (builder_field.MemberType, task_get);
}
var pe_task = new PropertyExpr (storey.Task, loc) {
InstanceExpression = new FieldExpr (builder_field, loc) {
InstanceExpression = storey.Instance
},
Getter = task_get
};
pe_task.Emit (ec);
}
storey.EmitInitializer (ec);
ec.Emit (OpCodes.Ret);
}
}
@ -529,30 +457,27 @@ namespace Mono.CSharp @@ -529,30 +457,27 @@ namespace Mono.CSharp
class AsyncTaskStorey : StateMachine
{
int awaiters;
Field builder, continuation;
Field builder;
readonly TypeSpec return_type;
MethodSpec set_result;
MethodSpec set_exception;
MethodSpec builder_factory;
MethodSpec builder_start;
PropertySpec task;
LocalVariable hoisted_return;
int locals_captured;
Dictionary<TypeSpec, List<StackField>> stack_fields;
TypeSpec action;
Dictionary<TypeSpec, List<Field>> stack_fields;
Dictionary<TypeSpec, List<Field>> awaiter_fields;
public AsyncTaskStorey (IMemberContext context, AsyncInitializer initializer, TypeSpec type)
: base (initializer.OriginalBlock, initializer.Host, context.CurrentMemberDefinition as MemberBase, context.CurrentTypeParameters, "async")
public AsyncTaskStorey (ParametersBlock block, IMemberContext context, AsyncInitializer initializer, TypeSpec type)
: base (block, initializer.Host, context.CurrentMemberDefinition as MemberBase, context.CurrentTypeParameters, "async", MemberKind.Struct)
{
return_type = type;
awaiter_fields = new Dictionary<TypeSpec, List<Field>> ();
}
#region Properties
public Field Builder {
get {
return builder;
}
}
public LocalVariable HoistedReturn {
get {
return hoisted_return;
@ -575,34 +500,53 @@ namespace Mono.CSharp @@ -575,34 +500,53 @@ namespace Mono.CSharp
public Field AddAwaiter (TypeSpec type, Location loc)
{
return AddCapturedVariable ("$awaiter" + awaiters++.ToString ("X"), type);
if (mutator != null)
type = mutator.Mutate (type);
List<Field> existing_fields = null;
if (awaiter_fields.TryGetValue (type, out existing_fields)) {
foreach (var f in existing_fields) {
if (f.IsAvailableForReuse) {
f.IsAvailableForReuse = false;
return f;
}
}
}
var field = AddCompilerGeneratedField ("$awaiter" + awaiters++.ToString ("X"), new TypeExpression (type, Location), true);
field.Define ();
if (existing_fields == null) {
existing_fields = new List<Field> ();
awaiter_fields.Add (type, existing_fields);
}
existing_fields.Add (field);
return field;
}
public StackField AddCapturedLocalVariable (TypeSpec type)
public Field AddCapturedLocalVariable (TypeSpec type)
{
if (mutator != null)
type = mutator.Mutate (type);
List<StackField> existing_fields = null;
List<Field> existing_fields = null;
if (stack_fields == null) {
stack_fields = new Dictionary<TypeSpec, List<StackField>> ();
stack_fields = new Dictionary<TypeSpec, List<Field>> ();
} else if (stack_fields.TryGetValue (type, out existing_fields)) {
foreach (var f in existing_fields) {
if (f.CanBeReused) {
f.CanBeReused = false;
if (f.IsAvailableForReuse) {
f.IsAvailableForReuse = false;
return f;
}
}
}
const Modifiers mod = Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE;
var field = new StackField (this, new TypeExpression (type, Location), mod, new MemberName ("<s>$" + locals_captured++.ToString ("X"), Location));
AddField (field);
var field = AddCompilerGeneratedField ("$stack" + locals_captured++.ToString ("X"), new TypeExpression (type, Location), true);
field.Define ();
if (existing_fields == null) {
existing_fields = new List<StackField> ();
existing_fields = new List<Field> ();
stack_fields.Add (type, existing_fields);
}
@ -613,39 +557,52 @@ namespace Mono.CSharp @@ -613,39 +557,52 @@ namespace Mono.CSharp
protected override bool DoDefineMembers ()
{
action = Module.PredefinedTypes.Action.Resolve ();
PredefinedType builder_type;
PredefinedMember<MethodSpec> bf;
PredefinedMember<MethodSpec> bs;
PredefinedMember<MethodSpec> sr;
PredefinedMember<MethodSpec> se;
PredefinedMember<MethodSpec> sm;
bool has_task_return_type = false;
var pred_members = Module.PredefinedMembers;
if (return_type.Kind == MemberKind.Void) {
builder_type = Module.PredefinedTypes.AsyncVoidMethodBuilder;
bf = pred_members.AsyncVoidMethodBuilderCreate;
bs = pred_members.AsyncVoidMethodBuilderStart;
sr = pred_members.AsyncVoidMethodBuilderSetResult;
se = pred_members.AsyncVoidMethodBuilderSetException;
sm = pred_members.AsyncVoidMethodBuilderSetStateMachine;
} else if (return_type == Module.PredefinedTypes.Task.TypeSpec) {
builder_type = Module.PredefinedTypes.AsyncTaskMethodBuilder;
bf = pred_members.AsyncTaskMethodBuilderCreate;
bs = pred_members.AsyncTaskMethodBuilderStart;
sr = pred_members.AsyncTaskMethodBuilderSetResult;
se = pred_members.AsyncTaskMethodBuilderSetException;
sm = pred_members.AsyncTaskMethodBuilderSetStateMachine;
task = pred_members.AsyncTaskMethodBuilderTask.Get ();
} else {
builder_type = Module.PredefinedTypes.AsyncTaskMethodBuilderGeneric;
bf = pred_members.AsyncTaskMethodBuilderGenericCreate;
bs = pred_members.AsyncTaskMethodBuilderGenericStart;
sr = pred_members.AsyncTaskMethodBuilderGenericSetResult;
se = pred_members.AsyncTaskMethodBuilderGenericSetException;
sm = pred_members.AsyncTaskMethodBuilderGenericSetStateMachine;
task = pred_members.AsyncTaskMethodBuilderGenericTask.Get ();
has_task_return_type = true;
}
set_result = sr.Get ();
set_exception = se.Get ();
var builder_factory = bf.Get ();
if (!builder_type.Define () || set_result == null || builder_factory == null || set_exception == null) {
builder_factory = bf.Get ();
builder_start = bs.Get ();
var istate_machine = Module.PredefinedTypes.IAsyncStateMachine;
var set_statemachine = sm.Get ();
if (!builder_type.Define () || !istate_machine.Define () || set_result == null || builder_factory == null ||
set_exception == null || set_statemachine == null || builder_start == null ||
!Module.PredefinedTypes.INotifyCompletion.Define ()) {
Report.Error (1993, Location,
"Cannot find compiler required types for asynchronous functions support. Are you targeting the wrong framework version?");
return base.DoDefineMembers ();
@ -662,83 +619,206 @@ namespace Mono.CSharp @@ -662,83 +619,206 @@ namespace Mono.CSharp
task_return_type = mutator.Mutate (task_return_type);
bt = bt.MakeGenericType (Module, task_return_type);
builder_factory = MemberCache.GetMember<MethodSpec> (bt, builder_factory);
set_result = MemberCache.GetMember<MethodSpec> (bt, set_result);
set_exception = MemberCache.GetMember<MethodSpec> (bt, set_exception);
set_result = MemberCache.GetMember (bt, set_result);
set_exception = MemberCache.GetMember (bt, set_exception);
set_statemachine = MemberCache.GetMember (bt, set_statemachine);
if (task != null)
task = MemberCache.GetMember<PropertySpec> (bt, task);
task = MemberCache.GetMember (bt, task);
}
builder = AddCompilerGeneratedField ("$builder", new TypeExpression (bt, Location));
var ctor = DefineDefaultConstructor (false);
var set_state_machine = new Method (this, new TypeExpression (Compiler.BuiltinTypes.Void, Location),
Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN | Modifiers.PUBLIC,
new MemberName ("SetStateMachine"),
ParametersCompiled.CreateFullyResolved (
new Parameter (new TypeExpression (istate_machine.TypeSpec, Location), "stateMachine", Parameter.Modifier.NONE, null, Location),
istate_machine.TypeSpec),
null);
ToplevelBlock block = new ToplevelBlock (Compiler, set_state_machine.ParameterInfo, Location);
block.IsCompilerGenerated = true;
set_state_machine.Block = block;
Members.Add (set_state_machine);
if (!base.DoDefineMembers ())
return false;
Block block = ctor.Block;
//
// Fabricates SetStateMachine method
//
// public void SetStateMachine (IAsyncStateMachine stateMachine)
// {
// $builder.SetStateMachine (stateMachine);
// }
//
var mg = MethodGroupExpr.CreatePredefined (set_statemachine, bt, Location);
mg.InstanceExpression = new FieldExpr (builder, Location);
var mg = MethodGroupExpr.CreatePredefined (builder_factory, bt, Location);
block.AddStatement (
new StatementExpression (new SimpleAssign (
new FieldExpr (builder, Location),
new Invocation (mg, new Arguments (0)),
Location)));
var param_reference = block.GetParameterReference (0, Location);
param_reference.Type = istate_machine.TypeSpec;
param_reference.eclass = ExprClass.Variable;
var args = new Arguments (1);
args.Add (new Argument (param_reference));
set_state_machine.Block.AddStatement (new StatementExpression (new Invocation (mg, args)));
if (has_task_return_type) {
hoisted_return = LocalVariable.CreateCompilerGenerated (bt.TypeArguments[0], block, Location);
hoisted_return = LocalVariable.CreateCompilerGenerated (bt.TypeArguments[0], StateMachineMethod.Block, Location);
}
return true;
}
public Expression EmitContinuationInitialization (EmitContext ec)
public void EmitAwaitOnCompletedDynamic (EmitContext ec, FieldExpr awaiter)
{
var critical = Module.PredefinedTypes.ICriticalNotifyCompletion;
if (!critical.Define ()) {
throw new NotImplementedException ();
}
var temp_critical = new LocalTemporary (critical.TypeSpec);
var label_critical = ec.DefineLabel ();
var label_end = ec.DefineLabel ();
//
// When more than 1 awaiter has been used in the block we
// introduce class scope field to cache continuation delegate
// Special path for dynamic awaiters
//
if (awaiters > 1) {
if (continuation == null) {
continuation = AddCompilerGeneratedField ("$continuation", new TypeExpression (action, Location), true);
continuation.Define ();
}
// var awaiter = this.$awaiter as ICriticalNotifyCompletion;
// if (awaiter == null) {
// var completion = (INotifyCompletion) this.$awaiter;
// this.$builder.AwaitOnCompleted (ref completion, ref this);
// } else {
// this.$builder.AwaitUnsafeOnCompleted (ref awaiter, ref this);
// }
//
awaiter.Emit (ec);
ec.Emit (OpCodes.Isinst, critical.TypeSpec);
temp_critical.Store (ec);
temp_critical.Emit (ec);
ec.Emit (OpCodes.Brtrue_S, label_critical);
var temp = new LocalTemporary (Module.PredefinedTypes.INotifyCompletion.TypeSpec);
awaiter.Emit (ec);
ec.Emit (OpCodes.Castclass, temp.Type);
temp.Store (ec);
EmitOnCompleted (ec, temp, false);
temp.Release (ec);
ec.Emit (OpCodes.Br_S, label_end);
var fexpr = new FieldExpr (continuation, Location);
fexpr.InstanceExpression = new CompilerGeneratedThis (CurrentType, Location);
ec.MarkLabel (label_critical);
//
// if ($continuation == null)
// $continuation = new Action (MoveNext);
//
fexpr.Emit (ec);
EmitOnCompleted (ec, temp_critical, true);
var skip_cont_init = ec.DefineLabel ();
ec.Emit (OpCodes.Brtrue_S, skip_cont_init);
ec.MarkLabel (label_end);
ec.EmitThis ();
EmitActionLoad (ec);
ec.Emit (OpCodes.Stfld, continuation.Spec);
ec.MarkLabel (skip_cont_init);
temp_critical.Release (ec);
}
return fexpr;
public void EmitAwaitOnCompleted (EmitContext ec, FieldExpr awaiter)
{
bool unsafe_version = false;
if (Module.PredefinedTypes.ICriticalNotifyCompletion.Define ()) {
unsafe_version = awaiter.Type.ImplementsInterface (Module.PredefinedTypes.ICriticalNotifyCompletion.TypeSpec, false);
}
//
// Otherwise simply use temporary local variable
//
var field = LocalVariable.CreateCompilerGenerated (action, OriginalSourceBlock, Location);
EmitActionLoad (ec);
field.EmitAssign (ec);
return new LocalVariableReference (field, Location);
EmitOnCompleted (ec, awaiter, unsafe_version);
}
void EmitActionLoad (EmitContext ec)
void EmitOnCompleted (EmitContext ec, Expression awaiter, bool unsafeVersion)
{
ec.EmitThis ();
ec.Emit (OpCodes.Ldftn, StateMachineMethod.Spec);
ec.Emit (OpCodes.Newobj, (MethodSpec) MemberCache.FindMember (action, MemberFilter.Constructor (null), BindingRestriction.DeclaredOnly));
var pm = Module.PredefinedMembers;
PredefinedMember<MethodSpec> predefined;
bool has_task_return_type = false;
if (return_type.Kind == MemberKind.Void) {
predefined = unsafeVersion ? pm.AsyncVoidMethodBuilderOnCompletedUnsafe : pm.AsyncVoidMethodBuilderOnCompleted;
} else if (return_type == Module.PredefinedTypes.Task.TypeSpec) {
predefined = unsafeVersion ? pm.AsyncTaskMethodBuilderOnCompletedUnsafe : pm.AsyncTaskMethodBuilderOnCompleted;
} else {
predefined = unsafeVersion ? pm.AsyncTaskMethodBuilderGenericOnCompletedUnsafe : pm.AsyncTaskMethodBuilderGenericOnCompleted;
has_task_return_type = true;
}
var on_completed = predefined.Resolve (Location);
if (on_completed == null)
return;
if (has_task_return_type)
on_completed = MemberCache.GetMember<MethodSpec> (set_result.DeclaringType, on_completed);
on_completed = on_completed.MakeGenericMethod (this, awaiter.Type, ec.CurrentType);
var mg = MethodGroupExpr.CreatePredefined (on_completed, on_completed.DeclaringType, Location);
mg.InstanceExpression = new FieldExpr (builder, Location) {
InstanceExpression = new CompilerGeneratedThis (ec.CurrentType, Location)
};
var args = new Arguments (2);
args.Add (new Argument (awaiter, Argument.AType.Ref));
args.Add (new Argument (new CompilerGeneratedThis (CurrentType, Location), Argument.AType.Ref));
mg.EmitCall (ec, args);
}
public void EmitInitializer (EmitContext ec)
{
//
// Some predefined types are missing
//
if (builder == null)
return;
var instance = (TemporaryVariableReference) Instance;
var builder_field = builder.Spec;
if (MemberName.Arity > 0) {
builder_field = MemberCache.GetMember (instance.Type, builder_field);
}
//
// Inflated factory method when task is of generic type
//
if (builder_factory.DeclaringType.IsGeneric) {
var task_return_type = return_type.TypeArguments;
var bt = builder_factory.DeclaringType.MakeGenericType (Module, task_return_type);
builder_factory = MemberCache.GetMember (bt, builder_factory);
builder_start = MemberCache.GetMember (bt, builder_start);
}
//
// stateMachine.$builder = AsyncTaskMethodBuilder<{task-type}>.Create();
//
instance.AddressOf (ec, AddressOp.Store);
ec.Emit (OpCodes.Call, builder_factory);
ec.Emit (OpCodes.Stfld, builder_field);
//
// stateMachine.$builder.Start<{storey-type}>(ref stateMachine);
//
instance.AddressOf (ec, AddressOp.Store);
ec.Emit (OpCodes.Ldflda, builder_field);
if (Task != null)
ec.Emit (OpCodes.Dup);
instance.AddressOf (ec, AddressOp.Store);
ec.Emit (OpCodes.Call, builder_start.MakeGenericMethod (Module, instance.Type));
//
// Emits return stateMachine.$builder.Task;
//
if (Task != null) {
var task_get = Task.Get;
if (MemberName.Arity > 0) {
task_get = MemberCache.GetMember (builder_field.MemberType, task_get);
}
var pe_task = new PropertyExpr (Task, Location) {
InstanceExpression = EmptyExpression.Null, // Comes from the dup above
Getter = task_get
};
pe_task.Emit (ec);
}
}
public void EmitSetException (EmitContext ec, LocalVariableReference exceptionVariable)
@ -747,7 +827,7 @@ namespace Mono.CSharp @@ -747,7 +827,7 @@ namespace Mono.CSharp
// $builder.SetException (Exception)
//
var mg = MethodGroupExpr.CreatePredefined (set_exception, set_exception.DeclaringType, Location);
mg.InstanceExpression = new FieldExpr (Builder, Location) {
mg.InstanceExpression = new FieldExpr (builder, Location) {
InstanceExpression = new CompilerGeneratedThis (ec.CurrentType, Location)
};
@ -764,7 +844,7 @@ namespace Mono.CSharp @@ -764,7 +844,7 @@ namespace Mono.CSharp
// $builder.SetResult<return-type> (value);
//
var mg = MethodGroupExpr.CreatePredefined (set_result, set_result.DeclaringType, Location);
mg.InstanceExpression = new FieldExpr (Builder, Location) {
mg.InstanceExpression = new FieldExpr (builder, Location) {
InstanceExpression = new CompilerGeneratedThis (ec.CurrentType, Location)
};
@ -778,31 +858,57 @@ namespace Mono.CSharp @@ -778,31 +858,57 @@ namespace Mono.CSharp
mg.EmitCall (ec, args);
}
}
class StackField : Field
{
public StackField (TypeDefinition parent, FullNamedExpression type, Modifiers mod, MemberName name)
: base (parent, type, mod, name, null)
protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
{
}
base_type = Compiler.BuiltinTypes.ValueType;
base_class = null;
public bool CanBeReused { get; set; }
var istate_machine = Module.PredefinedTypes.IAsyncStateMachine;
if (istate_machine.Define ()) {
return new[] { istate_machine.TypeSpec };
}
return null;
}
}
class StackFieldExpr : FieldExpr
class StackFieldExpr : FieldExpr, IExpressionCleanup
{
public StackFieldExpr (Field field)
: base (field, Location.Null)
{
}
public override void AddressOf (EmitContext ec, AddressOp mode)
{
base.AddressOf (ec, mode);
if (mode == AddressOp.Load) {
var field = (Field) spec.MemberDefinition;
field.IsAvailableForReuse = true;
}
}
public override void Emit (EmitContext ec)
{
base.Emit (ec);
var field = (StackField) spec.MemberDefinition;
field.CanBeReused = true;
var field = (Field) spec.MemberDefinition;
field.IsAvailableForReuse = true;
//
// Release any captured reference type stack variables
// to imitate real stack behavour and help GC stuff early
//
if (TypeSpec.IsReferenceType (type)) {
ec.AddStatementEpilog (this);
}
}
void IExpressionCleanup.EmitCleanup (EmitContext ec)
{
EmitAssign (ec, new NullConstant (type, loc), false, false);
}
}
}

14
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/attribute.cs

@ -902,6 +902,11 @@ namespace Mono.CSharp { @@ -902,6 +902,11 @@ namespace Mono.CSharp {
// Returns true for MethodImplAttribute with MethodImplOptions.InternalCall value
//
public bool IsInternalCall ()
{
return (GetMethodImplOptions () & MethodImplOptions.InternalCall) != 0;
}
public MethodImplOptions GetMethodImplOptions ()
{
MethodImplOptions options = 0;
if (pos_args.Count == 1) {
@ -911,7 +916,7 @@ namespace Mono.CSharp { @@ -911,7 +916,7 @@ namespace Mono.CSharp {
options = (MethodImplOptions) System.Enum.Parse (typeof (MethodImplOptions), named.GetValue ().ToString ());
}
return (options & MethodImplOptions.InternalCall) != 0;
return options;
}
//
@ -1631,6 +1636,9 @@ namespace Mono.CSharp { @@ -1631,6 +1636,9 @@ namespace Mono.CSharp {
public readonly PredefinedDecimalAttribute DecimalConstant;
public readonly PredefinedAttribute StructLayout;
public readonly PredefinedAttribute FieldOffset;
public readonly PredefinedAttribute CallerMemberNameAttribute;
public readonly PredefinedAttribute CallerLineNumberAttribute;
public readonly PredefinedAttribute CallerFilePathAttribute;
public PredefinedAttributes (ModuleContainer module)
{
@ -1682,6 +1690,10 @@ namespace Mono.CSharp { @@ -1682,6 +1690,10 @@ namespace Mono.CSharp {
StructLayout = new PredefinedAttribute (module, "System.Runtime.InteropServices", "StructLayoutAttribute");
FieldOffset = new PredefinedAttribute (module, "System.Runtime.InteropServices", "FieldOffsetAttribute");
CallerMemberNameAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerMemberNameAttribute");
CallerLineNumberAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerLineNumberAttribute");
CallerFilePathAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerFilePathAttribute");
// TODO: Should define only attributes which are used for comparison
const System.Reflection.BindingFlags all_fields = System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly;

8
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cfold.cs

@ -149,7 +149,7 @@ namespace Mono.CSharp { @@ -149,7 +149,7 @@ namespace Mono.CSharp {
case Binary.Operator.ExclusiveOr:
result = BinaryFold (ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc);
if (result != null)
result = result.TryReduce (ec, lt, loc);
result = result.TryReduce (ec, lt);
return result;
///
@ -158,7 +158,7 @@ namespace Mono.CSharp { @@ -158,7 +158,7 @@ namespace Mono.CSharp {
case Binary.Operator.Subtraction:
result = BinaryFold (ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc);
if (result != null)
result = result.TryReduce (ec, EnumSpec.GetUnderlyingType (lt), loc);
result = result.TryReduce (ec, EnumSpec.GetUnderlyingType (lt));
return result;
///
@ -340,7 +340,7 @@ namespace Mono.CSharp { @@ -340,7 +340,7 @@ namespace Mono.CSharp {
if (result == null)
return null;
result = result.TryReduce (ec, lt, loc);
result = result.TryReduce (ec, lt);
if (result == null)
return null;
@ -459,7 +459,7 @@ namespace Mono.CSharp { @@ -459,7 +459,7 @@ namespace Mono.CSharp {
if (result == null)
return null;
result = result.TryReduce (ec, lt, loc);
result = result.TryReduce (ec, lt);
if (result == null)
return null;

97
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs

@ -85,16 +85,15 @@ namespace Mono.CSharp @@ -85,16 +85,15 @@ namespace Mono.CSharp
}
}
#if FULL_AST
//
// Any unattached attributes during parsing get added here.
// Any unattached attributes during parsing get added here. User
// by FULL_AST mode
//
public Attributes UnattachedAttributes {
get; set;
}
#endif
public virtual void AddCompilerGeneratedClass (CompilerGeneratedClass c)
public virtual void AddCompilerGeneratedClass (CompilerGeneratedContainer c)
{
containers.Add (c);
}
@ -747,7 +746,7 @@ namespace Mono.CSharp @@ -747,7 +746,7 @@ namespace Mono.CSharp
base.AddTypeContainer (tc);
}
public override void AddCompilerGeneratedClass (CompilerGeneratedClass c)
public override void AddCompilerGeneratedClass (CompilerGeneratedContainer c)
{
members.Add (c);
@ -1326,7 +1325,7 @@ namespace Mono.CSharp @@ -1326,7 +1325,7 @@ namespace Mono.CSharp
}
if (proxy_method == null) {
string name = CompilerGeneratedClass.MakeName (method.Name, null, "BaseCallProxy", hoisted_base_call_proxies.Count);
string name = CompilerGeneratedContainer.MakeName (method.Name, null, "BaseCallProxy", hoisted_base_call_proxies.Count);
var base_parameters = new Parameter[method.Parameters.Count];
for (int i = 0; i < base_parameters.Length; ++i) {
var base_param = method.Parameters.FixedParameters[i];
@ -1958,28 +1957,28 @@ namespace Mono.CSharp @@ -1958,28 +1957,28 @@ namespace Mono.CSharp
if (OptAttributes != null)
OptAttributes.Emit ();
if (!IsTopLevel) {
MemberSpec candidate;
bool overrides = false;
var conflict_symbol = MemberCache.FindBaseMember (this, out candidate, ref overrides);
if (conflict_symbol == null && candidate == null) {
if ((ModFlags & Modifiers.NEW) != 0)
Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
GetSignatureForError ());
} else {
if ((ModFlags & Modifiers.NEW) == 0) {
if (candidate == null)
candidate = conflict_symbol;
if (!IsCompilerGenerated) {
if (!IsTopLevel) {
MemberSpec candidate;
bool overrides = false;
var conflict_symbol = MemberCache.FindBaseMember (this, out candidate, ref overrides);
if (conflict_symbol == null && candidate == null) {
if ((ModFlags & Modifiers.NEW) != 0)
Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
GetSignatureForError ());
} else {
if ((ModFlags & Modifiers.NEW) == 0) {
if (candidate == null)
candidate = conflict_symbol;
Report.SymbolRelatedToPreviousError (candidate);
Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
GetSignatureForError (), candidate.GetSignatureForError ());
Report.SymbolRelatedToPreviousError (candidate);
Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
GetSignatureForError (), candidate.GetSignatureForError ());
}
}
}
}
// Run constraints check on all possible generic types
if ((ModFlags & Modifiers.COMPILER_GENERATED) == 0) {
// Run constraints check on all possible generic types
if (base_type != null && base_type_expr != null) {
ConstraintChecker.Check (this, base_type, base_type_expr.Location);
}
@ -2355,6 +2354,8 @@ namespace Mono.CSharp @@ -2355,6 +2354,8 @@ namespace Mono.CSharp
public abstract class ClassOrStruct : TypeDefinition
{
public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed;
SecurityType declarative_security;
public ClassOrStruct (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
@ -2364,7 +2365,19 @@ namespace Mono.CSharp @@ -2364,7 +2365,19 @@ namespace Mono.CSharp
protected override TypeAttributes TypeAttr {
get {
return has_static_constructor ? base.TypeAttr : base.TypeAttr | TypeAttributes.BeforeFieldInit;
TypeAttributes ta = base.TypeAttr;
if (!has_static_constructor)
ta |= TypeAttributes.BeforeFieldInit;
if (Kind == MemberKind.Class) {
ta |= TypeAttributes.AutoLayout | TypeAttributes.Class;
if (IsStatic)
ta |= StaticClassAttribute;
} else {
ta |= TypeAttributes.SequentialLayout;
}
return ta;
}
}
@ -2479,8 +2492,8 @@ namespace Mono.CSharp @@ -2479,8 +2492,8 @@ namespace Mono.CSharp
}
// TODO: should be sealed
public class Class : ClassOrStruct {
public sealed class Class : ClassOrStruct
{
const Modifiers AllowedModifiers =
Modifiers.NEW |
Modifiers.PUBLIC |
@ -2492,8 +2505,6 @@ namespace Mono.CSharp @@ -2492,8 +2505,6 @@ namespace Mono.CSharp
Modifiers.STATIC |
Modifiers.UNSAFE;
public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed;
public Class (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
: base (parent, name, attrs, MemberKind.Class)
{
@ -2687,23 +2698,10 @@ namespace Mono.CSharp @@ -2687,23 +2698,10 @@ namespace Mono.CSharp
caching_flags |= Flags.Excluded;
return conditions;
}
//
// FIXME: How do we deal with the user specifying a different
// layout?
//
protected override TypeAttributes TypeAttr {
get {
TypeAttributes ta = base.TypeAttr | TypeAttributes.AutoLayout | TypeAttributes.Class;
if (IsStatic)
ta |= StaticClassAttribute;
return ta;
}
}
}
public sealed class Struct : ClassOrStruct {
public sealed class Struct : ClassOrStruct
{
bool is_unmanaged, has_unmanaged_check_done;
bool InTransit;
@ -2875,17 +2873,6 @@ namespace Mono.CSharp @@ -2875,17 +2873,6 @@ namespace Mono.CSharp
return ifaces;
}
protected override TypeAttributes TypeAttr {
get {
const
TypeAttributes DefaultTypeAttributes =
TypeAttributes.SequentialLayout |
TypeAttributes.Sealed ;
return base.TypeAttr | DefaultTypeAttributes;
}
}
public override void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
{
if ((field.ModFlags & Modifiers.STATIC) == 0) {

42
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/codegen.cs

@ -83,6 +83,8 @@ namespace Mono.CSharp @@ -83,6 +83,8 @@ namespace Mono.CSharp
Label? return_label;
List<IExpressionCleanup> epilogue_expressions;
public EmitContext (IMemberContext rc, ILGenerator ig, TypeSpec return_type, SourceMethodBuilder methodSymbols)
{
this.member_context = rc;
@ -137,6 +139,12 @@ namespace Mono.CSharp @@ -137,6 +139,12 @@ namespace Mono.CSharp
}
}
public bool HasMethodSymbolBuilder {
get {
return methodSymbols != null;
}
}
public bool HasReturnLabel {
get {
return return_label.HasValue;
@ -190,8 +198,25 @@ namespace Mono.CSharp @@ -190,8 +198,25 @@ namespace Mono.CSharp
}
}
public List<IExpressionCleanup> StatementEpilogue {
get {
return epilogue_expressions;
}
}
#endregion
public void AddStatementEpilog (IExpressionCleanup cleanupExpression)
{
if (epilogue_expressions == null) {
epilogue_expressions = new List<IExpressionCleanup> ();
} else if (epilogue_expressions.Contains (cleanupExpression)) {
return;
}
epilogue_expressions.Add (cleanupExpression);
}
public void AssertEmptyStack ()
{
#if STATIC
@ -810,6 +835,17 @@ namespace Mono.CSharp @@ -810,6 +835,17 @@ namespace Mono.CSharp
ig.Emit (OpCodes.Ldarg_0);
}
public void EmitEpilogue ()
{
if (epilogue_expressions == null)
return;
foreach (var e in epilogue_expressions)
e.EmitCleanup (this);
epilogue_expressions = null;
}
/// <summary>
/// Returns a temporary storage for a variable of type t as
/// a local variable in the current body.
@ -1060,9 +1096,11 @@ namespace Mono.CSharp @@ -1060,9 +1096,11 @@ namespace Mono.CSharp
return false;
//
// It's non-virtual and will never be null
// It's non-virtual and will never be null and it can be determined
// whether it's known value or reference type by verifier
//
if (!method.IsVirtual && (instance is This || instance is New || instance is ArrayCreation || instance is DelegateCreation))
if (!method.IsVirtual && (instance is This || instance is New || instance is ArrayCreation || instance is DelegateCreation) &&
!instance.Type.IsGenericParameter)
return false;
return true;

2
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/const.cs

@ -205,7 +205,7 @@ namespace Mono.CSharp { @@ -205,7 +205,7 @@ namespace Mono.CSharp {
else if (!(expr is Constant))
Error_ExpressionMustBeConstant (rc, expr.Location, GetSignatureForError ());
else
expr.Error_ValueCannotBeConverted (rc, expr.Location, field.MemberType, false);
expr.Error_ValueCannotBeConverted (rc, field.MemberType, false);
}
expr = c;

39
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/constant.cs

@ -58,7 +58,7 @@ namespace Mono.CSharp { @@ -58,7 +58,7 @@ namespace Mono.CSharp {
}
#endif
public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
{
if (!expl && IsLiteral &&
BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (target) &&
@ -66,7 +66,7 @@ namespace Mono.CSharp { @@ -66,7 +66,7 @@ namespace Mono.CSharp {
ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
GetValueAsLiteral (), TypeManager.CSharpName (target));
} else {
base.Error_ValueCannotBeConverted (ec, loc, target, expl);
base.Error_ValueCannotBeConverted (ec, target, expl);
}
}
@ -74,7 +74,7 @@ namespace Mono.CSharp { @@ -74,7 +74,7 @@ namespace Mono.CSharp {
{
Constant c = ConvertImplicitly (type);
if (c == null)
Error_ValueCannotBeConverted (ec, loc, type, false);
Error_ValueCannotBeConverted (ec, type, false);
return c;
}
@ -160,8 +160,11 @@ namespace Mono.CSharp { @@ -160,8 +160,11 @@ namespace Mono.CSharp {
return new NullConstant (t, loc);
}
throw new InternalErrorException ("Constant value `{0}' has unexpected underlying type `{1}'",
v, TypeManager.CSharpName (t));
#if STATIC
throw new InternalErrorException ("Constant value `{0}' has unexpected underlying type `{1}'", v, t.GetSignatureForError ());
#else
return null;
#endif
}
public override Expression CreateExpressionTree (ResolveContext ec)
@ -251,32 +254,38 @@ namespace Mono.CSharp { @@ -251,32 +254,38 @@ namespace Mono.CSharp {
/// <summary>
/// Attempts to do a compile-time folding of a constant cast.
/// </summary>
public Constant TryReduce (ResolveContext ec, TypeSpec target_type, Location loc)
public Constant TryReduce (ResolveContext ec, TypeSpec target_type)
{
try {
return TryReduce (ec, target_type);
}
catch (OverflowException) {
return TryReduceConstant (ec, target_type);
} catch (OverflowException) {
if (ec.ConstantCheckState && Type.BuiltinType != BuiltinTypeSpec.Type.Decimal) {
ec.Report.Error (221, loc,
"Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)",
GetValueAsLiteral (), target_type.GetSignatureForError ());
} else {
Error_ValueCannotBeConverted (ec, loc, target_type, false);
Error_ValueCannotBeConverted (ec, target_type, false);
}
return New.Constantify (target_type, loc);
}
}
Constant TryReduce (ResolveContext ec, TypeSpec target_type)
Constant TryReduceConstant (ResolveContext ec, TypeSpec target_type)
{
if (Type == target_type)
if (Type == target_type) {
//
// Reducing literal value produces a new constant. Syntactically 10 is not same as (int)10
//
if (IsLiteral)
return CreateConstantFromValue (target_type, GetValue (), loc);
return this;
}
Constant c;
if (target_type.IsEnum) {
c = TryReduce (ec, EnumSpec.GetUnderlyingType (target_type));
c = TryReduceConstant (ec, EnumSpec.GetUnderlyingType (target_type));
if (c == null)
return null;
@ -378,11 +387,11 @@ namespace Mono.CSharp { @@ -378,11 +387,11 @@ namespace Mono.CSharp {
eclass = ExprClass.Value;
}
public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
{
try {
ConvertExplicitly (true, target);
base.Error_ValueCannotBeConverted (ec, loc, target, expl);
base.Error_ValueCannotBeConverted (ec, target, expl);
}
catch
{

2
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/context.cs

@ -481,7 +481,7 @@ namespace Mono.CSharp @@ -481,7 +481,7 @@ namespace Mono.CSharp
// or it's a parameter
//
if (CurrentAnonymousMethod is AsyncInitializer)
return CurrentBlock.Explicit.HasAwait;
return local.IsParameter || CurrentBlock.Explicit.HasAwait;
return local.Block.ParametersBlock != CurrentBlock.ParametersBlock.Original;
}

13
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/convert.cs

@ -495,6 +495,11 @@ namespace Mono.CSharp { @@ -495,6 +495,11 @@ namespace Mono.CSharp {
return ImplicitNumericConversion (expr, expr.Type, target_type);
}
public static bool ImplicitNumericConversionExists (TypeSpec expr_type, TypeSpec target_type)
{
return ImplicitNumericConversion (null, expr_type, target_type) != null;
}
static Expression ImplicitNumericConversion (Expression expr, TypeSpec expr_type, TypeSpec target_type)
{
switch (expr_type.BuiltinType) {
@ -1190,7 +1195,7 @@ namespace Mono.CSharp { @@ -1190,7 +1195,7 @@ namespace Mono.CSharp {
if (s_x != source_type) {
var c = source as Constant;
if (c != null) {
source = c.TryReduce (ec, s_x, loc);
source = c.TryReduce (ec, s_x);
} else {
source = implicitOnly ?
ImplicitConversionStandard (ec, source_type_expr, s_x, loc) :
@ -1418,7 +1423,7 @@ namespace Mono.CSharp { @@ -1418,7 +1423,7 @@ namespace Mono.CSharp {
if (e != null)
return e;
source.Error_ValueCannotBeConverted (ec, loc, target_type, false);
source.Error_ValueCannotBeConverted (ec, target_type, false);
return null;
}
@ -2098,7 +2103,7 @@ namespace Mono.CSharp { @@ -2098,7 +2103,7 @@ namespace Mono.CSharp {
if (ec.IsUnsafe && expr.Type.IsPointer && target_type.IsPointer && ((PointerContainer)expr.Type).Element.Kind == MemberKind.Void)
return EmptyCast.Create (expr, target_type);
expr.Error_ValueCannotBeConverted (ec, l, target_type, true);
expr.Error_ValueCannotBeConverted (ec, target_type, true);
return null;
}
@ -2161,7 +2166,7 @@ namespace Mono.CSharp { @@ -2161,7 +2166,7 @@ namespace Mono.CSharp {
if (e != null)
return e;
expr.Error_ValueCannotBeConverted (ec, loc, target_type, true);
expr.Error_ValueCannotBeConverted (ec, target_type, true);
return null;
}
}

8809
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs

File diff suppressed because it is too large Load Diff

130
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.jay

@ -400,6 +400,8 @@ outer_declaration @@ -400,6 +400,8 @@ outer_declaration
Attributes attrs = (Attributes) $4;
report.Error (1730, attrs.Attrs [0].Location,
"Assembly and module attributes must precede all other elements except using clauses and extern alias declarations");
current_namespace.UnattachedAttributes = attrs;
}
}
| opt_extern_alias_directives opt_using_directives attribute_sections
@ -618,9 +620,7 @@ namespace_or_type_declaration @@ -618,9 +620,7 @@ namespace_or_type_declaration
current_namespace.DeclarationFound = true;
}
| attribute_sections CLOSE_BRACE {
#if FULL_AST
current_namespace.UnattachedAttributes = (Attributes) $1;
#endif
report.Error (1518, lexer.Location, "Attributes must be attached to class, delegate, enum, interface or struct");
lexer.putback ('}');
}
@ -1521,12 +1521,18 @@ fixed_parameter @@ -1521,12 +1521,18 @@ fixed_parameter
$$ = new Parameter ((FullNamedExpression) $3, lt.Value, (Parameter.Modifier) $2, (Attributes) $1, lt.Location);
lbag.AddLocation ($$, parameterModifierLocation);
}
| attribute_sections error
{
Error_SyntaxError (yyToken);
Location l = GetLocation ($2);
$$ = new Parameter (null, null, Parameter.Modifier.NONE, (Attributes) $1, l);
}
| opt_attributes
opt_parameter_modifier
parameter_type
error
{
Error_SyntaxError (yyToken);
Error_SyntaxError (yyToken);
Location l = GetLocation ($4);
$$ = new Parameter ((FullNamedExpression) $3, null, (Parameter.Modifier) $2, (Attributes) $1, l);
lbag.AddLocation ($$, parameterModifierLocation);
@ -2536,10 +2542,9 @@ event_accessor_block @@ -2536,10 +2542,9 @@ event_accessor_block
;
attributes_without_members
: attribute_sections CLOSE_BRACE {
#if FULL_AST
: attribute_sections CLOSE_BRACE
{
current_type.UnattachedAttributes = (Attributes) $1;
#endif
report.Error (1519, GetLocation ($1), "An attribute is missing member declaration");
lexer.putback ('}');
}
@ -2565,7 +2570,7 @@ enum_declaration @@ -2565,7 +2570,7 @@ enum_declaration
report.Error (1675, name.Location, "Enums cannot have type parameters");
}
push_current_container (new Enum (current_container, (TypeExpression) $5, (Modifiers) $2, name, (Attributes) $1), null);
push_current_container (new Enum (current_container, (FullNamedExpression) $5, (Modifiers) $2, name, (Attributes) $1), null);
if ($5 != null) {
lbag.AddMember (current_container, GetModifierLocations (), GetLocation ($3), savedLocation, GetLocation ($7));
} else {
@ -2600,14 +2605,8 @@ opt_enum_base @@ -2600,14 +2605,8 @@ opt_enum_base
: /* empty */
| COLON type
{
var te = $2 as TypeExpression;
if (te == null || !EnumSpec.IsValidUnderlyingType (te.Type)) {
Enum.Error_1008 (GetLocation ($2), report);
$$ = null;
} else {
savedLocation = GetLocation ($1);
$$ = $2;
}
savedLocation = GetLocation ($1);
$$ = $2;
}
| COLON error
{
@ -3326,10 +3325,10 @@ argument_list @@ -3326,10 +3325,10 @@ argument_list
lbag.AppendTo (list, GetLocation ($2));
$$ = list;
}
| argument_list COMMA
| argument_list COMMA error
{
report.Error (839, GetLocation ($2), "An argument is missing");
$$ = $1;
Error_SyntaxError (yyToken);
$$ = $1;
}
| COMMA error
{
@ -3386,10 +3385,12 @@ element_access @@ -3386,10 +3385,12 @@ element_access
}
| primary_expression OPEN_BRACKET_EXPR expression_list_arguments error
{
Error_SyntaxError (yyToken);
$$ = new ElementAccess ((Expression) $1, (Arguments) $3, GetLocation ($2));
}
| primary_expression OPEN_BRACKET_EXPR error
{
Error_SyntaxError (yyToken);
$$ = new ElementAccess ((Expression) $1, null, GetLocation ($2));
}
;
@ -3530,8 +3531,9 @@ array_creation_expression @@ -3530,8 +3531,9 @@ array_creation_expression
}
| NEW new_expr_type error
{
Error_SyntaxError (1526, yyToken, "Unexpected symbol");
$$ = new ArrayCreation ((FullNamedExpression) $2, null, GetLocation ($1));
Error_SyntaxError (yyToken);
// It can be any of new expression, create the most common one
$$ = new New ((FullNamedExpression) $2, null, GetLocation ($1));
}
;
@ -3899,8 +3901,16 @@ unary_expression @@ -3899,8 +3901,16 @@ unary_expression
| AWAIT prefixed_unary_expression
{
if (!async_block) {
report.Error (1992, GetLocation ($1),
"The `await' operator can only be used when its containing method or lambda expression is marked with the `async' modifier");
if (current_anonymous_method is LambdaExpression) {
report.Error (4034, GetLocation ($1),
"The `await' operator can only be used when its containing lambda expression is marked with the `async' modifier");
} else if (current_anonymous_method is AnonymousMethodExpression) {
report.Error (4035, GetLocation ($1),
"The `await' operator can only be used when its containing anonymous method is marked with the `async' modifier");
} else {
report.Error (4033, GetLocation ($1),
"The `await' operator can only be used when its containing method is marked with the `async' modifier");
}
} else {
current_block.Explicit.RegisterAsyncAwait ();
}
@ -4101,6 +4111,11 @@ conditional_expression @@ -4101,6 +4111,11 @@ conditional_expression
$$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, (Expression) $5, GetLocation ($2));
lbag.AddLocation ($$, GetLocation ($4));
}
| null_coalescing_expression INTERR expression error
{
Error_SyntaxError (yyToken);
$$ = new Conditional (new BooleanExpression ((Expression) $1), (Expression) $3, null, GetLocation ($2));
}
;
assignment_expression
@ -5293,6 +5308,11 @@ switch_label @@ -5293,6 +5308,11 @@ switch_label
$$ = new SwitchLabel ((Expression) $2, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($3));
}
| CASE constant_expression error
{
Error_SyntaxError (yyToken);
$$ = new SwitchLabel ((Expression) $2, GetLocation ($1));
}
| DEFAULT_COLON
{
$$ = new SwitchLabel (null, GetLocation ($1));
@ -5394,7 +5414,7 @@ for_statement_condition @@ -5394,7 +5414,7 @@ for_statement_condition
{
$$ = $4;
}
| opt_for_condition CLOSE_PARENS {
| boolean_expression CLOSE_PARENS {
report.Error (1525, GetLocation ($2), "Unexpected symbol ')', expected ';'");
For f = (For) $0;
f.Condition = (BooleanExpression) $1;
@ -5471,6 +5491,7 @@ statement_expression_list @@ -5471,6 +5491,7 @@ statement_expression_list
} else {
sl.Add ((Statement) $3);
lbag.AppendTo (sl, GetLocation ($2));
}
$$ = sl;
@ -5485,7 +5506,7 @@ foreach_statement @@ -5485,7 +5506,7 @@ foreach_statement
start_block (GetLocation ($2));
current_block.IsCompilerGenerated = true;
Foreach f = new Foreach ((Expression) $3, null, null, null, GetLocation ($1));
Foreach f = new Foreach ((Expression) $3, null, null, null, null, GetLocation ($1));
current_block.AddStatement (f);
lbag.AddStatement (f, GetLocation ($2));
@ -5494,7 +5515,7 @@ foreach_statement @@ -5494,7 +5515,7 @@ foreach_statement
| FOREACH open_parens_any type identifier_inside_body error
{
Error_SyntaxError (yyToken);
start_block (GetLocation ($2));
current_block.IsCompilerGenerated = true;
@ -5502,7 +5523,7 @@ foreach_statement @@ -5502,7 +5523,7 @@ foreach_statement
var li = new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ForeachVariable | LocalVariable.Flags.Used, lt.Location);
current_block.AddLocalName (li);
Foreach f = new Foreach ((Expression) $3, li, null, null, GetLocation ($1));
Foreach f = new Foreach ((Expression) $3, li, null, null, null, GetLocation ($1));
current_block.AddStatement (f);
lbag.AddStatement (f, GetLocation ($2));
@ -5521,12 +5542,12 @@ foreach_statement @@ -5521,12 +5542,12 @@ foreach_statement
{
if ($9 is EmptyStatement && lexer.peek_token () == Token.OPEN_BRACE)
Warning_EmptyStatement (GetLocation ($9));
Foreach f = new Foreach ((Expression) $3, (LocalVariable) $8, (Expression) $6, (Statement) $9, GetLocation ($1));
current_block.AddStatement (f);
Foreach f = new Foreach ((Expression) $3, (LocalVariable) $8, (Expression) $6, (Statement) $9, current_block, GetLocation ($1));
lbag.AddStatement (f, GetLocation ($2), GetLocation ($5), GetLocation ($7));
$$ = end_block (GetLocation ($7));
end_block (GetLocation ($7));
$$ = f;
}
| FOREACH open_parens_any type identifier_inside_body error
{
@ -5535,7 +5556,7 @@ foreach_statement @@ -5535,7 +5556,7 @@ foreach_statement
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));
Foreach f = new Foreach ((Expression) $3, li, null, null, null, GetLocation ($1));
current_block.AddStatement (f);
lbag.AddStatement (f, GetLocation ($2));
@ -5543,7 +5564,7 @@ foreach_statement @@ -5543,7 +5564,7 @@ foreach_statement
}
| FOREACH open_parens_any type error
{
Foreach f = new Foreach ((Expression) $3, null, null, null, GetLocation ($1));
Foreach f = new Foreach ((Expression) $3, null, null, null, null, GetLocation ($1));
current_block.AddStatement (f);
lbag.AddStatement (f, GetLocation ($2));
@ -5574,6 +5595,11 @@ continue_statement @@ -5574,6 +5595,11 @@ continue_statement
$$ = new Continue (GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($2));
}
| CONTINUE error
{
Error_SyntaxError (yyToken);
$$ = new Continue (GetLocation ($1));
}
;
goto_statement
@ -5601,6 +5627,11 @@ return_statement @@ -5601,6 +5627,11 @@ return_statement
$$ = new Return ((Expression) $2, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($3));
}
| RETURN error
{
Error_SyntaxError (yyToken);
$$ = new Return (null, GetLocation ($1));
}
;
throw_statement
@ -5609,6 +5640,11 @@ throw_statement @@ -5609,6 +5640,11 @@ throw_statement
$$ = new Throw ((Expression) $2, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($3));
}
| THROW error
{
Error_SyntaxError (yyToken);
$$ = new Throw (null, GetLocation ($1));
}
;
yield_statement
@ -6003,7 +6039,7 @@ from_clause @@ -6003,7 +6039,7 @@ from_clause
;
query_body
: opt_query_body_clauses select_or_group_clause opt_query_continuation
: query_body_clauses select_or_group_clause opt_query_continuation
{
Linq.AQueryClause head = (Linq.AQueryClause)$2;
@ -6018,7 +6054,24 @@ query_body @@ -6018,7 +6054,24 @@ query_body
$$ = head;
}
| opt_query_body_clauses COMPLETE_COMPLETION
| select_or_group_clause opt_query_continuation
{
Linq.AQueryClause head = (Linq.AQueryClause)$2;
if ($1 != null) {
Linq.AQueryClause clause = (Linq.AQueryClause)$1;
clause.Tail.Next = head;
head = clause;
}
$$ = head;
}
| query_body_clauses COMPLETE_COMPLETION
| query_body_clauses error
{
report.Error (742, GetLocation ($2), "Unexpected symbol `{0}'. A query body must end with select or group clause", GetSymbolName (yyToken));
$$ = $1;
}
| error
{
Error_SyntaxError (yyToken);
@ -6063,11 +6116,6 @@ select_or_group_clause @@ -6063,11 +6116,6 @@ select_or_group_clause
}
;
opt_query_body_clauses
: /* empty */
| query_body_clauses
;
query_body_clauses
: query_body_clause
| query_body_clauses query_body_clause
@ -6773,10 +6821,10 @@ public void parse () @@ -6773,10 +6821,10 @@ public void parse ()
report.Error (-25, lexer.Location, "Parsing error");
} else {
// Used by compiler-tester to test internal errors
if (yacc_verbose_flag > 0)
if (yacc_verbose_flag > 0 || e is FatalException)
throw;
report.Error (589, lexer.Location, "Internal compiler error during parsing");
report.Error (589, lexer.Location, "Internal compiler error during parsing" + e);
}
}
}

22
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs

@ -137,6 +137,11 @@ namespace Mono.CSharp @@ -137,6 +137,11 @@ namespace Mono.CSharp
pos = 0;
}
public override string ToString ()
{
return string.Format ("Token '{0}' at {1},{2}", Value, row, column);
}
public Location Location {
get { return new Location (row, column); }
}
@ -1266,10 +1271,24 @@ namespace Mono.CSharp @@ -1266,10 +1271,24 @@ namespace Mono.CSharp
int ntoken;
int interrs = 1;
int colons = 0;
int braces = 0;
//
// All shorcuts failed, do it hard way
//
while ((ntoken = xtoken ()) != Token.EOF) {
if (ntoken == Token.OPEN_BRACE) {
++braces;
continue;
}
if (ntoken == Token.CLOSE_BRACE) {
--braces;
continue;
}
if (braces != 0)
continue;
if (ntoken == Token.SEMICOLON)
break;
@ -1285,7 +1304,7 @@ namespace Mono.CSharp @@ -1285,7 +1304,7 @@ namespace Mono.CSharp
}
}
next_token = colons != interrs ? Token.INTERR_NULLABLE : Token.INTERR;
next_token = colons != interrs && braces == 0 ? Token.INTERR_NULLABLE : Token.INTERR;
break;
}
}
@ -1535,6 +1554,7 @@ namespace Mono.CSharp @@ -1535,6 +1554,7 @@ namespace Mono.CSharp
#endif
number_pos = 0;
var loc = Location;
bool hasLeadingDot = c == '.';
if (c >= '0' && c <= '9'){
if (c == '0'){

17
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/decl.cs

@ -299,7 +299,8 @@ namespace Mono.CSharp { @@ -299,7 +299,8 @@ namespace Mono.CSharp {
PartialDefinitionExists = 1 << 14, // Set when corresponding partial method definition exists
HasStructLayout = 1 << 15, // Has StructLayoutAttribute
HasInstanceConstructor = 1 << 16,
HasUserOperators = 1 << 17
HasUserOperators = 1 << 17,
CanBeReused = 1 << 18
}
/// <summary>
@ -425,6 +426,15 @@ namespace Mono.CSharp { @@ -425,6 +426,15 @@ namespace Mono.CSharp {
VerifyClsCompliance ();
}
public bool IsAvailableForReuse {
get {
return (caching_flags & Flags.CanBeReused) != 0;
}
set {
caching_flags = value ? (caching_flags | Flags.CanBeReused) : (caching_flags & ~Flags.CanBeReused);
}
}
public bool IsCompilerGenerated {
get {
if ((mod_flags & Modifiers.COMPILER_GENERATED) != 0)
@ -810,6 +820,11 @@ namespace Mono.CSharp { @@ -810,6 +820,11 @@ namespace Mono.CSharp {
Report.Warning (3008, 1, MemberName.Location, "Identifier `{0}' is not CLS-compliant", GetSignatureForError ());
}
public virtual string GetCallerMemberName ()
{
return MemberName.Name;
}
//
// Returns a string that represents the signature for this
// member which should be used in XML documentation.

8
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/delegate.cs

@ -220,7 +220,7 @@ namespace Mono.CSharp { @@ -220,7 +220,7 @@ namespace Mono.CSharp {
var p = parameters[i];
compiled[i] = new Parameter (new TypeExpression (parameters.Types[i], Location),
p.Name,
p.ModFlags & (Parameter.Modifier.REF | Parameter.Modifier.OUT),
p.ModFlags & Parameter.Modifier.RefOutMask,
p.OptAttributes == null ? null : p.OptAttributes.Clone (), Location);
}
@ -255,7 +255,7 @@ namespace Mono.CSharp { @@ -255,7 +255,7 @@ namespace Mono.CSharp {
int out_params = 0;
foreach (Parameter p in Parameters.FixedParameters) {
if ((p.ModFlags & Parameter.Modifier.ISBYREF) != 0)
if ((p.ModFlags & Parameter.Modifier.RefOutMask) != 0)
++out_params;
}
@ -265,12 +265,12 @@ namespace Mono.CSharp { @@ -265,12 +265,12 @@ namespace Mono.CSharp {
int param = 0;
for (int i = 0; i < Parameters.FixedParameters.Length; ++i) {
Parameter p = parameters [i];
if ((p.ModFlags & Parameter.Modifier.ISBYREF) == 0)
if ((p.ModFlags & Parameter.Modifier.RefOutMask) == 0)
continue;
end_params [param++] = new Parameter (new TypeExpression (p.Type, Location),
p.Name,
p.ModFlags & (Parameter.Modifier.REF | Parameter.Modifier.OUT),
p.ModFlags & Parameter.Modifier.RefOutMask,
p.OptAttributes == null ? null : p.OptAttributes.Clone (), Location);
}

112
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/doc.cs

@ -397,10 +397,15 @@ namespace Mono.CSharp @@ -397,10 +397,15 @@ namespace Mono.CSharp
if (ParsedParameters != null) {
var old_printer = mc.Module.Compiler.Report.SetPrinter (new NullReportPrinter ());
foreach (var pp in ParsedParameters) {
pp.Resolve (mc);
try {
var context = new DocumentationMemberContext (mc, ParsedName ?? MemberName.Null);
foreach (var pp in ParsedParameters) {
pp.Resolve (context);
}
} finally {
mc.Module.Compiler.Report.SetPrinter (old_printer);
}
mc.Module.Compiler.Report.SetPrinter (old_printer);
}
if (type != null) {
@ -433,13 +438,15 @@ namespace Mono.CSharp @@ -433,13 +438,15 @@ namespace Mono.CSharp
if (m.Kind == MemberKind.Operator && !ParsedOperator.HasValue)
continue;
var pm_params = pm.Parameters;
int i;
for (i = 0; i < parsed_param_count; ++i) {
var pparam = ParsedParameters[i];
if (i >= pm.Parameters.Count || pparam == null ||
pparam.TypeSpec != pm.Parameters.Types[i] ||
(pparam.Modifier & Parameter.Modifier.SignatureMask) != (pm.Parameters.FixedParameters[i].ModFlags & Parameter.Modifier.SignatureMask)) {
if (i >= pm_params.Count || pparam == null || pparam.TypeSpec == null ||
!TypeSpecComparer.Override.IsEqual (pparam.TypeSpec, pm_params.Types[i]) ||
(pparam.Modifier & Parameter.Modifier.RefOutMask) != (pm_params.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask)) {
if (i > parameters_match) {
parameters_match = i;
@ -459,7 +466,7 @@ namespace Mono.CSharp @@ -459,7 +466,7 @@ namespace Mono.CSharp
continue;
}
} else {
if (parsed_param_count != pm.Parameters.Count)
if (parsed_param_count != pm_params.Count)
continue;
}
}
@ -612,6 +619,97 @@ namespace Mono.CSharp @@ -612,6 +619,97 @@ namespace Mono.CSharp
}
}
//
// Type lookup of documentation references uses context of type where
// the reference is used but type parameters from cref value
//
sealed class DocumentationMemberContext : IMemberContext
{
readonly MemberCore host;
MemberName contextName;
public DocumentationMemberContext (MemberCore host, MemberName contextName)
{
this.host = host;
this.contextName = contextName;
}
public TypeSpec CurrentType {
get {
return host.CurrentType;
}
}
public TypeParameters CurrentTypeParameters {
get {
return contextName.TypeParameters;
}
}
public MemberCore CurrentMemberDefinition {
get {
return host.CurrentMemberDefinition;
}
}
public bool IsObsolete {
get {
return false;
}
}
public bool IsUnsafe {
get {
return host.IsStatic;
}
}
public bool IsStatic {
get {
return host.IsStatic;
}
}
public ModuleContainer Module {
get {
return host.Module;
}
}
public string GetSignatureForError ()
{
return host.GetSignatureForError ();
}
public ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
{
return null;
}
public FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
{
if (arity == 0) {
var tp = CurrentTypeParameters;
if (tp != null) {
for (int i = 0; i < tp.Count; ++i) {
var t = tp[i];
if (t.Name == name) {
t.Type.DeclaredPosition = i;
return new TypeParameterExpr (t, loc);
}
}
}
}
return host.Parent.LookupNamespaceOrType (name, arity, mode, loc);
}
public FullNamedExpression LookupNamespaceAlias (string name)
{
throw new NotImplementedException ();
}
}
class DocumentationParameter
{
public readonly Parameter.Modifier Modifier;

6
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/driver.cs

@ -259,6 +259,12 @@ namespace Mono.CSharp @@ -259,6 +259,12 @@ namespace Mono.CSharp
output_file = output_file_name;
} else {
output_file_name = Path.GetFileName (output_file);
if (string.IsNullOrEmpty (Path.GetFileNameWithoutExtension (output_file_name)) ||
output_file_name.IndexOfAny (Path.GetInvalidFileNameChars ()) >= 0) {
Report.Error (2021, "Output file name is not valid");
return false;
}
}
#if STATIC

2
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/dynamic.cs

@ -949,7 +949,7 @@ namespace Mono.CSharp @@ -949,7 +949,7 @@ namespace Mono.CSharp
sealed class DynamicSiteClass : HoistedStoreyClass
{
public DynamicSiteClass (TypeDefinition parent, MemberBase host, TypeParameters tparams)
: base (parent, MakeMemberName (host, "DynamicSite", parent.DynamicSitesCounter, tparams, Location.Null), tparams, Modifiers.STATIC)
: base (parent, MakeMemberName (host, "DynamicSite", parent.DynamicSitesCounter, tparams, Location.Null), tparams, Modifiers.STATIC, MemberKind.Class)
{
parent.DynamicSitesCounter++;
}

146
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/ecore.cs

@ -118,6 +118,11 @@ namespace Mono.CSharp { @@ -118,6 +118,11 @@ namespace Mono.CSharp {
bool IsFixed { get; }
}
public interface IExpressionCleanup
{
void EmitCleanup (EmitContext ec);
}
/// <remarks>
/// Base class for expressions
/// </remarks>
@ -222,8 +227,7 @@ namespace Mono.CSharp { @@ -222,8 +227,7 @@ namespace Mono.CSharp {
public static void Error_InvalidExpressionStatement (Report Report, Location loc)
{
Report.Error (201, loc, "Only assignment, call, increment, decrement, and new object " +
"expressions can be used as a statement");
Report.Error (201, loc, "Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement");
}
public void Error_InvalidExpressionStatement (BlockContext ec)
@ -236,7 +240,7 @@ namespace Mono.CSharp { @@ -236,7 +240,7 @@ namespace Mono.CSharp {
Report.Error (1547, loc, "Keyword `void' cannot be used in this context");
}
public virtual void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
public virtual void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
{
Error_ValueCannotBeConvertedCore (ec, loc, target, expl);
}
@ -316,7 +320,7 @@ namespace Mono.CSharp { @@ -316,7 +320,7 @@ namespace Mono.CSharp {
TypeManager.CSharpName (type), name);
}
public void Error_ValueAssignment (ResolveContext rc, Expression rhs)
public virtual void Error_ValueAssignment (ResolveContext rc, Expression rhs)
{
if (rhs == EmptyExpression.LValueMemberAccess || rhs == EmptyExpression.LValueMemberOutAccess) {
rc.Report.SymbolRelatedToPreviousError (type);
@ -536,38 +540,40 @@ namespace Mono.CSharp { @@ -536,38 +540,40 @@ namespace Mono.CSharp {
ec.EmitThis ();
// Emit original code
EmitToFieldSource (ec);
//
// Store the result to temporary field when we
// cannot load `this' directly
//
var field = ec.GetTemporaryField (type);
if (needs_temporary) {
var field = EmitToFieldSource (ec);
if (field == null) {
//
// Create temporary local (we cannot load `this' before Emit)
// Store the result to temporary field when we
// cannot load `this' directly
//
var temp = ec.GetTemporaryLocal (type);
ec.Emit (OpCodes.Stloc, temp);
field = ec.GetTemporaryField (type);
if (needs_temporary) {
//
// Create temporary local (we cannot load `this' before Emit)
//
var temp = ec.GetTemporaryLocal (type);
ec.Emit (OpCodes.Stloc, temp);
ec.EmitThis ();
ec.Emit (OpCodes.Ldloc, temp);
field.EmitAssignFromStack (ec);
ec.EmitThis ();
ec.Emit (OpCodes.Ldloc, temp);
field.EmitAssignFromStack (ec);
ec.FreeTemporaryLocal (temp, type);
} else {
field.EmitAssignFromStack (ec);
ec.FreeTemporaryLocal (temp, type);
} else {
field.EmitAssignFromStack (ec);
}
}
return field;
}
protected virtual void EmitToFieldSource (EmitContext ec)
protected virtual FieldExpr EmitToFieldSource (EmitContext ec)
{
//
// Default implementation calls Emit method
//
Emit (ec);
return null;
}
protected static void EmitExpressionsList (EmitContext ec, List<Expression> expressions)
@ -909,7 +915,7 @@ namespace Mono.CSharp { @@ -909,7 +915,7 @@ namespace Mono.CSharp {
converted = Convert.ImplicitConversion (ec, source, btypes.ULong, source.loc);
if (converted == null) {
source.Error_ValueCannotBeConverted (ec, source.loc, btypes.Int, false);
source.Error_ValueCannotBeConverted (ec, btypes.Int, false);
return null;
}
}
@ -1025,6 +1031,12 @@ namespace Mono.CSharp { @@ -1025,6 +1031,12 @@ namespace Mono.CSharp {
if (es == null)
Error_InvalidExpressionStatement (ec);
if (ec.CurrentAnonymousMethod is AsyncInitializer && !(e is Assign) &&
(e.Type.IsGenericTask || e.Type == ec.Module.PredefinedTypes.Task.TypeSpec)) {
ec.Report.Warning (4014, 1, e.Location,
"The statement is not awaited and execution of current method continues before the call is completed. Consider using `await' operator");
}
return es;
}
@ -1926,6 +1938,12 @@ namespace Mono.CSharp { @@ -1926,6 +1938,12 @@ namespace Mono.CSharp {
#region Properties
public override bool IsSideEffectFree {
get {
return expr.IsSideEffectFree;
}
}
public Expression OriginalExpression {
get {
return orig_expr;
@ -1998,6 +2016,11 @@ namespace Mono.CSharp { @@ -1998,6 +2016,11 @@ namespace Mono.CSharp {
expr.Emit (ec);
}
public override Expression EmitToField (EmitContext ec)
{
return expr.EmitToField(ec);
}
public override void EmitBranchable (EmitContext ec, Label target, bool on_true)
{
expr.EmitBranchable (ec, target, on_true);
@ -2473,6 +2496,12 @@ namespace Mono.CSharp { @@ -2473,6 +2496,12 @@ namespace Mono.CSharp {
ErrorIsInaccesible (rc, e.GetSignatureForError (), loc);
return e;
}
} else {
var me = MemberLookup (rc, false, rc.CurrentType, Name, Arity, restrictions & ~MemberLookupRestrictions.InvocableOnly, loc) as MemberExpr;
if (me != null) {
me.Error_UnexpectedKind (rc, me, "method group", me.KindName, loc);
return ErrorExpression.Instance;
}
}
e = rc.LookupNamespaceOrType (Name, -System.Math.Max (1, Arity), LookupMode.Probing, loc);
@ -3330,7 +3359,7 @@ namespace Mono.CSharp { @@ -3330,7 +3359,7 @@ namespace Mono.CSharp {
call.Emit (ec, best_candidate, arguments, loc);
}
public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
{
ec.Report.Error (428, loc, "Cannot convert method group `{0}' to non-delegate type `{1}'. Consider using parentheses to invoke the method",
Name, TypeManager.CSharpName (target));
@ -4031,10 +4060,15 @@ namespace Mono.CSharp { @@ -4031,10 +4060,15 @@ namespace Mono.CSharp {
Arguments orig_args = arguments;
if (arg_count != param_count) {
for (int i = 0; i < pd.Count; ++i) {
if (pd.FixedParameters[i].HasDefaultValue) {
optional_count = pd.Count - i;
break;
//
// No arguments expansion when doing exact match for delegates
//
if ((restrictions & Restrictions.CovariantDelegate) == 0) {
for (int i = 0; i < pd.Count; ++i) {
if (pd.FixedParameters[i].HasDefaultValue) {
optional_count = pd.Count - i;
break;
}
}
}
@ -4210,7 +4244,8 @@ namespace Mono.CSharp { @@ -4210,7 +4244,8 @@ namespace Mono.CSharp {
for (int i = 0; i < arg_count; i++) {
Argument a = arguments[i];
if (a == null) {
if (!pd.FixedParameters[i].HasDefaultValue) {
var fp = pd.FixedParameters[i];
if (!fp.HasDefaultValue) {
arguments = orig_args;
return arg_count * 2 + 2;
}
@ -4219,7 +4254,7 @@ namespace Mono.CSharp { @@ -4219,7 +4254,7 @@ namespace Mono.CSharp {
// Get the default value expression, we can use the same expression
// if the type matches
//
Expression e = pd.FixedParameters[i].DefaultValue;
Expression e = fp.DefaultValue;
if (!(e is Constant) || e.Type.IsGenericOrParentIsGeneric || e.Type.IsGenericParameter) {
//
// LAMESPEC: No idea what the exact rules are for System.Reflection.Missing.Value instead of null
@ -4234,6 +4269,19 @@ namespace Mono.CSharp { @@ -4234,6 +4269,19 @@ namespace Mono.CSharp {
e = e.Resolve (ec);
}
if ((fp.ModFlags & Parameter.Modifier.CallerMask) != 0) {
//
// LAMESPEC: Attributes can be mixed together with build-in priority
//
if ((fp.ModFlags & Parameter.Modifier.CallerLineNumber) != 0) {
e = new IntLiteral (ec.BuiltinTypes, loc.Row, loc);
} else if ((fp.ModFlags & Parameter.Modifier.CallerFilePath) != 0) {
e = new StringLiteral (ec.BuiltinTypes, loc.NameFullPath, loc);
} else if (ec.MemberContext.CurrentMemberDefinition != null) {
e = new StringLiteral (ec.BuiltinTypes, ec.MemberContext.CurrentMemberDefinition.GetCallerMemberName (), loc);
}
}
arguments[i] = new Argument (e, Argument.AType.Default);
continue;
}
@ -4264,7 +4312,7 @@ namespace Mono.CSharp { @@ -4264,7 +4312,7 @@ namespace Mono.CSharp {
continue;
}
} else {
score = IsArgumentCompatible (ec, a, p_mod & ~Parameter.Modifier.PARAMS, pt);
score = IsArgumentCompatible (ec, a, p_mod, pt);
if (score < 0)
dynamicArgument = true;
@ -4325,7 +4373,7 @@ namespace Mono.CSharp { @@ -4325,7 +4373,7 @@ namespace Mono.CSharp {
// Types have to be identical when ref or out modifer
// is used and argument is not of dynamic type
//
if ((argument.Modifier | param_mod) != 0) {
if (((argument.Modifier | param_mod) & Parameter.Modifier.RefOutMask) != 0) {
if (argument.Type != parameter) {
//
// Do full equality check after quick path
@ -4334,18 +4382,18 @@ namespace Mono.CSharp { @@ -4334,18 +4382,18 @@ namespace Mono.CSharp {
//
// Using dynamic for ref/out parameter can still succeed at runtime
//
if (argument.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic && argument.Modifier == 0 && (restrictions & Restrictions.CovariantDelegate) == 0)
if (argument.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic && (argument.Modifier & Parameter.Modifier.RefOutMask) == 0 && (restrictions & Restrictions.CovariantDelegate) == 0)
return -1;
return 2;
}
}
if (argument.Modifier != param_mod) {
if ((argument.Modifier & Parameter.Modifier.RefOutMask) != (param_mod & Parameter.Modifier.RefOutMask)) {
//
// Using dynamic for ref/out parameter can still succeed at runtime
//
if (argument.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic && argument.Modifier == 0 && (restrictions & Restrictions.CovariantDelegate) == 0)
if (argument.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic && (argument.Modifier & Parameter.Modifier.RefOutMask) == 0 && (restrictions & Restrictions.CovariantDelegate) == 0)
return -1;
return 1;
@ -4718,9 +4766,12 @@ namespace Mono.CSharp { @@ -4718,9 +4766,12 @@ namespace Mono.CSharp {
if (custom_errors != null && custom_errors.ArgumentMismatch (ec, method, a, idx))
return;
if (a.Type == InternalType.ErrorType)
return;
if (a is CollectionElementInitializer.ElementInitializerArgument) {
ec.Report.SymbolRelatedToPreviousError (method);
if ((expected_par.FixedParameters[idx].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
if ((expected_par.FixedParameters[idx].ModFlags & Parameter.Modifier.RefOutMask) != 0) {
ec.Report.Error (1954, loc, "The best overloaded collection initalizer method `{0}' cannot have 'ref', or `out' modifier",
TypeManager.CSharpSignature (method));
return;
@ -4730,7 +4781,7 @@ namespace Mono.CSharp { @@ -4730,7 +4781,7 @@ namespace Mono.CSharp {
} else if (IsDelegateInvoke) {
ec.Report.Error (1594, loc, "Delegate `{0}' has some invalid arguments",
DelegateType.GetSignatureForError ());
} else if (a.Type != InternalType.ErrorType) {
} else {
ec.Report.SymbolRelatedToPreviousError (method);
ec.Report.Error (1502, loc, "The best overloaded method match for `{0}' has some invalid arguments",
method.GetSignatureForError ());
@ -4739,15 +4790,14 @@ namespace Mono.CSharp { @@ -4739,15 +4790,14 @@ namespace Mono.CSharp {
Parameter.Modifier mod = idx >= expected_par.Count ? 0 : expected_par.FixedParameters[idx].ModFlags;
string index = (idx + 1).ToString ();
if (((mod & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) ^
(a.Modifier & (Parameter.Modifier.REF | Parameter.Modifier.OUT))) != 0) {
if ((mod & Parameter.Modifier.ISBYREF) == 0)
if (((mod & Parameter.Modifier.RefOutMask) ^ (a.Modifier & Parameter.Modifier.RefOutMask)) != 0) {
if ((mod & Parameter.Modifier.RefOutMask) == 0)
ec.Report.Error (1615, loc, "Argument `#{0}' does not require `{1}' modifier. Consider removing `{1}' modifier",
index, Parameter.GetModifierSignature (a.Modifier));
else
ec.Report.Error (1620, loc, "Argument `#{0}' is missing `{1}' modifier",
index, Parameter.GetModifierSignature (mod));
} else if (a.Type != InternalType.ErrorType) {
} else {
string p1 = a.GetSignatureForError ();
string p2 = TypeManager.CSharpName (paramType);
@ -4876,8 +4926,8 @@ namespace Mono.CSharp { @@ -4876,8 +4926,8 @@ namespace Mono.CSharp {
//
// Types have to be identical when ref or out modifer is used
//
if (a.Modifier != 0 || (p_mod & ~Parameter.Modifier.PARAMS) != 0) {
if ((p_mod & ~Parameter.Modifier.PARAMS) != a.Modifier)
if (((a.Modifier | p_mod) & Parameter.Modifier.RefOutMask) != 0) {
if ((a.Modifier & Parameter.Modifier.RefOutMask) != (p_mod & Parameter.Modifier.RefOutMask))
break;
if (a.Expr.Type == pt || TypeSpecComparer.IsEqual (a.Expr.Type, pt))
@ -5515,7 +5565,7 @@ namespace Mono.CSharp { @@ -5515,7 +5565,7 @@ namespace Mono.CSharp {
base.EmitSideEffect (ec);
}
public void AddressOf (EmitContext ec, AddressOp mode)
public virtual void AddressOf (EmitContext ec, AddressOp mode)
{
if ((mode & AddressOp.Store) != 0)
spec.MemberDefinition.SetIsAssigned ();
@ -5942,10 +5992,11 @@ namespace Mono.CSharp { @@ -5942,10 +5992,11 @@ namespace Mono.CSharp {
Emit (ec, false);
}
protected override void EmitToFieldSource (EmitContext ec)
protected override FieldExpr EmitToFieldSource (EmitContext ec)
{
has_await_arguments = true;
Emit (ec, false);
return null;
}
public abstract SLE.Expression MakeAssignExpression (BuilderContext ctx, Expression source);
@ -6249,9 +6300,10 @@ namespace Mono.CSharp { @@ -6249,9 +6300,10 @@ namespace Mono.CSharp {
//
// Don't capture temporary variables except when using
// state machine redirection
// state machine redirection and block yields
//
if (ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod is StateMachineInitializer && ec.IsVariableCapturingRequired) {
if (ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod.IsIterator &&
ec.CurrentBlock.Explicit.HasYield && ec.IsVariableCapturingRequired) {
AnonymousMethodStorey storey = li.Block.Explicit.CreateAnonymousMethodStorey (ec);
storey.CaptureLocalVariable (ec, li);
}

6
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/enum.cs

@ -162,9 +162,9 @@ namespace Mono.CSharp { @@ -162,9 +162,9 @@ namespace Mono.CSharp {
Modifiers.INTERNAL |
Modifiers.PRIVATE;
readonly TypeExpr underlying_type_expr;
readonly FullNamedExpression underlying_type_expr;
public Enum (TypeContainer parent, TypeExpression type, Modifiers mod_flags, MemberName name, Attributes attrs)
public Enum (TypeContainer parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, Attributes attrs)
: base (parent, name, attrs, MemberKind.Enum)
{
underlying_type_expr = type;
@ -181,7 +181,7 @@ namespace Mono.CSharp { @@ -181,7 +181,7 @@ namespace Mono.CSharp {
}
}
public TypeExpr BaseTypeExpression {
public FullNamedExpression BaseTypeExpression {
get {
return underlying_type_expr;
}

136
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs

@ -103,7 +103,12 @@ namespace Mono.CSharp @@ -103,7 +103,12 @@ namespace Mono.CSharp
protected override Expression DoResolve (ResolveContext ec)
{
return expr.Resolve (ec);
var res = expr.Resolve (ec);
var constant = res as Constant;
if (constant != null && constant.IsLiteral)
return Constant.CreateConstantFromValue (res.Type, constant.GetValue (), expr.Location);
return res;
}
public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
@ -142,10 +147,12 @@ namespace Mono.CSharp @@ -142,10 +147,12 @@ namespace Mono.CSharp
// This routine will attempt to simplify the unary expression when the
// argument is a constant.
// </summary>
Constant TryReduceConstant (ResolveContext ec, Constant e)
Constant TryReduceConstant (ResolveContext ec, Constant constant)
{
if (e is EmptyConstantCast)
return TryReduceConstant (ec, ((EmptyConstantCast) e).child);
var e = constant;
while (e is EmptyConstantCast)
e = ((EmptyConstantCast) e).child;
if (e is SideEffectConstant) {
Constant r = TryReduceConstant (ec, ((SideEffectConstant) e).value);
@ -220,7 +227,7 @@ namespace Mono.CSharp @@ -220,7 +227,7 @@ namespace Mono.CSharp
return new LongConstant (ec.BuiltinTypes, -lvalue, e.Location);
case BuiltinTypeSpec.Type.UInt:
UIntLiteral uil = e as UIntLiteral;
UIntLiteral uil = constant as UIntLiteral;
if (uil != null) {
if (uil.Value == int.MaxValue + (uint) 1)
return new IntLiteral (ec.BuiltinTypes, int.MinValue, e.Location);
@ -230,13 +237,13 @@ namespace Mono.CSharp @@ -230,13 +237,13 @@ namespace Mono.CSharp
case BuiltinTypeSpec.Type.ULong:
ULongLiteral ull = e as ULongLiteral;
ULongLiteral ull = constant as ULongLiteral;
if (ull != null && ull.Value == 9223372036854775808)
return new LongLiteral (ec.BuiltinTypes, long.MinValue, e.Location);
return null;
case BuiltinTypeSpec.Type.Float:
FloatLiteral fl = e as FloatLiteral;
FloatLiteral fl = constant as FloatLiteral;
// For better error reporting
if (fl != null)
return new FloatLiteral (ec.BuiltinTypes, -fl.Value, e.Location);
@ -244,7 +251,7 @@ namespace Mono.CSharp @@ -244,7 +251,7 @@ namespace Mono.CSharp
return new FloatConstant (ec.BuiltinTypes, -((FloatConstant) e).Value, e.Location);
case BuiltinTypeSpec.Type.Double:
DoubleLiteral dl = e as DoubleLiteral;
DoubleLiteral dl = constant as DoubleLiteral;
// For better error reporting
if (dl != null)
return new DoubleLiteral (ec.BuiltinTypes, -dl.Value, e.Location);
@ -1687,19 +1694,19 @@ namespace Mono.CSharp @@ -1687,19 +1694,19 @@ namespace Mono.CSharp
return null;
}
eclass = ExprClass.Value;
if (type.IsPointer && !ec.IsUnsafe) {
UnsafeError (ec, loc);
}
eclass = ExprClass.Value;
Constant c = expr as Constant;
if (c != null) {
c = c.TryReduce (ec, type, loc);
c = c.TryReduce (ec, type);
if (c != null)
return c;
}
if (type.IsPointer && !ec.IsUnsafe) {
UnsafeError (ec, loc);
}
var res = Convert.ExplicitConversion (ec, expr, type, loc);
if (res == expr)
return EmptyCast.Create (res, type);
@ -2654,7 +2661,7 @@ namespace Mono.CSharp @@ -2654,7 +2661,7 @@ namespace Mono.CSharp
return left;
if (left.IsZeroInteger)
return left.TryReduce (ec, right.Type, loc);
return left.TryReduce (ec, right.Type);
break;
@ -3929,6 +3936,27 @@ namespace Mono.CSharp @@ -3929,6 +3936,27 @@ namespace Mono.CSharp
}
}
public override Expression EmitToField (EmitContext ec)
{
if ((oper & Operator.LogicalMask) == 0) {
var await_expr = left as Await;
if (await_expr != null && right.IsSideEffectFree) {
await_expr.Statement.EmitPrologue (ec);
left = await_expr.Statement.GetResultExpression (ec);
return this;
}
await_expr = right as Await;
if (await_expr != null && left.IsSideEffectFree) {
await_expr.Statement.EmitPrologue (ec);
right = await_expr.Statement.GetResultExpression (ec);
return this;
}
}
return base.EmitToField (ec);
}
protected override void CloneTo (CloneContext clonectx, Expression t)
{
Binary target = (Binary) t;
@ -4245,7 +4273,7 @@ namespace Mono.CSharp @@ -4245,7 +4273,7 @@ namespace Mono.CSharp
//
bool right_contains_await = ec.HasSet (BuilderContext.Options.AsyncBody) && arguments[1].Expr.ContainsEmitWithAwait ();
if (right_contains_await) {
arguments[0] = arguments[0].EmitToField (ec);
arguments[0] = arguments[0].EmitToField (ec, false);
arguments[0].Expr.Emit (ec);
} else {
arguments[0].Expr.Emit (ec);
@ -4476,7 +4504,7 @@ namespace Mono.CSharp @@ -4476,7 +4504,7 @@ namespace Mono.CSharp
//
converted = GetOperatorTrue (ec, expr, loc);
if (converted == null) {
expr.Error_ValueCannotBeConverted (ec, loc, type, false);
expr.Error_ValueCannotBeConverted (ec, type, false);
return null;
}
@ -4961,22 +4989,25 @@ namespace Mono.CSharp @@ -4961,22 +4989,25 @@ namespace Mono.CSharp
return this;
}
public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
public override Expression DoResolveLValue (ResolveContext ec, Expression rhs)
{
// is out param
if (right_side == EmptyExpression.OutAccess)
//
// Don't be too pedantic when variable is used as out param or for some broken code
// which uses property/indexer access to run some initialization
//
if (rhs == EmptyExpression.OutAccess || rhs.eclass == ExprClass.PropertyAccess || rhs.eclass == ExprClass.IndexerAccess)
local_info.SetIsUsed ();
if (local_info.IsReadonly && !ec.HasAny (ResolveContext.Options.FieldInitializerScope | ResolveContext.Options.UsingInitializerScope)) {
int code;
string msg;
if (right_side == EmptyExpression.OutAccess) {
if (rhs == EmptyExpression.OutAccess) {
code = 1657; msg = "Cannot pass `{0}' as a ref or out argument because it is a `{1}'";
} else if (right_side == EmptyExpression.LValueMemberAccess) {
} else if (rhs == EmptyExpression.LValueMemberAccess) {
code = 1654; msg = "Cannot assign to members of `{0}' because it is a `{1}'";
} else if (right_side == EmptyExpression.LValueMemberOutAccess) {
} else if (rhs == EmptyExpression.LValueMemberOutAccess) {
code = 1655; msg = "Cannot pass members of `{0}' as ref or out arguments because it is a `{1}'";
} else if (right_side == EmptyExpression.UnaryAddress) {
} else if (rhs == EmptyExpression.UnaryAddress) {
code = 459; msg = "Cannot take the address of {1} `{0}'";
} else {
code = 1656; msg = "Cannot assign to `{0}' because it is a `{1}'";
@ -4989,7 +5020,7 @@ namespace Mono.CSharp @@ -4989,7 +5020,7 @@ namespace Mono.CSharp
if (eclass == ExprClass.Unresolved)
DoResolveBase (ec);
return base.DoResolveLValue (ec, right_side);
return base.DoResolveLValue (ec, rhs);
}
public override int GetHashCode ()
@ -5052,11 +5083,11 @@ namespace Mono.CSharp @@ -5052,11 +5083,11 @@ namespace Mono.CSharp
}
public override bool IsRef {
get { return (pi.Parameter.ModFlags & Parameter.Modifier.ISBYREF) != 0; }
get { return (pi.Parameter.ModFlags & Parameter.Modifier.RefOutMask) != 0; }
}
bool HasOutModifier {
get { return pi.Parameter.ModFlags == Parameter.Modifier.OUT; }
get { return (pi.Parameter.ModFlags & Parameter.Modifier.OUT) != 0; }
}
public override HoistedVariable GetHoistedVariable (AnonymousExpression ae)
@ -5138,7 +5169,7 @@ namespace Mono.CSharp @@ -5138,7 +5169,7 @@ namespace Mono.CSharp
if (ec.IsVariableCapturingRequired && !pi.Block.ParametersBlock.IsExpressionTree) {
AnonymousMethodStorey storey = pi.Block.Explicit.CreateAnonymousMethodStorey (ec);
storey.CaptureParameter (ec, this);
storey.CaptureParameter (ec, pi, this);
}
}
@ -5249,6 +5280,12 @@ namespace Mono.CSharp @@ -5249,6 +5280,12 @@ namespace Mono.CSharp
return expr;
}
}
public MethodGroupExpr MethodGroup {
get {
return mg;
}
}
#endregion
protected override void CloneTo (CloneContext clonectx, Expression t)
@ -6627,6 +6664,11 @@ namespace Mono.CSharp @@ -6627,6 +6664,11 @@ namespace Mono.CSharp
}
public override void Emit (EmitContext ec)
{
EmitToFieldSource (ec);
}
protected sealed override FieldExpr EmitToFieldSource (EmitContext ec)
{
if (first_emit != null) {
first_emit.Emit (ec);
@ -6646,7 +6688,7 @@ namespace Mono.CSharp @@ -6646,7 +6688,7 @@ namespace Mono.CSharp
ec.EmitArrayNew ((ArrayContainer) type);
if (initializers == null)
return;
return await_stack_field;
if (await_stack_field != null)
await_stack_field.EmitAssignFromStack (ec);
@ -6671,11 +6713,10 @@ namespace Mono.CSharp @@ -6671,11 +6713,10 @@ namespace Mono.CSharp
EmitDynamicInitializers (ec, true, await_stack_field);
}
if (await_stack_field != null)
await_stack_field.Emit (ec);
if (first_emit_temp != null)
first_emit_temp.Release (ec);
return await_stack_field;
}
public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
@ -6974,15 +7015,7 @@ namespace Mono.CSharp @@ -6974,15 +7015,7 @@ namespace Mono.CSharp
return null;
AnonymousMethodStorey storey = ae.Storey;
while (storey != null) {
AnonymousMethodStorey temp = storey.Parent as AnonymousMethodStorey;
if (temp == null)
return storey.HoistedThis;
storey = temp;
}
return null;
return storey != null ? storey.HoistedThis : null;
}
public static bool IsThisAvailable (ResolveContext ec, bool ignoreAnonymous)
@ -7011,11 +7044,20 @@ namespace Mono.CSharp @@ -7011,11 +7044,20 @@ namespace Mono.CSharp
var block = ec.CurrentBlock;
if (block != null) {
if (block.ParametersBlock.TopBlock.ThisVariable != null)
variable_info = block.ParametersBlock.TopBlock.ThisVariable.VariableInfo;
var top = block.ParametersBlock.TopBlock;
if (top.ThisVariable != null)
variable_info = top.ThisVariable.VariableInfo;
AnonymousExpression am = ec.CurrentAnonymousMethod;
if (am != null && ec.IsVariableCapturingRequired) {
if (am != null && ec.IsVariableCapturingRequired && !block.Explicit.HasCapturedThis) {
//
// Hoisted this is almost like hoisted variable but not exactly. When
// there is no variable hoisted we can simply emit an instance method
// without lifting this into a storey. Unfotunatelly this complicates
// this in other cases because we don't know where this will be hoisted
// until top-level block is fully resolved
//
top.AddThisReferenceFromChildrenBlock (block.Explicit);
am.SetHasThisAccess ();
}
}
@ -9248,11 +9290,15 @@ namespace Mono.CSharp @@ -9248,11 +9290,15 @@ namespace Mono.CSharp
return this;
}
public override void Error_ValueAssignment (ResolveContext rc, Expression rhs)
{
}
public override void Error_UnexpectedKind (ResolveContext ec, ResolveFlags flags, Location loc)
{
}
public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
{
}

2
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/field.cs

@ -232,7 +232,7 @@ namespace Mono.CSharp @@ -232,7 +232,7 @@ namespace Mono.CSharp
{
if (member_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
Module.PredefinedAttributes.Dynamic.EmitAttribute (FieldBuilder);
} else if (!(Parent is CompilerGeneratedClass) && member_type.HasDynamicElement) {
} else if (!Parent.IsCompilerGenerated && member_type.HasDynamicElement) {
Module.PredefinedAttributes.Dynamic.EmitAttribute (FieldBuilder, member_type, Location);
}

152
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/iterators.cs

@ -11,10 +11,6 @@ @@ -11,10 +11,6 @@
// Copyright 2011 Xamarin Inc.
//
// TODO:
// Flow analysis for Yield.
//
using System;
using System.Collections.Generic;
using Mono.CompilerServices.SymbolWriter;
@ -160,9 +156,10 @@ namespace Mono.CSharp @@ -160,9 +156,10 @@ namespace Mono.CSharp
Field pc_field;
StateMachineMethod method;
int local_name_idx;
protected StateMachine (Block block, TypeDefinition parent, MemberBase host, TypeParameters tparams, string name)
: base (block, parent, host, tparams, name)
protected StateMachine (ParametersBlock block, TypeDefinition parent, MemberBase host, TypeParameters tparams, string name, MemberKind kind)
: base (block, parent, host, tparams, name, kind)
{
}
@ -197,6 +194,14 @@ namespace Mono.CSharp @@ -197,6 +194,14 @@ namespace Mono.CSharp
return base.DoDefineMembers ();
}
protected override string GetVariableMangledName (LocalVariable local_info)
{
if (local_info.IsCompilerGenerated)
return base.GetVariableMangledName (local_info);
return "<" + local_info.Name + ">__" + local_name_idx++.ToString ("X");
}
}
class IteratorStorey : StateMachine
@ -399,17 +404,13 @@ namespace Mono.CSharp @@ -399,17 +404,13 @@ namespace Mono.CSharp
TypeExpr iterator_type_expr;
Field current_field;
Field disposing_field;
int local_name_idx;
TypeExpr enumerator_type;
TypeExpr enumerable_type;
TypeArguments generic_args;
TypeExpr generic_enumerator_type;
TypeExpr generic_enumerable_type;
TypeSpec generic_enumerator_type;
TypeSpec generic_enumerable_type;
public IteratorStorey (Iterator iterator)
: base (iterator.Container.ParametersBlock, iterator.Host,
iterator.OriginalMethod as MemberBase, iterator.OriginalMethod.CurrentTypeParameters, "Iterator")
iterator.OriginalMethod as MemberBase, iterator.OriginalMethod.CurrentTypeParameters, "Iterator", MemberKind.Class)
{
this.Iterator = iterator;
}
@ -437,33 +438,30 @@ namespace Mono.CSharp @@ -437,33 +438,30 @@ namespace Mono.CSharp
mtype = Mutator.Mutate (mtype);
iterator_type_expr = new TypeExpression (mtype, Location);
generic_args = new TypeArguments (iterator_type_expr);
var list = new List<FullNamedExpression> ();
var ifaces = new List<TypeSpec> (5);
if (Iterator.IsEnumerable) {
enumerable_type = new TypeExpression (Compiler.BuiltinTypes.IEnumerable, Location);
list.Add (enumerable_type);
ifaces.Add (Compiler.BuiltinTypes.IEnumerable);
if (Module.PredefinedTypes.IEnumerableGeneric.Define ()) {
generic_enumerable_type = new GenericTypeExpr (Module.PredefinedTypes.IEnumerableGeneric.TypeSpec, generic_args, Location);
list.Add (generic_enumerable_type);
generic_enumerable_type = Module.PredefinedTypes.IEnumerableGeneric.TypeSpec.MakeGenericType (Module, new[] { mtype });
ifaces.Add (generic_enumerable_type);
}
}
enumerator_type = new TypeExpression (Compiler.BuiltinTypes.IEnumerator, Location);
list.Add (enumerator_type);
list.Add (new TypeExpression (Compiler.BuiltinTypes.IDisposable, Location));
ifaces.Add (Compiler.BuiltinTypes.IEnumerator);
ifaces.Add (Compiler.BuiltinTypes.IDisposable);
var ienumerator_generic = Module.PredefinedTypes.IEnumeratorGeneric;
if (ienumerator_generic.Define ()) {
generic_enumerator_type = new GenericTypeExpr (ienumerator_generic.TypeSpec, generic_args, Location);
list.Add (generic_enumerator_type);
generic_enumerator_type = ienumerator_generic.TypeSpec.MakeGenericType (Module, new [] { mtype });
ifaces.Add (generic_enumerator_type);
}
type_bases = list;
base_class = null;
return base.ResolveBaseTypes (out base_class);
base_type = Compiler.BuiltinTypes.Object;
return ifaces.ToArray ();
}
protected override bool DoDefineMembers ()
@ -497,20 +495,20 @@ namespace Mono.CSharp @@ -497,20 +495,20 @@ namespace Mono.CSharp
var name = new MemberName ("GetEnumerator", null, explicit_iface, Location.Null);
if (generic_enumerator_type != null) {
explicit_iface = new GenericTypeExpr (Module.PredefinedTypes.IEnumerableGeneric.Resolve (), generic_args, Location);
explicit_iface = new TypeExpression (generic_enumerable_type, Location);
var gname = new MemberName ("GetEnumerator", null, explicit_iface, Location.Null);
Method gget_enumerator = GetEnumeratorMethod.Create (this, generic_enumerator_type, gname);
Method gget_enumerator = GetEnumeratorMethod.Create (this, new TypeExpression (generic_enumerator_type, Location), gname);
//
// Just call generic GetEnumerator implementation
//
var stmt = new Return (new Invocation (new DynamicMethodGroupExpr (gget_enumerator, Location), null), Location);
Method get_enumerator = GetEnumeratorMethod.Create (this, enumerator_type, name, stmt);
Method get_enumerator = GetEnumeratorMethod.Create (this, new TypeExpression (Compiler.BuiltinTypes.IEnumerator, Location), name, stmt);
Members.Add (get_enumerator);
Members.Add (gget_enumerator);
} else {
Members.Add (GetEnumeratorMethod.Create (this, enumerator_type, name));
Members.Add (GetEnumeratorMethod.Create (this, new TypeExpression (Compiler.BuiltinTypes.IEnumerator, Location), name));
}
}
@ -523,7 +521,7 @@ namespace Mono.CSharp @@ -523,7 +521,7 @@ namespace Mono.CSharp
FullNamedExpression explicit_iface;
if (is_generic) {
explicit_iface = new GenericTypeExpr (Module.PredefinedTypes.IEnumeratorGeneric.Resolve (), generic_args, Location);
explicit_iface = new TypeExpression (generic_enumerator_type, Location);
type = iterator_type_expr;
} else {
explicit_iface = new TypeExpression (Module.Compiler.BuiltinTypes.IEnumerator, Location);
@ -564,16 +562,11 @@ namespace Mono.CSharp @@ -564,16 +562,11 @@ namespace Mono.CSharp
reset.Block.AddStatement (new Throw (new New (new TypeExpression (ex_type, Location), null, Location), Location));
}
protected override void EmitHoistedParameters (EmitContext ec, IList<HoistedParameter> hoisted)
protected override void EmitHoistedParameters (EmitContext ec, List<HoistedParameter> hoisted)
{
base.EmitHoistedParameters (ec, hoisted);
base.EmitHoistedParameters (ec, hoisted_params_copy);
}
protected override string GetVariableMangledName (LocalVariable local_info)
{
return "<" + local_info.Name + ">__" + local_name_idx++.ToString ("X");
}
}
public class StateMachineMethod : Method
@ -705,8 +698,6 @@ namespace Mono.CSharp @@ -705,8 +698,6 @@ namespace Mono.CSharp
protected override Expression DoResolve (ResolveContext ec)
{
storey = (StateMachine) block.Parent.ParametersBlock.AnonymousMethodStorey;
var ctx = CreateBlockContext (ec);
Block.Resolve (ctx);
@ -733,7 +724,7 @@ namespace Mono.CSharp @@ -733,7 +724,7 @@ namespace Mono.CSharp
public override void Emit (EmitContext ec)
{
//
// Load Iterator storey instance
// Load state machine instance
//
storey.Instance.Emit (ec);
}
@ -752,11 +743,7 @@ namespace Mono.CSharp @@ -752,11 +743,7 @@ namespace Mono.CSharp
iterator_body_end = ec.DefineLabel ();
if (ec.EmitAccurateDebugInfo && ec.Mark (Block.Original.StartLocation)) {
ec.Emit (OpCodes.Nop);
}
block.Emit (ec);
block.EmitEmbedded (ec);
ec.MarkLabel (iterator_body_end);
@ -819,11 +806,7 @@ namespace Mono.CSharp @@ -819,11 +806,7 @@ namespace Mono.CSharp
iterator_body_end = ec.DefineLabel ();
if (ec.EmitAccurateDebugInfo && ec.Mark (Block.Original.StartLocation)) {
ec.Emit (OpCodes.Nop);
}
block.Emit (ec);
block.EmitEmbedded (ec);
ec.MarkLabel (iterator_body_end);
@ -908,16 +891,51 @@ namespace Mono.CSharp @@ -908,16 +891,51 @@ namespace Mono.CSharp
ec.Emit (OpCodes.Stloc, skip_finally);
}
}
public void SetStateMachine (StateMachine stateMachine)
{
this.storey = stateMachine;
}
}
//
// Iterators are implemented as hidden anonymous block
// Iterators are implemented as state machine blocks
//
public class Iterator : StateMachineInitializer
{
sealed class TryFinallyBlockProxyStatement : Statement
{
TryFinallyBlock block;
Iterator iterator;
public TryFinallyBlockProxyStatement (Iterator iterator, TryFinallyBlock block)
{
this.iterator = iterator;
this.block = block;
}
protected override void CloneTo (CloneContext clonectx, Statement target)
{
throw new NotSupportedException ();
}
protected override void DoEmit (EmitContext ec)
{
//
// Restore redirection for any captured variables
//
ec.CurrentAnonymousMethod = iterator;
using (ec.With (BuilderContext.Options.OmitDebugInfo, !ec.HasMethodSymbolBuilder)) {
block.EmitFinallyBody (ec);
}
}
}
public readonly IMethodData OriginalMethod;
public readonly bool IsEnumerable;
public readonly TypeSpec OriginalIteratorType;
int finally_hosts_counter;
public Iterator (ParametersBlock block, IMethodData method, TypeDefinition host, TypeSpec iterator_type, bool is_enumerable)
: base (block, host, host.Compiler.BuiltinTypes.Bool)
@ -928,7 +946,9 @@ namespace Mono.CSharp @@ -928,7 +946,9 @@ namespace Mono.CSharp
this.type = method.ReturnType;
}
public Block Container {
#region Properties
public ToplevelBlock Container {
get { return OriginalMethod.Block; }
}
@ -940,6 +960,22 @@ namespace Mono.CSharp @@ -940,6 +960,22 @@ namespace Mono.CSharp
get { return true; }
}
#endregion
public Method CreateFinallyHost (TryFinallyBlock block)
{
var method = new Method (storey, new TypeExpression (storey.Compiler.BuiltinTypes.Void, loc),
Modifiers.COMPILER_GENERATED, new MemberName (CompilerGeneratedContainer.MakeName (null, null, "Finally", finally_hosts_counter++), loc),
ParametersCompiled.EmptyReadOnlyParameters, null);
method.Block = new ToplevelBlock (method.Compiler, method.ParameterInfo, loc);
method.Block.IsCompilerGenerated = true;
method.Block.AddStatement (new TryFinallyBlockProxyStatement (this, block));
storey.AddMember (method);
return method;
}
public void EmitYieldBreak (EmitContext ec, bool unwind_protect)
{
ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, move_next_error);
@ -975,11 +1011,13 @@ namespace Mono.CSharp @@ -975,11 +1011,13 @@ namespace Mono.CSharp
public void EmitDispose (EmitContext ec)
{
if (resume_points == null)
return;
Label end = ec.DefineLabel ();
Label[] labels = null;
int n_resume_points = resume_points == null ? 0 : resume_points.Count;
for (int i = 0; i < n_resume_points; ++i) {
for (int i = 0; i < resume_points.Count; ++i) {
ResumableStatement s = resume_points[i];
Label ret = s.PrepareForDispose (ec, end);
if (ret.Equals (end) && labels == null)
@ -1069,7 +1107,7 @@ namespace Mono.CSharp @@ -1069,7 +1107,7 @@ namespace Mono.CSharp
for (int i = 0; i < parameters.Count; i++) {
Parameter p = parameters [i];
Parameter.Modifier mod = p.ModFlags;
if ((mod & Parameter.Modifier.ISBYREF) != 0) {
if ((mod & Parameter.Modifier.RefOutMask) != 0) {
parent.Compiler.Report.Error (1623, p.Location,
"Iterators cannot have ref or out parameters");
return;
@ -1092,7 +1130,7 @@ namespace Mono.CSharp @@ -1092,7 +1130,7 @@ namespace Mono.CSharp
parent.Compiler.Report.Error (1629, method.Location, "Unsafe code may not appear in iterators");
}
method.Block.WrapIntoIterator (method, parent, iterator_type, is_enumerable);
method.Block = method.Block.ConvertToIterator (method, parent, iterator_type, is_enumerable);
}
static bool CheckType (TypeSpec ret, TypeContainer parent, out TypeSpec original_iterator_type, out bool is_enumerable)

6
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/lambda.cs

@ -81,7 +81,7 @@ namespace Mono.CSharp { @@ -81,7 +81,7 @@ namespace Mono.CSharp {
TypeSpec [] ptypes = new TypeSpec [Parameters.Count];
for (int i = 0; i < d_params.Count; i++) {
// D has no ref or out parameters
if ((d_params.FixedParameters [i].ModFlags & Parameter.Modifier.ISBYREF) != 0)
if ((d_params.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask) != 0)
return null;
TypeSpec d_param = d_params.Types [i];
@ -191,7 +191,7 @@ namespace Mono.CSharp { @@ -191,7 +191,7 @@ namespace Mono.CSharp {
return Expr.CreateExpressionTree (ec);
}
public override void Emit (EmitContext ec)
protected override void DoEmit (EmitContext ec)
{
if (statement != null) {
statement.EmitStatement (ec);
@ -203,7 +203,7 @@ namespace Mono.CSharp { @@ -203,7 +203,7 @@ namespace Mono.CSharp {
return;
}
base.Emit (ec);
base.DoEmit (ec);
}
protected override bool DoResolve (BlockContext ec)

20
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/linq.cs

@ -90,6 +90,13 @@ namespace Mono.CSharp.Linq @@ -90,6 +90,13 @@ namespace Mono.CSharp.Linq
return rmg;
}
protected override Expression DoResolveDynamic (ResolveContext ec, Expression memberExpr)
{
ec.Report.Error (1979, loc,
"Query expressions with a source or join sequence of type `dynamic' are not allowed");
return null;
}
#region IErrorHandler Members
bool OverloadResolver.IErrorHandler.AmbiguousCandidates (ResolveContext ec, MemberSpec best, MemberSpec ambiguous)
@ -422,19 +429,6 @@ namespace Mono.CSharp.Linq @@ -422,19 +429,6 @@ namespace Mono.CSharp.Linq
public override Expression BuildQueryClause (ResolveContext ec, Expression lSide, Parameter parameter)
{
/*
expr = expr.Resolve (ec);
if (expr == null)
return null;
if (expr.Type == InternalType.Dynamic || expr.Type == TypeManager.void_type) {
ec.Report.Error (1979, expr.Location,
"Query expression with a source or join sequence of type `{0}' is not allowed",
TypeManager.CSharpName (expr.Type));
return null;
}
*/
if (IdentifierType != null)
expr = CreateCastExpression (expr);

8
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/literal.cs

@ -50,7 +50,7 @@ namespace Mono.CSharp @@ -50,7 +50,7 @@ namespace Mono.CSharp
{
}
public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec t, bool expl)
public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec t, bool expl)
{
if (t.IsGenericParameter) {
ec.Report.Error(403, loc,
@ -65,7 +65,7 @@ namespace Mono.CSharp @@ -65,7 +65,7 @@ namespace Mono.CSharp
return;
}
base.Error_ValueCannotBeConverted (ec, loc, t, expl);
base.Error_ValueCannotBeConverted (ec, t, expl);
}
public override string GetValueAsLiteral ()
@ -253,7 +253,7 @@ namespace Mono.CSharp @@ -253,7 +253,7 @@ namespace Mono.CSharp
{
}
public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
{
if (target.BuiltinType == BuiltinTypeSpec.Type.Float) {
Error_664 (ec, loc, "float", "f");
@ -265,7 +265,7 @@ namespace Mono.CSharp @@ -265,7 +265,7 @@ namespace Mono.CSharp
return;
}
base.Error_ValueCannotBeConverted (ec, loc, target, expl);
base.Error_ValueCannotBeConverted (ec, target, expl);
}
static void Error_664 (ResolveContext ec, Location loc, string type, string suffix)

10
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/membercache.cs

@ -1352,8 +1352,10 @@ namespace Mono.CSharp { @@ -1352,8 +1352,10 @@ namespace Mono.CSharp {
type_a = parameters.Types [ii];
type_b = p_types [ii];
if ((pd.FixedParameters [ii].ModFlags & Parameter.Modifier.ISBYREF) !=
(parameters.FixedParameters [ii].ModFlags & Parameter.Modifier.ISBYREF))
var a_byref = (pd.FixedParameters[ii].ModFlags & Parameter.Modifier.RefOutMask) != 0;
var b_byref = (parameters.FixedParameters[ii].ModFlags & Parameter.Modifier.RefOutMask) != 0;
if (a_byref != b_byref)
break;
} while (TypeSpecComparer.Override.IsEqual (type_a, type_b) && ii-- != 0);
@ -1372,7 +1374,9 @@ namespace Mono.CSharp { @@ -1372,7 +1374,9 @@ namespace Mono.CSharp {
//
if (pd != null && member is MethodCore) {
ii = method_param_count;
while (ii-- != 0 && parameters.FixedParameters[ii].ModFlags == pd.FixedParameters[ii].ModFlags &&
while (ii-- != 0 &&
(parameters.FixedParameters[ii].ModFlags & Parameter.Modifier.ModifierMask) ==
(pd.FixedParameters[ii].ModFlags & Parameter.Modifier.ModifierMask) &&
parameters.ExtensionMethodType == pd.ExtensionMethodType) ;
if (ii >= 0) {

30
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/method.cs

@ -19,6 +19,7 @@ using System.Security.Permissions; @@ -19,6 +19,7 @@ using System.Security.Permissions;
using System.Text;
using System.Linq;
using Mono.CompilerServices.SymbolWriter;
using System.Runtime.CompilerServices;
#if NET_2_1
using XmlElement = System.Object;
@ -533,10 +534,13 @@ namespace Mono.CSharp { @@ -533,10 +534,13 @@ namespace Mono.CSharp {
}
if (a.Type == pa.MethodImpl) {
is_external_implementation = a.IsInternalCall ();
}
if ((ModFlags & Modifiers.ASYNC) != 0 && (a.GetMethodImplOptions () & MethodImplOptions.Synchronized) != 0) {
Report.Error (4015, a.Location, "`{0}': Async methods cannot use `MethodImplOptions.Synchronized'",
GetSignatureForError ());
}
if (a.Type == pa.DllImport) {
is_external_implementation = a.IsInternalCall ();
} else if (a.Type == pa.DllImport) {
const Modifiers extern_static = Modifiers.EXTERN | Modifiers.STATIC;
if ((ModFlags & extern_static) != extern_static) {
Report.Error (601, a.Location, "The DllImport attribute must be specified on a method marked `static' and `extern'");
@ -633,7 +637,7 @@ namespace Mono.CSharp { @@ -633,7 +637,7 @@ namespace Mono.CSharp {
if ((ModFlags & Modifiers.PARTIAL) != 0) {
for (int i = 0; i < parameters.Count; ++i) {
IParameterData p = parameters.FixedParameters [i];
if (p.ModFlags == Parameter.Modifier.OUT) {
if ((p.ModFlags & Parameter.Modifier.OUT) != 0) {
Report.Error (752, Location, "`{0}': A partial method parameters cannot use `out' modifier",
GetSignatureForError ());
}
@ -888,7 +892,7 @@ namespace Mono.CSharp { @@ -888,7 +892,7 @@ namespace Mono.CSharp {
var ac = parameters.Types [0] as ArrayContainer;
return ac != null && ac.Rank == 1 && ac.Element.BuiltinType == BuiltinTypeSpec.Type.String &&
(parameters[0].ModFlags & ~Parameter.Modifier.PARAMS) == Parameter.Modifier.NONE;
(parameters[0].ModFlags & Parameter.Modifier.RefOutMask) == 0;
}
public override FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
@ -936,7 +940,7 @@ namespace Mono.CSharp { @@ -936,7 +940,7 @@ namespace Mono.CSharp {
}
for (int i = 0; i < parameters.Count; ++i) {
if (parameters.FixedParameters [i].ModFlags == Parameter.Modifier.OUT) {
if ((parameters.FixedParameters [i].ModFlags & Parameter.Modifier.OUT) != 0) {
Report.Error (685, Location, "Conditional method `{0}' cannot have an out parameter", GetSignatureForError ());
return;
}
@ -1192,7 +1196,7 @@ namespace Mono.CSharp { @@ -1192,7 +1196,7 @@ namespace Mono.CSharp {
Report.Error (1983, Location, "The return type of an async method must be void, Task, or Task<T>");
}
AsyncInitializer.Create (this, block, parameters, Parent.PartialContainer, ReturnType, Location);
block = (ToplevelBlock) block.ConvertToAsyncTask (this, Parent.PartialContainer, parameters, ReturnType, Location);
ModFlags |= Modifiers.DEBUGGER_HIDDEN;
}
}
@ -1699,6 +1703,11 @@ namespace Mono.CSharp { @@ -1699,6 +1703,11 @@ namespace Mono.CSharp {
return null;
}
public override string GetCallerMemberName ()
{
return IsStatic ? TypeConstructorName : ConstructorName;
}
public override string GetSignatureForDocumentation ()
{
return Parent.GetSignatureForDocumentation () + ".#ctor" + parameters.GetSignatureForDocumentation ();
@ -2104,7 +2113,7 @@ namespace Mono.CSharp { @@ -2104,7 +2113,7 @@ namespace Mono.CSharp {
get;
set;
}
public Destructor (TypeDefinition parent, Modifiers mod, ParametersCompiled parameters, Attributes attrs, Location l)
: base (parent, null, mod, AllowedModifiers, new MemberName (MetadataName, l), attrs, parameters)
{
@ -2347,6 +2356,11 @@ namespace Mono.CSharp { @@ -2347,6 +2356,11 @@ namespace Mono.CSharp {
return false;
}
public override string GetCallerMemberName ()
{
return base.GetCallerMemberName ().Substring (prefix.Length);
}
public override string GetSignatureForDocumentation ()
{
// should not be called

5
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/module.cs

@ -36,13 +36,14 @@ namespace Mono.CSharp @@ -36,13 +36,14 @@ namespace Mono.CSharp
//
// Compiler generated container for static data
//
sealed class StaticDataContainer : CompilerGeneratedClass
sealed class StaticDataContainer : CompilerGeneratedContainer
{
readonly Dictionary<int, Struct> size_types;
int fields;
public StaticDataContainer (ModuleContainer module)
: base (module, new MemberName ("<PrivateImplementationDetails>" + module.builder.ModuleVersionId.ToString ("B"), Location.Null), Modifiers.STATIC)
: base (module, new MemberName ("<PrivateImplementationDetails>" + module.builder.ModuleVersionId.ToString ("B"), Location.Null),
Modifiers.STATIC | Modifiers.INTERNAL)
{
size_types = new Dictionary<int, Struct> ();
}

4
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/nullable.cs

@ -860,7 +860,7 @@ namespace Mono.CSharp.Nullable @@ -860,7 +860,7 @@ namespace Mono.CSharp.Nullable
if (lifted_type == null)
return null;
if (left is UserCast || left is TypeCast)
if (left is UserCast || left is EmptyCast || left is OpcodeCast)
left.Type = lifted_type;
else
left = EmptyCast.Create (left, lifted_type);
@ -875,7 +875,7 @@ namespace Mono.CSharp.Nullable @@ -875,7 +875,7 @@ namespace Mono.CSharp.Nullable
if (r is ReducedExpression)
r = ((ReducedExpression) r).OriginalExpression;
if (r is UserCast || r is TypeCast)
if (r is UserCast || r is EmptyCast || r is OpcodeCast)
r.Type = lifted_type;
else
right = EmptyCast.Create (right, lifted_type);

126
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/parameter.cs

@ -209,21 +209,23 @@ namespace Mono.CSharp { @@ -209,21 +209,23 @@ namespace Mono.CSharp {
[Flags]
public enum Modifier : byte {
NONE = 0,
REF = REFMASK | ISBYREF,
OUT = OUTMASK | ISBYREF,
PARAMS = 4,
// This is a flag which says that it's either REF or OUT.
ISBYREF = 8,
REFMASK = 32,
OUTMASK = 64,
SignatureMask = REFMASK | OUTMASK,
This = 128
PARAMS = 1 << 0,
REF = 1 << 1,
OUT = 1 << 2,
This = 1 << 3,
CallerMemberName = 1 << 4,
CallerLineNumber = 1 << 5,
CallerFilePath = 1 << 6,
RefOutMask = REF | OUT,
ModifierMask = PARAMS | REF | OUT | This,
CallerMask = CallerMemberName | CallerLineNumber | CallerFilePath
}
static readonly string[] attribute_targets = new string[] { "param" };
FullNamedExpression texpr;
readonly Modifier modFlags;
Modifier modFlags;
string name;
Expression default_expr;
protected TypeSpec parameter_type;
@ -233,7 +235,7 @@ namespace Mono.CSharp { @@ -233,7 +235,7 @@ namespace Mono.CSharp {
TemporaryVariableReference expr_tree_variable;
HoistedVariable hoisted_variant;
HoistedParameter hoisted_variant;
public Parameter (FullNamedExpression type, string name, Modifier mod, Attributes attrs, Location loc)
{
@ -323,7 +325,7 @@ namespace Mono.CSharp { @@ -323,7 +325,7 @@ namespace Mono.CSharp {
return;
}
if (a.Type == pa.Out && (ModFlags & Modifier.REF) == Modifier.REF &&
if (a.Type == pa.Out && (ModFlags & Modifier.REF) != 0 &&
!OptAttributes.Contains (pa.In)) {
a.Report.Error (662, a.Location,
"Cannot specify only `Out' attribute on a ref parameter. Use both `In' and `Out' attributes or neither");
@ -332,9 +334,7 @@ namespace Mono.CSharp { @@ -332,9 +334,7 @@ namespace Mono.CSharp {
if (a.Type == pa.CLSCompliant) {
a.Report.Warning (3022, 1, a.Location, "CLSCompliant attribute has no meaning when applied to parameters. Try putting it on the method instead");
}
if (a.Type == pa.DefaultParameterValue || a.Type == pa.OptionalParameter) {
} else if (a.Type == pa.DefaultParameterValue || a.Type == pa.OptionalParameter) {
if (HasOptionalExpression) {
a.Report.Error (1745, a.Location,
"Cannot specify `{0}' attribute on optional parameter `{1}'",
@ -343,6 +343,21 @@ namespace Mono.CSharp { @@ -343,6 +343,21 @@ namespace Mono.CSharp {
if (a.Type == pa.DefaultParameterValue)
return;
} else if (a.Type == pa.CallerMemberNameAttribute) {
if ((modFlags & Modifier.CallerMemberName) == 0) {
a.Report.Error (4022, a.Location,
"The CallerMemberName attribute can only be applied to parameters with default value");
}
} else if (a.Type == pa.CallerLineNumberAttribute) {
if ((modFlags & Modifier.CallerLineNumber) == 0) {
a.Report.Error (4020, a.Location,
"The CallerLineNumber attribute can only be applied to parameters with default value");
}
} else if (a.Type == pa.CallerFilePathAttribute) {
if ((modFlags & Modifier.CallerFilePath) == 0) {
a.Report.Error (4021, a.Location,
"The CallerFilePath attribute can only be applied to parameters with default value");
}
}
base.ApplyAttributeBuilder (a, ctor, cdata, pa);
@ -372,15 +387,15 @@ namespace Mono.CSharp { @@ -372,15 +387,15 @@ namespace Mono.CSharp {
return null;
this.idx = index;
if ((modFlags & Parameter.Modifier.ISBYREF) != 0 && parameter_type.IsSpecialRuntimeType) {
if ((modFlags & Parameter.Modifier.RefOutMask) != 0 && parameter_type.IsSpecialRuntimeType) {
rc.Module.Compiler.Report.Error (1601, Location, "Method or delegate parameter cannot be of type `{0}'",
GetSignatureForError ());
return null;
}
TypeManager.CheckTypeVariance (parameter_type,
(modFlags & Parameter.Modifier.ISBYREF) != 0 ? Variance.None : Variance.Contravariant,
(modFlags & Parameter.Modifier.RefOutMask) != 0 ? Variance.None : Variance.Contravariant,
rc);
if (parameter_type.IsStatic) {
@ -397,6 +412,54 @@ namespace Mono.CSharp { @@ -397,6 +412,54 @@ namespace Mono.CSharp {
return parameter_type;
}
void ResolveCallerAttributes (ResolveContext rc)
{
var pa = rc.Module.PredefinedAttributes;
TypeSpec caller_type;
foreach (var attr in attributes.Attrs) {
var atype = attr.ResolveType ();
if (atype == null)
continue;
if (atype == pa.CallerMemberNameAttribute) {
caller_type = rc.BuiltinTypes.String;
if (caller_type != parameter_type && !Convert.ImplicitReferenceConversionExists (caller_type, parameter_type)) {
rc.Report.Error (4019, attr.Location,
"The CallerMemberName attribute cannot be applied because there is no standard conversion from `{0}' to `{1}'",
caller_type.GetSignatureForError (), parameter_type.GetSignatureForError ());
}
modFlags |= Modifier.CallerMemberName;
continue;
}
if (atype == pa.CallerLineNumberAttribute) {
caller_type = rc.BuiltinTypes.Int;
if (caller_type != parameter_type && !Convert.ImplicitNumericConversionExists (caller_type, parameter_type)) {
rc.Report.Error (4017, attr.Location,
"The CallerMemberName attribute cannot be applied because there is no standard conversion from `{0}' to `{1}'",
caller_type.GetSignatureForError (), parameter_type.GetSignatureForError ());
}
modFlags |= Modifier.CallerLineNumber;
continue;
}
if (atype == pa.CallerFilePathAttribute) {
caller_type = rc.BuiltinTypes.String;
if (caller_type != parameter_type && !Convert.ImplicitReferenceConversionExists (caller_type, parameter_type)) {
rc.Report.Error (4018, attr.Location,
"The CallerFilePath attribute cannot be applied because there is no standard conversion from `{0}' to `{1}'",
caller_type.GetSignatureForError (), parameter_type.GetSignatureForError ());
}
modFlags |= Modifier.CallerFilePath;
continue;
}
}
}
public void ResolveDefaultValue (ResolveContext rc)
{
//
@ -404,14 +467,17 @@ namespace Mono.CSharp { @@ -404,14 +467,17 @@ namespace Mono.CSharp {
//
if (default_expr != null) {
((DefaultParameterValueExpression)default_expr).Resolve (rc, this);
if (attributes != null)
ResolveCallerAttributes (rc);
return;
}
if (attributes == null)
return;
var opt_attr = attributes.Search (rc.Module.PredefinedAttributes.OptionalParameter);
var def_attr = attributes.Search (rc.Module.PredefinedAttributes.DefaultParameterValue);
var pa = rc.Module.PredefinedAttributes;
var def_attr = attributes.Search (pa.DefaultParameterValue);
if (def_attr != null) {
if (def_attr.Resolve () == null)
return;
@ -466,6 +532,7 @@ namespace Mono.CSharp { @@ -466,6 +532,7 @@ namespace Mono.CSharp {
return;
}
var opt_attr = attributes.Search (pa.OptionalParameter);
if (opt_attr != null) {
default_expr = EmptyExpression.MissingValue;
}
@ -482,7 +549,7 @@ namespace Mono.CSharp { @@ -482,7 +549,7 @@ namespace Mono.CSharp {
//
// Hoisted parameter variant
//
public HoistedVariable HoistedVariant {
public HoistedParameter HoistedVariant {
get {
return hoisted_variant;
}
@ -611,7 +678,7 @@ namespace Mono.CSharp { @@ -611,7 +678,7 @@ namespace Mono.CSharp {
public ExpressionStatement CreateExpressionTreeVariable (BlockContext ec)
{
if ((modFlags & Modifier.ISBYREF) != 0)
if ((modFlags & Modifier.RefOutMask) != 0)
ec.Report.Error (1951, Location, "An expression tree parameter cannot use `ref' or `out' modifier");
expr_tree_variable = TemporaryVariableReference.Create (ResolveParameterExpressionType (ec, Location).Type, ec.CurrentBlock.ParametersBlock, Location);
@ -636,7 +703,7 @@ namespace Mono.CSharp { @@ -636,7 +703,7 @@ namespace Mono.CSharp {
public void EmitAddressOf (EmitContext ec)
{
if ((ModFlags & Modifier.ISBYREF) != 0) {
if ((ModFlags & Modifier.RefOutMask) != 0) {
ec.EmitArgumentLoad (idx);
} else {
ec.EmitArgumentAddress (idx);
@ -701,7 +768,7 @@ namespace Mono.CSharp { @@ -701,7 +768,7 @@ namespace Mono.CSharp {
}
public Parameter.Modifier ModFlags {
get { return modifiers & ~Parameter.Modifier.This; }
get { return modifiers; }
}
public string Name {
@ -750,7 +817,7 @@ namespace Mono.CSharp { @@ -750,7 +817,7 @@ namespace Mono.CSharp {
public static ParameterAttributes GetParameterAttribute (Parameter.Modifier modFlags)
{
return (modFlags & Parameter.Modifier.OUT) == Parameter.Modifier.OUT ?
return (modFlags & Parameter.Modifier.OUT) != 0 ?
ParameterAttributes.Out : ParameterAttributes.None;
}
@ -773,7 +840,7 @@ namespace Mono.CSharp { @@ -773,7 +840,7 @@ namespace Mono.CSharp {
for (int i = 0; i < types.Length; ++i) {
types[i] = Types[i].GetMetaInfo ();
if ((FixedParameters [i].ModFlags & Parameter.Modifier.ISBYREF) == 0)
if ((FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask) == 0)
continue;
// TODO MemberCache: Should go to MetaInfo getter
@ -808,7 +875,7 @@ namespace Mono.CSharp { @@ -808,7 +875,7 @@ namespace Mono.CSharp {
sb.Append (types [i].GetSignatureForDocumentation ());
if ((parameters[i].ModFlags & Parameter.Modifier.ISBYREF) != 0)
if ((parameters[i].ModFlags & Parameter.Modifier.RefOutMask) != 0)
sb.Append ("@");
}
sb.Append (")");
@ -1027,8 +1094,7 @@ namespace Mono.CSharp { @@ -1027,8 +1094,7 @@ namespace Mono.CSharp {
var a_type = a.Types[i];
var b_type = b.Types[i];
if (TypeSpecComparer.Override.IsEqual (a_type, b_type)) {
const Parameter.Modifier ref_out = Parameter.Modifier.REF | Parameter.Modifier.OUT;
if ((a.FixedParameters[i].ModFlags & ref_out) != (b.FixedParameters[i].ModFlags & ref_out))
if ((a.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask) != (b.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask))
res |= 1;
continue;

10
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/pending.cs

@ -305,11 +305,10 @@ namespace Mono.CSharp { @@ -305,11 +305,10 @@ namespace Mono.CSharp {
//
// First check exact modifiers match
//
const Parameter.Modifier ref_out = Parameter.Modifier.REF | Parameter.Modifier.OUT;
if ((cp[pi].ModFlags & ref_out) == (tp[pi].ModFlags & ref_out))
if ((cp[pi].ModFlags & Parameter.Modifier.RefOutMask) == (tp[pi].ModFlags & Parameter.Modifier.RefOutMask))
continue;
if ((cp[pi].ModFlags & tp[pi].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
if (((cp[pi].ModFlags | tp[pi].ModFlags) & Parameter.Modifier.RefOutMask) == Parameter.Modifier.RefOutMask) {
ref_only_difference = true;
continue;
}
@ -557,8 +556,7 @@ namespace Mono.CSharp { @@ -557,8 +556,7 @@ namespace Mono.CSharp {
//
// First check exact ref/out match
//
const Parameter.Modifier ref_out = Parameter.Modifier.REF | Parameter.Modifier.OUT;
if ((parameters.FixedParameters[i].ModFlags & ref_out) == (candidate_param.FixedParameters[i].ModFlags & ref_out))
if ((parameters.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask) == (candidate_param.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask))
continue;
modifiers_match = false;
@ -566,7 +564,7 @@ namespace Mono.CSharp { @@ -566,7 +564,7 @@ namespace Mono.CSharp {
//
// Different in ref/out only
//
if ((parameters.FixedParameters[i].ModFlags & candidate_param.FixedParameters[i].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
if ((parameters.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask) != (candidate_param.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask)) {
if (similar_candidate == null) {
if (!candidate.IsPublic)
break;

3
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/report.cs

@ -55,7 +55,8 @@ namespace Mono.CSharp { @@ -55,7 +55,8 @@ namespace Mono.CSharp {
2002, 2023, 2029,
3000, 3001, 3002, 3003, 3005, 3006, 3007, 3008, 3009,
3010, 3011, 3012, 3013, 3014, 3015, 3016, 3017, 3018, 3019,
3021, 3022, 3023, 3024, 3026, 3027
3021, 3022, 3023, 3024, 3026, 3027,
4014
};
static HashSet<int> AllWarningsHashSet;

567
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/statement.cs

File diff suppressed because it is too large Load Diff

153
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/typemanager.cs

@ -228,6 +228,9 @@ namespace Mono.CSharp @@ -228,6 +228,9 @@ namespace Mono.CSharp
public readonly PredefinedType Action;
public readonly PredefinedType Task;
public readonly PredefinedType TaskGeneric;
public readonly PredefinedType IAsyncStateMachine;
public readonly PredefinedType INotifyCompletion;
public readonly PredefinedType ICriticalNotifyCompletion;
public PredefinedTypes (ModuleContainer module)
{
@ -276,6 +279,9 @@ namespace Mono.CSharp @@ -276,6 +279,9 @@ namespace Mono.CSharp
AsyncTaskMethodBuilderGeneric = new PredefinedType (module, MemberKind.Struct, "System.Runtime.CompilerServices", "AsyncTaskMethodBuilder", 1);
Task = new PredefinedType (module, MemberKind.Class, "System.Threading.Tasks", "Task");
TaskGeneric = new PredefinedType (module, MemberKind.Class, "System.Threading.Tasks", "Task", 1);
IAsyncStateMachine = new PredefinedType (module, MemberKind.Interface, "System.Runtime.CompilerServices", "IAsyncStateMachine");
INotifyCompletion = new PredefinedType (module, MemberKind.Interface, "System.Runtime.CompilerServices", "INotifyCompletion");
ICriticalNotifyCompletion = new PredefinedType (module, MemberKind.Interface, "System.Runtime.CompilerServices", "ICriticalNotifyCompletion");
//
// Define types which are used for comparison. It does not matter
@ -312,16 +318,28 @@ namespace Mono.CSharp @@ -312,16 +318,28 @@ namespace Mono.CSharp
{
public readonly PredefinedMember<MethodSpec> ActivatorCreateInstance;
public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderCreate;
public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderStart;
public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderSetResult;
public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderSetException;
public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderSetStateMachine;
public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderOnCompleted;
public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderOnCompletedUnsafe;
public readonly PredefinedMember<PropertySpec> AsyncTaskMethodBuilderTask;
public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericCreate;
public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericStart;
public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericSetResult;
public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericSetException;
public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericSetStateMachine;
public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericOnCompleted;
public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericOnCompletedUnsafe;
public readonly PredefinedMember<PropertySpec> AsyncTaskMethodBuilderGenericTask;
public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderCreate;
public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderStart;
public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetException;
public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetResult;
public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetStateMachine;
public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderOnCompleted;
public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderOnCompletedUnsafe;
public readonly PredefinedMember<MethodSpec> DebuggerBrowsableAttributeCtor;
public readonly PredefinedMember<MethodSpec> DecimalCtor;
public readonly PredefinedMember<MethodSpec> DecimalCtorInt;
@ -363,6 +381,8 @@ namespace Mono.CSharp @@ -363,6 +381,8 @@ namespace Mono.CSharp
var atypes = module.PredefinedAttributes;
var btypes = module.Compiler.BuiltinTypes;
var tp = new TypeParameter (0, new MemberName ("T"), null, null, Variance.None);
ActivatorCreateInstance = new PredefinedMember<MethodSpec> (module, types.Activator,
MemberFilter.Method ("CreateInstance", 1, ParametersCompiled.EmptyReadOnlyParameters, null));
@ -372,10 +392,52 @@ namespace Mono.CSharp @@ -372,10 +392,52 @@ namespace Mono.CSharp
AsyncTaskMethodBuilderSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
MemberFilter.Method ("SetResult", 0, ParametersCompiled.EmptyReadOnlyParameters, btypes.Void));
AsyncTaskMethodBuilderSetStateMachine = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
"SetStateMachine", MemberKind.Method, () => new[] {
types.IAsyncStateMachine.TypeSpec
}, btypes.Void);
AsyncTaskMethodBuilderSetException = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
MemberFilter.Method ("SetException", 0,
ParametersCompiled.CreateFullyResolved (btypes.Exception), btypes.Void));
AsyncTaskMethodBuilderOnCompleted = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
MemberFilter.Method ("AwaitOnCompleted", 2,
new ParametersImported (
new[] {
new ParameterData (null, Parameter.Modifier.REF),
new ParameterData (null, Parameter.Modifier.REF)
},
new[] {
new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
}, false),
btypes.Void));
AsyncTaskMethodBuilderOnCompletedUnsafe = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
MemberFilter.Method ("AwaitUnsafeOnCompleted", 2,
new ParametersImported (
new[] {
new ParameterData (null, Parameter.Modifier.REF),
new ParameterData (null, Parameter.Modifier.REF)
},
new[] {
new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
}, false),
btypes.Void));
AsyncTaskMethodBuilderStart = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
MemberFilter.Method ("Start", 1,
new ParametersImported (
new[] {
new ParameterData (null, Parameter.Modifier.REF),
},
new[] {
new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
}, false),
btypes.Void));
AsyncTaskMethodBuilderTask = new PredefinedMember<PropertySpec> (module, types.AsyncTaskMethodBuilder,
MemberFilter.Property ("Task", null));
@ -385,12 +447,54 @@ namespace Mono.CSharp @@ -385,12 +447,54 @@ namespace Mono.CSharp
AsyncTaskMethodBuilderGenericSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
"SetResult", MemberKind.Method, () => new TypeSpec[] {
types.AsyncTaskMethodBuilderGeneric.TypeSpec.MemberDefinition.TypeParameters[0]
});
}, btypes.Void);
AsyncTaskMethodBuilderGenericSetStateMachine = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
"SetStateMachine", MemberKind.Method, () => new[] {
types.IAsyncStateMachine.TypeSpec
}, btypes.Void);
AsyncTaskMethodBuilderGenericSetException = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
MemberFilter.Method ("SetException", 0,
ParametersCompiled.CreateFullyResolved (btypes.Exception), btypes.Void));
AsyncTaskMethodBuilderGenericOnCompleted = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
MemberFilter.Method ("AwaitOnCompleted", 2,
new ParametersImported (
new[] {
new ParameterData (null, Parameter.Modifier.REF),
new ParameterData (null, Parameter.Modifier.REF)
},
new[] {
new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
}, false),
btypes.Void));
AsyncTaskMethodBuilderGenericOnCompletedUnsafe = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
MemberFilter.Method ("AwaitUnsafeOnCompleted", 2,
new ParametersImported (
new[] {
new ParameterData (null, Parameter.Modifier.REF),
new ParameterData (null, Parameter.Modifier.REF)
},
new[] {
new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
}, false),
btypes.Void));
AsyncTaskMethodBuilderGenericStart = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
MemberFilter.Method ("Start", 1,
new ParametersImported (
new[] {
new ParameterData (null, Parameter.Modifier.REF),
},
new[] {
new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
}, false),
btypes.Void));
AsyncTaskMethodBuilderGenericTask = new PredefinedMember<PropertySpec> (module, types.AsyncTaskMethodBuilderGeneric,
MemberFilter.Property ("Task", null));
@ -403,6 +507,48 @@ namespace Mono.CSharp @@ -403,6 +507,48 @@ namespace Mono.CSharp
AsyncVoidMethodBuilderSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
MemberFilter.Method ("SetResult", 0, ParametersCompiled.EmptyReadOnlyParameters, btypes.Void));
AsyncVoidMethodBuilderSetStateMachine = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
"SetStateMachine", MemberKind.Method, () => new[] {
types.IAsyncStateMachine.TypeSpec
}, btypes.Void);
AsyncVoidMethodBuilderOnCompleted = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
MemberFilter.Method ("AwaitOnCompleted", 2,
new ParametersImported (
new[] {
new ParameterData (null, Parameter.Modifier.REF),
new ParameterData (null, Parameter.Modifier.REF)
},
new[] {
new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
}, false),
btypes.Void));
AsyncVoidMethodBuilderOnCompletedUnsafe = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
MemberFilter.Method ("AwaitUnsafeOnCompleted", 2,
new ParametersImported (
new[] {
new ParameterData (null, Parameter.Modifier.REF),
new ParameterData (null, Parameter.Modifier.REF)
},
new[] {
new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
}, false),
btypes.Void));
AsyncVoidMethodBuilderStart = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
MemberFilter.Method ("Start", 1,
new ParametersImported (
new[] {
new ParameterData (null, Parameter.Modifier.REF),
},
new[] {
new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
}, false),
btypes.Void));
DebuggerBrowsableAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.DebuggerBrowsable,
MemberFilter.Constructor (null));
@ -464,7 +610,6 @@ namespace Mono.CSharp @@ -464,7 +610,6 @@ namespace Mono.CSharp
false),
btypes.Int));
var tp = new TypeParameter(0, new MemberName("T"), null, null, Variance.None);
InterlockedCompareExchange_T = new PredefinedMember<MethodSpec> (module, types.Interlocked,
MemberFilter.Method ("CompareExchange", 1,
new ParametersImported (
@ -743,8 +888,8 @@ namespace Mono.CSharp @@ -743,8 +888,8 @@ namespace Mono.CSharp
};
}
public PredefinedMember (ModuleContainer module, PredefinedType type, string name, MemberKind kind, Func<TypeSpec[]> typesBuilder)
: this (module, type, new MemberFilter (name, 0, kind, null, null))
public PredefinedMember (ModuleContainer module, PredefinedType type, string name, MemberKind kind, Func<TypeSpec[]> typesBuilder, TypeSpec returnType)
: this (module, type, new MemberFilter (name, 0, kind, null, returnType))
{
filter_builder = typesBuilder;
}

3
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/typespec.cs

@ -1061,8 +1061,7 @@ namespace Mono.CSharp @@ -1061,8 +1061,7 @@ namespace Mono.CSharp
if (!IsEqual (a.Types[i], b.Types[i]))
return false;
const Parameter.Modifier ref_out = Parameter.Modifier.REF | Parameter.Modifier.OUT;
if ((a.FixedParameters[i].ModFlags & ref_out) != (b.FixedParameters[i].ModFlags & ref_out))
if ((a.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask) != (b.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask))
return false;
}

9
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/visit.cs

@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
// visit.cs: Visitors for parsed dom
//
// Authors: Mike Krüger (mkrueger@novell.com)
// Marek Safar (marek.safar@gmail.com)
// Marek Safar (marek.safar@gmail.com)
//
// Dual licensed under the terms of the MIT X11 or GNU GPL
//
@ -26,16 +26,15 @@ namespace Mono.CSharp @@ -26,16 +26,15 @@ namespace Mono.CSharp
foreach (var container in mc.Containers) {
container.Accept (this);
}
}
void VisitTypeDefinition (TypeDefinition tc)
{
foreach (var container in tc.Members) {
container.Accept (this);
foreach (var member in tc.Members) {
member.Accept (this);
}
}
public virtual void Visit (NamespaceContainer ns)
{
}

27
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/BaseRefactoringContext.cs

@ -34,12 +34,13 @@ using ICSharpCode.NRefactory.TypeSystem; @@ -34,12 +34,13 @@ using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.NRefactory.Editor;
using System.ComponentModel.Design;
using ICSharpCode.NRefactory.CSharp.Analysis;
namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
public abstract class BaseRefactoringContext : IServiceProvider
{
protected readonly CSharpAstResolver resolver;
readonly CSharpAstResolver resolver;
readonly CancellationToken cancellationToken;
public virtual bool Supports(Version version)
@ -65,6 +66,12 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -65,6 +66,12 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
}
}
public CSharpAstResolver Resolver {
get {
return resolver;
}
}
public virtual CSharpParsedFile ParsedFile {
get {
return resolver.ParsedFile;
@ -113,7 +120,23 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -113,7 +120,23 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
return resolver.GetConversion(expression, cancellationToken);
}
#endregion
#region Code Analyzation
/// <summary>
/// Creates a new definite assignment analysis object with a given root statement.
/// </summary>
/// <returns>
/// The definite assignment analysis object.
/// </returns>
/// <param name='root'>
/// The root statement.
/// </param>
public DefiniteAssignmentAnalysis CreateDefiniteAssignmentAnalysis (Statement root)
{
return new DefiniteAssignmentAnalysis (root, resolver, CancellationToken);
}
#endregion
/// <summary>
/// Translates the english input string to the context language.
/// </summary>

18
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeAction.cs

@ -27,18 +27,36 @@ using System; @@ -27,18 +27,36 @@ using System;
namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
/// <summary>
/// A code action provides a code transformation with a description.
/// </summary>
public class CodeAction
{
/// <summary>
/// Gets the description.
/// </summary>
public string Description {
get;
private set;
}
/// <summary>
/// Gets the code transformation.
/// </summary>
public Action<Script> Run {
get;
private set;
}
/// <summary>
/// Initializes a new instance of the <see cref="ICSharpCode.NRefactory.CSharp.Refactoring.CodeAction"/> class.
/// </summary>
/// <param name='description'>
/// The description.
/// </param>
/// <param name='action'>
/// The code transformation.
/// </param>
public CodeAction (string description, Action<Script> action)
{
if (action == null) {

29
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CheckIfParameterIsNullAction.cs

@ -33,40 +33,25 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -33,40 +33,25 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
/// Creates a 'if (param == null) throw new System.ArgumentNullException ();' contruct for a parameter.
/// </summary>
[ContextAction("Check if parameter is null", Description = "Checks function parameter is not null.")]
public class CheckIfParameterIsNullAction : ICodeActionProvider
public class CheckIfParameterIsNullAction : SpecializedCodeAction<ParameterDeclaration>
{
public IEnumerable<CodeAction> GetActions(RefactoringContext context)
protected override CodeAction GetAction(RefactoringContext context, ParameterDeclaration parameter)
{
var parameter = GetParameterDeclaration(context);
if (parameter == null) {
yield break;
}
var bodyStatement = parameter.Parent.GetChildByRole(Roles.Body);
if (bodyStatement == null) {
yield break;
}
if (bodyStatement == null)
return null;
var type = context.ResolveType(parameter.Type);
if (type.IsReferenceType == false || HasNullCheck(parameter)) {
yield break;
}
if (type.IsReferenceType == false || HasNullCheck(parameter))
return null;
yield return new CodeAction (context.TranslateString("Add null check for parameter"), script => {
return new CodeAction (context.TranslateString("Add null check for parameter"), script => {
var statement = new IfElseStatement () {
Condition = new BinaryOperatorExpression (new IdentifierExpression (parameter.Name), BinaryOperatorType.Equality, new NullReferenceExpression ()),
TrueStatement = new ThrowStatement (new ObjectCreateExpression (context.CreateShortType("System", "ArgumentNullException"), new PrimitiveExpression (parameter.Name)))
};
script.AddTo(bodyStatement, statement);
});
}
static ParameterDeclaration GetParameterDeclaration (RefactoringContext context)
{
return context.GetNode<ICSharpCode.NRefactory.CSharp.ParameterDeclaration> ();
}
static bool HasNullCheck (ParameterDeclaration parameter)
{

13
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertDecToHexAction.cs

@ -37,16 +37,15 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -37,16 +37,15 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
public IEnumerable<CodeAction> GetActions(RefactoringContext context)
{
var pexpr = context.GetNode<PrimitiveExpression>();
if (pexpr == null || pexpr.LiteralValue.StartsWith("0X", System.StringComparison.OrdinalIgnoreCase)) {
if (pexpr == null || pexpr.LiteralValue.StartsWith("0X", System.StringComparison.OrdinalIgnoreCase))
yield break;
}
if (!((pexpr.Value is int) || (pexpr.Value is long) || (pexpr.Value is short) || (pexpr.Value is sbyte) ||
(pexpr.Value is uint) || (pexpr.Value is ulong) || (pexpr.Value is ushort) || (pexpr.Value is byte))) {
var value = pexpr.Value;
if (value is string)
yield break;
}
yield return new CodeAction(context.TranslateString("Convert dec to hex"), script => {
script.Replace(pexpr, new PrimitiveExpression (pexpr.Value, string.Format("0x{0:x}", pexpr.Value)));
script.Replace(pexpr, new PrimitiveExpression (value, string.Format("0x{0:x}", value)));
});
}
}

105
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateClassDeclarationAction.cs

@ -27,6 +27,7 @@ @@ -27,6 +27,7 @@
using System.Collections.Generic;
using ICSharpCode.NRefactory.Semantics;
using System.Linq;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
@ -71,7 +72,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -71,7 +72,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
var result = node is SimpleType ?
CreateClassFromType(context, (SimpleType)node) :
CreateClassFromObjectCreation(context, (ObjectCreateExpression)node);
return AddBaseTypesAccordingToNamingRules(context, service, result);
}
@ -115,9 +116,109 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -115,9 +116,109 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
};
decl.Parameters.AddRange(CreateMethodDeclarationAction.GenerateParameters(context, createExpression.Arguments));
}
var guessedType = CreateFieldAction.GuessType(context, createExpression);
if (guessedType.Kind == TypeKind.Interface || guessedType.Kind == TypeKind.Class && guessedType.GetDefinition ().IsAbstract) {
result.BaseTypes.Add(context.CreateShortType(guessedType));
AddImplementation(context, result, guessedType);
}
return result;
}
static Modifiers GetModifiers(IEntity property)
{
if (property.DeclaringType.Kind == TypeKind.Interface)
return Modifiers.Public;
switch (property.Accessibility) {
case Accessibility.Public:
return Modifiers.Public | Modifiers.Override;
case Accessibility.Protected:
return Modifiers.Protected | Modifiers.Override;
case Accessibility.Internal:
return Modifiers.Internal | Modifiers.Override;
case Accessibility.ProtectedOrInternal:
// TODO: oops
return Modifiers.Internal | Modifiers.Protected | Modifiers.Override;
case Accessibility.ProtectedAndInternal:
// TODO: oops
return Modifiers.Internal | Modifiers.Protected | Modifiers.Override;
}
return Modifiers.Override;
}
static void AddImplementation(RefactoringContext context, TypeDeclaration result, ICSharpCode.NRefactory.TypeSystem.IType guessedType)
{
foreach (var property in guessedType.GetProperties ()) {
if (!property.IsAbstract)
continue;
if (property.IsIndexer) {
var indexerDecl = new IndexerDeclaration() {
ReturnType = context.CreateShortType(property.ReturnType),
Modifiers = GetModifiers(property),
Name = property.Name
};
indexerDecl.Parameters.AddRange(ConvertParameters(context, property.Parameters));
if (property.CanGet)
indexerDecl.Getter = new Accessor();
if (property.CanSet)
indexerDecl.Setter = new Accessor();
result.AddChild(indexerDecl, Roles.TypeMemberRole);
continue;
}
var propDecl = new PropertyDeclaration() {
ReturnType = context.CreateShortType(property.ReturnType),
Modifiers = GetModifiers (property),
Name = property.Name
};
if (property.CanGet)
propDecl.Getter = new Accessor();
if (property.CanSet)
propDecl.Setter = new Accessor();
result.AddChild(propDecl, Roles.TypeMemberRole);
}
foreach (var method in guessedType.GetMethods ()) {
if (!method.IsAbstract)
continue;
var decl = new MethodDeclaration() {
ReturnType = context.CreateShortType(method.ReturnType),
Modifiers = GetModifiers (method),
Name = method.Name,
Body = new BlockStatement() {
new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException")))
}
};
decl.Parameters.AddRange(ConvertParameters(context, method.Parameters));
result.AddChild(decl, Roles.TypeMemberRole);
}
foreach (var evt in guessedType.GetEvents ()) {
if (!evt.IsAbstract)
continue;
var decl = new EventDeclaration() {
ReturnType = context.CreateShortType(evt.ReturnType),
Modifiers = GetModifiers (evt),
Name = evt.Name
};
result.AddChild(decl, Roles.TypeMemberRole);
}
}
static IEnumerable<ParameterDeclaration> ConvertParameters(RefactoringContext context, IList<IParameter> parameters)
{
foreach (var param in parameters) {
ParameterModifier mod = ParameterModifier.None;
if (param.IsOut) {
mod = ParameterModifier.Out;
} else if (param.IsRef) {
mod = ParameterModifier.Ref;
} else if (param.IsParams) {
mod = ParameterModifier.Params;
}
yield return new ParameterDeclaration(context.CreateShortType(param.Type), param.Name, mod);
}
}
static TypeDeclaration AddBaseTypesAccordingToNamingRules(RefactoringContext context, NamingConventionService service, TypeDeclaration result)
{
if (service.HasValidRule(result.Name, AffectedEntity.CustomAttributes, Modifiers.Public)) {

52
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateFieldAction.cs

@ -95,13 +95,13 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -95,13 +95,13 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
return -1;
}
static IEnumerable<IType> GetAllValidTypesFromInvokation(RefactoringContext context, InvocationExpression invoke, AstNode parameter)
static IEnumerable<IType> GetAllValidTypesFromInvokation(CSharpAstResolver resolver, InvocationExpression invoke, AstNode parameter)
{
int index = GetArgumentIndex(invoke.Arguments, parameter);
if (index < 0)
yield break;
var targetResult = context.Resolve(invoke.Target);
var targetResult = resolver.Resolve(invoke.Target);
if (targetResult is MethodGroupResolveResult) {
foreach (var method in ((MethodGroupResolveResult)targetResult).Methods) {
if (index < method.Parameters.Count) {
@ -111,13 +111,13 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -111,13 +111,13 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
}
}
static IEnumerable<IType> GetAllValidTypesFromObjectCreation(RefactoringContext context, ObjectCreateExpression invoke, AstNode parameter)
static IEnumerable<IType> GetAllValidTypesFromObjectCreation(CSharpAstResolver resolver, ObjectCreateExpression invoke, AstNode parameter)
{
int index = GetArgumentIndex(invoke.Arguments, parameter);
if (index < 0)
yield break;
var targetResult = context.Resolve(invoke.Type);
var targetResult = resolver.Resolve(invoke.Type);
if (targetResult is TypeResolveResult) {
var type = ((TypeResolveResult)targetResult).Type;
if (type.Kind == TypeKind.Delegate && index == 0) {
@ -131,13 +131,13 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -131,13 +131,13 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
}
}
internal static IEnumerable<IType> GetValidTypes(RefactoringContext context, Expression expr)
internal static IEnumerable<IType> GetValidTypes(CSharpAstResolver resolver, Expression expr)
{
if (expr.Parent is DirectionExpression) {
var parent = expr.Parent.Parent;
if (parent is InvocationExpression) {
var invoke = (InvocationExpression)parent;
return GetAllValidTypesFromInvokation(context, invoke, expr.Parent);
return GetAllValidTypesFromInvokation(resolver, invoke, expr.Parent);
}
}
@ -145,7 +145,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -145,7 +145,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
var parent = expr.Parent;
if (parent is ObjectCreateExpression) {
var invoke = (ObjectCreateExpression)parent;
return GetAllValidTypesFromObjectCreation(context, invoke, expr);
return GetAllValidTypesFromObjectCreation(resolver, invoke, expr);
}
}
@ -153,59 +153,73 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -153,59 +153,73 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
var parent = expr.Parent;
if (parent is InvocationExpression) {
var invoke = (InvocationExpression)parent;
return GetAllValidTypesFromInvokation(context, invoke, expr);
return GetAllValidTypesFromInvokation(resolver, invoke, expr);
}
}
if (expr.Parent is VariableInitializer) {
var initializer = (VariableInitializer)expr.Parent;
return new [] { context.Resolve(initializer).Type };
return new [] { resolver.Resolve(initializer).Type };
}
if (expr.Parent is CastExpression) {
var cast = (CastExpression)expr.Parent;
return new [] { context.Resolve(cast.Type).Type };
return new [] { resolver.Resolve(cast.Type).Type };
}
if (expr.Parent is AsExpression) {
var cast = (AsExpression)expr.Parent;
return new [] { context.Resolve(cast.Type).Type };
return new [] { resolver.Resolve(cast.Type).Type };
}
if (expr.Parent is AssignmentExpression) {
var assign = (AssignmentExpression)expr.Parent;
var other = assign.Left == expr ? assign.Right : assign.Left;
return new [] { context.Resolve(other).Type };
return new [] { resolver.Resolve(other).Type };
}
if (expr.Parent is BinaryOperatorExpression) {
var assign = (BinaryOperatorExpression)expr.Parent;
var other = assign.Left == expr ? assign.Right : assign.Left;
return new [] { context.Resolve(other).Type };
return new [] { resolver.Resolve(other).Type };
}
if (expr.Parent is ReturnStatement) {
var state = context.GetResolverStateBefore(expr);
var state = resolver.GetResolverStateBefore(expr);
if (state != null)
return new [] { state.CurrentMember.ReturnType };
}
if (expr.Parent is YieldReturnStatement) {
var state = context.GetResolverStateBefore(expr);
var state = resolver.GetResolverStateBefore(expr);
if (state != null && (state.CurrentMember.ReturnType is ParameterizedType)) {
var pt = (ParameterizedType)state.CurrentMember.ReturnType;
if (pt.FullName == "System.Collections.Generic.IEnumerable") {
return new [] { pt.TypeArguments.First () };
return new [] { pt.TypeArguments.First() };
}
}
}
if (expr.Parent is UnaryOperatorExpression) {
var uop = (UnaryOperatorExpression)expr.Parent;
switch (uop.Operator) {
case UnaryOperatorType.Not:
return new [] { resolver.Compilation.FindType(KnownTypeCode.Boolean) };
case UnaryOperatorType.Minus:
case UnaryOperatorType.Plus:
case UnaryOperatorType.Increment:
case UnaryOperatorType.Decrement:
case UnaryOperatorType.PostIncrement:
case UnaryOperatorType.PostDecrement:
return new [] { resolver.Compilation.FindType(KnownTypeCode.Int32) };
}
}
return Enumerable.Empty<IType>();
}
static readonly IType[] emptyTypes = new IType[0];
internal static AstType GuessAstType(RefactoringContext context, Expression expr)
{
var type = GetValidTypes(context, expr).ToArray();
var type = GetValidTypes(context.Resolver, expr).ToArray();
var typeInference = new TypeInference(context.Compilation);
typeInference.Algorithm = TypeInferenceAlgorithm.ImprovedReturnAllResults;
var inferedType = typeInference.FindTypeInBounds(type, emptyTypes);
@ -216,7 +230,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -216,7 +230,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
internal static IType GuessType(RefactoringContext context, Expression expr)
{
var type = GetValidTypes(context, expr).ToArray();
var type = GetValidTypes(context.Resolver, expr).ToArray();
var typeInference = new TypeInference(context.Compilation);
typeInference.Algorithm = TypeInferenceAlgorithm.ImprovedReturnAllResults;
var inferedType = typeInference.FindTypeInBounds(type, emptyTypes);

2
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateIndexerAction.cs

@ -43,6 +43,8 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -43,6 +43,8 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
yield break;
var state = context.GetResolverStateBefore(indexer);
if (state.CurrentTypeDefinition == null)
yield break;
var guessedType = CreateFieldAction.GuessAstType(context, indexer);
bool createInOtherType = false;

136
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateMethodDeclarationAction.cs

@ -40,6 +40,10 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -40,6 +40,10 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
var identifier = context.GetNode<IdentifierExpression>();
if (identifier != null && !(identifier.Parent is InvocationExpression && ((InvocationExpression)identifier.Parent).Target == identifier))
return GetActionsFromIdentifier(context, identifier);
var memberReference = context.GetNode<MemberReferenceExpression>();
if (memberReference != null && !(memberReference.Parent is InvocationExpression && ((InvocationExpression)memberReference.Parent).Target == memberReference))
return GetActionsFromMemberReferenceExpression(context, memberReference);
var invocation = context.GetNode<InvocationExpression>();
if (invocation != null)
@ -47,7 +51,54 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -47,7 +51,54 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
return Enumerable.Empty<CodeAction>();
}
public IEnumerable<CodeAction> GetActionsFromIdentifier(RefactoringContext context, IdentifierExpression identifier)
IEnumerable<CodeAction> GetActionsFromMemberReferenceExpression(RefactoringContext context, MemberReferenceExpression invocation)
{
if (!(context.Resolve(invocation).IsError))
yield break;
var methodName = invocation.MemberName;
var guessedType = CreateFieldAction.GuessType(context, invocation);
if (guessedType.Kind != TypeKind.Delegate)
yield break;
var invocationMethod = guessedType.GetDelegateInvokeMethod();
var state = context.GetResolverStateBefore(invocation);
if (state.CurrentTypeDefinition == null)
yield break;
ResolveResult targetResolveResult = context.Resolve(invocation.Target);
bool createInOtherType = !state.CurrentTypeDefinition.Equals(targetResolveResult.Type.GetDefinition());
bool isStatic;
if (createInOtherType) {
if (targetResolveResult.Type.GetDefinition() == null || targetResolveResult.Type.GetDefinition().Region.IsEmpty)
yield break;
isStatic = targetResolveResult is TypeResolveResult;
if (isStatic && targetResolveResult.Type.Kind == TypeKind.Interface)
yield break;
} else {
if (state.CurrentMember == null)
yield break;
isStatic = state.CurrentMember.IsStatic || state.CurrentTypeDefinition.IsStatic;
}
// var service = (NamingConventionService)context.GetService(typeof(NamingConventionService));
// if (service != null && !service.IsValidName(methodName, AffectedEntity.Method, Modifiers.Private, isStatic)) {
// yield break;
// }
yield return CreateAction(
context,
methodName,
context.CreateShortType(invocationMethod.ReturnType),
invocationMethod.Parameters.Select(parameter => new ParameterDeclaration(context.CreateShortType(parameter.Type), parameter.Name) {
ParameterModifier = GetModifiers(parameter)
}),
createInOtherType,
isStatic,
targetResolveResult);
}
IEnumerable<CodeAction> GetActionsFromIdentifier(RefactoringContext context, IdentifierExpression identifier)
{
if (!(context.Resolve(identifier).IsError))
yield break;
@ -65,39 +116,19 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -65,39 +116,19 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
if (service != null && !service.IsValidName(methodName, AffectedEntity.Method, Modifiers.Private, isStatic))
yield break;
yield return new CodeAction(context.TranslateString("Create delegate handler"), script => {
var decl = new MethodDeclaration() {
ReturnType = context.CreateShortType(invocationMethod.ReturnType),
Name = methodName,
Body = new BlockStatement() {
new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException")))
}
};
if (isStatic)
decl.Modifiers |= Modifiers.Static;
foreach (var parameter in invocationMethod.Parameters) {
decl.Parameters.Add(new ParameterDeclaration(context.CreateShortType (parameter.Type), parameter.Name) {
ParameterModifier = GetModifiers(parameter)
});
}
script.InsertWithCursor(context.TranslateString("Create delegate handler"), decl, Script.InsertPosition.Before);
});
yield return CreateAction(
context,
methodName,
context.CreateShortType(invocationMethod.ReturnType),
invocationMethod.Parameters.Select(parameter => new ParameterDeclaration(context.CreateShortType(parameter.Type), parameter.Name) {
ParameterModifier = GetModifiers(parameter)
}),
false,
isStatic,
null);
}
static ParameterModifier GetModifiers(IParameter parameter)
{
if (parameter.IsOut)
return ParameterModifier.Out;
if (parameter.IsRef)
return ParameterModifier.Ref;
if (parameter.IsParams)
return ParameterModifier.Params;
return ParameterModifier.None;
}
public IEnumerable<CodeAction> GetActionsFromInvocation(RefactoringContext context, InvocationExpression invocation)
IEnumerable<CodeAction> GetActionsFromInvocation(RefactoringContext context, InvocationExpression invocation)
{
if (!(context.Resolve(invocation.Target).IsError))
yield break;
@ -106,6 +137,8 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -106,6 +137,8 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
if (methodName == null)
yield break;
var state = context.GetResolverStateBefore(invocation);
if (state.CurrentMember == null || state.CurrentTypeDefinition == null)
yield break;
var guessedType = invocation.Parent is ExpressionStatement ? new PrimitiveType("void") : CreateFieldAction.GuessAstType(context, invocation);
bool createInOtherType = false;
@ -123,8 +156,6 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -123,8 +156,6 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
if (isStatic && targetResolveResult.Type.Kind == TypeKind.Interface)
yield break;
} else {
if (state.CurrentMember == null || state.CurrentTypeDefinition == null)
yield break;
isStatic = state.CurrentMember.IsStatic || state.CurrentTypeDefinition.IsStatic;
}
@ -133,15 +164,40 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -133,15 +164,40 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
// yield break;
// }
yield return new CodeAction(context.TranslateString("Create method"), script => {
yield return CreateAction(
context,
methodName,
guessedType,
GenerateParameters(context, invocation.Arguments),
createInOtherType,
isStatic,
targetResolveResult);
}
static ParameterModifier GetModifiers(IParameter parameter)
{
if (parameter.IsOut)
return ParameterModifier.Out;
if (parameter.IsRef)
return ParameterModifier.Ref;
if (parameter.IsParams)
return ParameterModifier.Params;
return ParameterModifier.None;
}
static CodeAction CreateAction(RefactoringContext context, string methodName, AstType returnType, IEnumerable<ParameterDeclaration> parameters, bool createInOtherType, bool isStatic, ResolveResult targetResolveResult)
{
return new CodeAction(context.TranslateString("Create method"), script => {
var decl = new MethodDeclaration() {
ReturnType = guessedType,
ReturnType = returnType,
Name = methodName,
Body = new BlockStatement() {
new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException")))
}
};
decl.Parameters.AddRange(GenerateParameters (context, invocation.Arguments));
decl.Parameters.AddRange(parameters);
if (isStatic)
decl.Modifiers |= Modifiers.Static;
@ -267,6 +323,11 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -267,6 +323,11 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
case "System.Char":
return "ch";
case "System.Double":
case "System.Decimal":
return "d";
case "System.Single":
return "f";
case "System.String":
return "str";
@ -282,7 +343,6 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -282,7 +343,6 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
return returnType.Name;
}
string GetMethodName(InvocationExpression invocation)
{
if (invocation.Target is IdentifierExpression)

11
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreatePropertyAction.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
//
//
// CreateProperty.cs
//
// Author:
@ -56,6 +56,8 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -56,6 +56,8 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
if (guessedType == null)
yield break;
var state = context.GetResolverStateBefore(identifier);
if (state.CurrentTypeDefinition == null)
yield break;
bool createInOtherType = false;
ResolveResult targetResolveResult = null;
@ -64,15 +66,14 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -64,15 +66,14 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
createInOtherType = !state.CurrentTypeDefinition.Equals(targetResolveResult.Type.GetDefinition());
}
bool isStatic;
bool isStatic = targetResolveResult is TypeResolveResult;
if (createInOtherType) {
isStatic = targetResolveResult is TypeResolveResult;
if (isStatic && targetResolveResult.Type.Kind == TypeKind.Interface)
yield break;
} else {
if (state.CurrentMember == null || state.CurrentTypeDefinition == null)
if (state.CurrentMember == null)
yield break;
isStatic = state.CurrentMember.IsStatic || state.CurrentTypeDefinition.IsStatic;
isStatic |= state.CurrentMember.IsStatic || state.CurrentTypeDefinition.IsStatic;
}
// var service = (NamingConventionService)context.GetService(typeof(NamingConventionService));

186
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ExtractMethod/ExtractMethodAction.cs

@ -0,0 +1,186 @@ @@ -0,0 +1,186 @@
//
// ExtractMethodAction.cs
//
// Author:
// Mike Krüger <mkrueger@xamarin.com>
//
// Copyright (c) 2012 Xamarin Inc. (http://xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using ICSharpCode.NRefactory.Semantics;
using System.Linq;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.CSharp.Analysis;
using System.Threading;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.NRefactory.CSharp.Refactoring.ExtractMethod
{
[ContextAction("Extract method", Description = "Creates a new method out of selected text.")]
public class ExtractMethodAction : ICodeActionProvider
{
public IEnumerable<CodeAction> GetActions(RefactoringContext context)
{
if (!context.IsSomethingSelected)
yield break;
var selected = new List<AstNode>(context.GetSelectedNodes());
if (selected.Count == 0)
yield break;
if (selected.Count == 1 && selected [0] is Expression) {
var codeAction = CreateFromExpression(context, (Expression)selected [0]);
if (codeAction == null)
yield break;
yield return codeAction;
}
foreach (var node in selected) {
if (!(node is Statement))
yield break;
}
var action = CreateFromStatements (context, new List<Statement> (selected.OfType<Statement> ()));
if (action != null)
yield return action;
}
CodeAction CreateFromExpression(RefactoringContext context, Expression expression)
{
var resolveResult = context.Resolve(expression);
if (resolveResult.IsError)
return null;
return new CodeAction(context.TranslateString("Extract method"), script => {
string methodName = "NewMethod";
var method = new MethodDeclaration() {
ReturnType = context.CreateShortType(resolveResult.Type),
Name = methodName,
Body = new BlockStatement() {
new ReturnStatement(expression.Clone())
}
};
if (!StaticVisitor.UsesNotStaticMember(context, expression))
method.Modifiers |= Modifiers.Static;
script.InsertWithCursor(context.TranslateString("Extract method"), method, Script.InsertPosition.Before);
var target = new IdentifierExpression(methodName);
script.Replace(expression, new InvocationExpression(target));
// script.Link(target, method.NameToken);
});
}
CodeAction CreateFromStatements(RefactoringContext context, List<Statement> statements)
{
if (!(statements [0].Parent is Statement))
return null;
return new CodeAction(context.TranslateString("Extract method"), script => {
string methodName = "NewMethod";
var method = new MethodDeclaration() {
ReturnType = new PrimitiveType("void"),
Name = methodName,
Body = new BlockStatement()
};
bool usesNonStaticMember = false;
foreach (Statement node in statements) {
usesNonStaticMember |= StaticVisitor.UsesNotStaticMember(context, node);
method.Body.Add(node.Clone());
}
if (!usesNonStaticMember)
method.Modifiers |= Modifiers.Static;
var target = new IdentifierExpression(methodName);
var invocation = new InvocationExpression(target);
var usedVariables = VariableLookupVisitor.Analyze(context, statements);
var extractedCodeAnalysis = new DefiniteAssignmentAnalysis((Statement)statements [0].Parent, context.Resolver, context.CancellationToken);
var lastStatement = statements [statements.Count - 1];
extractedCodeAnalysis.SetAnalyzedRange(statements [0], lastStatement);
var statusAfterMethod = new List<Tuple<IVariable, DefiniteAssignmentStatus>>();
foreach (var variable in usedVariables) {
extractedCodeAnalysis.Analyze(variable.Name, DefiniteAssignmentStatus.PotentiallyAssigned, context.CancellationToken);
statusAfterMethod.Add(Tuple.Create(variable, extractedCodeAnalysis.GetStatusAfter(lastStatement)));
}
var stmt = statements [0].GetParent<BlockStatement>();
while (stmt.GetParent<BlockStatement> () != null) {
stmt = stmt.GetParent<BlockStatement>();
}
var wholeCodeAnalysis = new DefiniteAssignmentAnalysis(stmt, context.Resolver, context.CancellationToken);
var statusBeforeMethod = new Dictionary<IVariable, DefiniteAssignmentStatus>();
foreach (var variable in usedVariables) {
wholeCodeAnalysis.Analyze(variable.Name, DefiniteAssignmentStatus.PotentiallyAssigned, context.CancellationToken);
statusBeforeMethod [variable] = extractedCodeAnalysis.GetStatusBefore(statements [0]);
}
var afterCodeAnalysis = new DefiniteAssignmentAnalysis(stmt, context.Resolver, context.CancellationToken);
var statusAtEnd = new Dictionary<IVariable, DefiniteAssignmentStatus>();
afterCodeAnalysis.SetAnalyzedRange(lastStatement, stmt.Statements.Last(), false, true);
foreach (var variable in usedVariables) {
afterCodeAnalysis.Analyze(variable.Name, DefiniteAssignmentStatus.PotentiallyAssigned, context.CancellationToken);
statusBeforeMethod [variable] = extractedCodeAnalysis.GetStatusBefore(statements [0]);
}
var beforeVisitor = new VariableLookupVisitor(context);
beforeVisitor.SetAnalyzedRange(stmt, statements [0], true, false);
stmt.AcceptVisitor(beforeVisitor);
var afterVisitor = new VariableLookupVisitor(context);
afterVisitor.SetAnalyzedRange(lastStatement, stmt, false, true);
stmt.AcceptVisitor(afterVisitor);
foreach (var status in statusAfterMethod) {
if (!beforeVisitor.UsedVariables.Contains(status.Item1) && !afterVisitor.UsedVariables.Contains(status.Item1))
continue;
Expression argumentExpression = new IdentifierExpression(status.Item1.Name);
ParameterModifier mod;
switch (status.Item2) {
case DefiniteAssignmentStatus.AssignedAfterTrueExpression:
case DefiniteAssignmentStatus.AssignedAfterFalseExpression:
case DefiniteAssignmentStatus.PotentiallyAssigned:
mod = ParameterModifier.Ref;
argumentExpression = new DirectionExpression(FieldDirection.Ref, argumentExpression);
break;
case DefiniteAssignmentStatus.DefinitelyAssigned:
if (statusBeforeMethod [status.Item1] != DefiniteAssignmentStatus.PotentiallyAssigned)
goto case DefiniteAssignmentStatus.PotentiallyAssigned;
mod = ParameterModifier.Out;
argumentExpression = new DirectionExpression(FieldDirection.Out, argumentExpression);
break;
// case DefiniteAssignmentStatus.Unassigned:
default:
mod = ParameterModifier.None;
break;
}
method.Parameters.Add(new ParameterDeclaration(context.CreateShortType(status.Item1.Type), status.Item1.Name, mod));
invocation.Arguments.Add(argumentExpression);
}
foreach (var node in statements.Skip (1)) {
script.Remove(node);
}
script.Replace(statements [0], new ExpressionStatement(invocation));
script.InsertWithCursor(context.TranslateString("Extract method"), method, Script.InsertPosition.Before);
//script.Link(target, method.NameToken);
});
}
}
}

85
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ExtractMethod/StaticVisitor.cs

@ -0,0 +1,85 @@ @@ -0,0 +1,85 @@
//
// StaticVisitor.cs
//
// Author:
// Mike Krüger <mkrueger@xamarin.com>
//
// Copyright (c) 2012 Xamarin Inc. (http://xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using ICSharpCode.NRefactory.Semantics;
using System.Linq;
using ICSharpCode.NRefactory.CSharp.Resolver;
namespace ICSharpCode.NRefactory.CSharp.Refactoring.ExtractMethod
{
class StaticVisitor : DepthFirstAstVisitor
{
readonly RefactoringContext context;
public bool UsesNonStaticMember = false;
StaticVisitor(RefactoringContext context)
{
this.context = context;
}
public static bool UsesNotStaticMember(RefactoringContext context, AstNode node)
{
var visitor = new StaticVisitor(context);
node.AcceptVisitor(visitor);
return visitor.UsesNonStaticMember;
}
protected override void VisitChildren(AstNode node)
{
if (UsesNonStaticMember)
return;
base.VisitChildren(node);
}
public override void VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression)
{
UsesNonStaticMember = true;
base.VisitThisReferenceExpression(thisReferenceExpression);
}
public override void VisitBaseReferenceExpression(BaseReferenceExpression baseReferenceExpression)
{
UsesNonStaticMember = true;
base.VisitBaseReferenceExpression(baseReferenceExpression);
}
public override void VisitIdentifierExpression(IdentifierExpression identifierExpression)
{
var resolveResult = context.Resolve(identifierExpression);
if (resolveResult is MemberResolveResult) {
var memberResult = (MemberResolveResult)resolveResult;
if (!memberResult.Member.IsStatic)
UsesNonStaticMember = true;
} else if (resolveResult is MethodGroupResolveResult) {
var methodGroupResolveResult = (MethodGroupResolveResult)resolveResult;
if (methodGroupResolveResult.Methods.Any(m => !m.IsStatic))
UsesNonStaticMember = true;
}
}
}
}

97
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ExtractMethod/VariableLookupVisitor.cs

@ -0,0 +1,97 @@ @@ -0,0 +1,97 @@
//
// VariableLookupVisitor.cs
//
// Author:
// Mike Krüger <mkrueger@xamarin.com>
//
// Copyright (c) 2012 Xamarin Inc. (http://xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.NRefactory.CSharp.Refactoring.ExtractMethod
{
class VariableLookupVisitor : DepthFirstAstVisitor
{
readonly RefactoringContext context;
public List<IVariable> UsedVariables = new List<IVariable> ();
TextLocation startLocation = TextLocation.Empty;
TextLocation endLocation = TextLocation.Empty;
public VariableLookupVisitor (RefactoringContext context)
{
this.context = context;
}
public void SetAnalyzedRange(AstNode start, AstNode end, bool startInclusive = true, bool endInclusive = true)
{
if (start == null)
throw new ArgumentNullException("start");
if (end == null)
throw new ArgumentNullException("end");
startLocation = startInclusive ? start.StartLocation : start.EndLocation;
endLocation = endInclusive ? end.EndLocation : end.StartLocation;
}
public override void VisitIdentifierExpression(IdentifierExpression identifierExpression)
{
if (startLocation.IsEmpty || startLocation <= identifierExpression.StartLocation && identifierExpression.EndLocation <= endLocation) {
var result = context.Resolve(identifierExpression);
var local = result as LocalResolveResult;
if (local != null && !UsedVariables.Contains(local.Variable))
UsedVariables.Add(local.Variable);
}
}
public override void VisitVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement)
{
base.VisitVariableDeclarationStatement(variableDeclarationStatement);
foreach (var varDecl in variableDeclarationStatement.Variables) {
if (startLocation.IsEmpty || startLocation <= varDecl.StartLocation && varDecl.EndLocation <= endLocation) {
var result = context.Resolve(varDecl);
var local = result as LocalResolveResult;
if (local != null && !UsedVariables.Contains(local.Variable))
UsedVariables.Add(local.Variable);
}
}
}
public static List<IVariable> Analyze(RefactoringContext context, Expression expression)
{
var visitor = new VariableLookupVisitor(context);
expression.AcceptVisitor(visitor);
return visitor.UsedVariables;
}
public static List<IVariable> Analyze(RefactoringContext context, List<Statement> statements)
{
var visitor = new VariableLookupVisitor(context);
statements.ForEach(stmt => stmt.AcceptVisitor(visitor));
return visitor.UsedVariables;
}
}
}

7
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/GeneratePropertyAction.cs

@ -36,7 +36,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -36,7 +36,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
public IEnumerable<CodeAction> GetActions(RefactoringContext context)
{
var initializer = GetVariableInitializer(context);
var initializer = context.GetNode<VariableInitializer>();
if (initializer == null || !initializer.NameToken.Contains(context.Location.Line, context.Location.Column)) {
yield break;
}
@ -92,10 +92,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -92,10 +92,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
ret.Expression.IsMatch (new MemberReferenceExpression (new ThisReferenceExpression (), initializer.Name));
}
VariableInitializer GetVariableInitializer (RefactoringContext context)
{
return context.GetNode<VariableInitializer> ();
}
}
}

89
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/IntroduceConstantAction.cs

@ -0,0 +1,89 @@ @@ -0,0 +1,89 @@
//
// IntroduceConstantAction.cs
//
// Author:
// Mike Krüger <mkrueger@xamarin.com>
//
// Copyright (c) 2012 Xamarin <http://xamarin.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections.Generic;
namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
[ContextAction("Introduce constant", Description = "Creates a constant for a non constant primitive expression.")]
public class IntroduceConstantAction : ICodeActionProvider
{
public IEnumerable<CodeAction> GetActions(RefactoringContext context)
{
var pexpr = context.GetNode<PrimitiveExpression>();
if (pexpr == null)
yield break;
var statement = context.GetNode<Statement>();
if (statement == null) {
yield break;
}
var resolveResult = context.Resolve(pexpr);
yield return new CodeAction(context.TranslateString("Create local constant"), script => {
string name = CreateMethodDeclarationAction.CreateBaseName(pexpr, resolveResult.Type);
var service = (NamingConventionService)context.GetService(typeof(NamingConventionService));
if (service != null)
name = service.CheckName(context, name, AffectedEntity.LocalConstant);
var initializer = new VariableInitializer(name, pexpr.Clone());
var decl = new VariableDeclarationStatement() {
Type = context.CreateShortType(resolveResult.Type),
Modifiers = Modifiers.Const,
Variables = { initializer }
};
script.InsertBefore(statement, decl);
var variableUsage = new IdentifierExpression(name);
script.Replace(pexpr, variableUsage);
script.Link(initializer.NameToken, variableUsage);
});
yield return new CodeAction(context.TranslateString("Create constant field"), script => {
string name = CreateMethodDeclarationAction.CreateBaseName(pexpr, resolveResult.Type);
var service = (NamingConventionService)context.GetService(typeof(NamingConventionService));
if (service != null)
name = service.CheckName(context, name, AffectedEntity.ConstantField);
var initializer = new VariableInitializer(name, pexpr.Clone());
var decl = new FieldDeclaration() {
ReturnType = context.CreateShortType(resolveResult.Type),
Modifiers = Modifiers.Const,
Variables = { initializer }
};
var variableUsage = new IdentifierExpression(name);
script.Replace(pexpr, variableUsage);
// script.Link(initializer.NameToken, variableUsage);
script.InsertWithCursor(context.TranslateString("Create constant"), decl, Script.InsertPosition.Before);
});
}
}
}

2
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/RemoveBackingStoreAction.cs

@ -48,7 +48,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -48,7 +48,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
newProperty.Getter.Body = BlockStatement.Null;
newProperty.Setter.Body = BlockStatement.Null;
yield return new CodeAction(context.TranslateString("Remove backing store"), script => {
yield return new CodeAction(context.TranslateString("Convert to auto property"), script => {
script.Rename((IEntity)field, newProperty.Name);
script.Remove (context.RootNode.GetNodeAt<FieldDeclaration> (field.Region.Begin));
script.Replace (property, newProperty);

10
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/RemoveBracesAction.cs

@ -47,14 +47,16 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -47,14 +47,16 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
});
}
static BlockStatement GetBlockStatement (RefactoringContext context)
static BlockStatement GetBlockStatement(RefactoringContext context)
{
var block = context.GetNode<BlockStatement> ();
var block = context.GetNode<BlockStatement>();
if (block == null || block.LBraceToken.IsNull || block.RBraceToken.IsNull)
return null;
if (!(block.Parent is Statement))
if (!(block.LBraceToken.IsInside(context.Location) || block.RBraceToken.IsInside(context.Location)))
return null;
if (block.Statements.Count != 1)
if (!(block.Parent is Statement) || block.Parent is TryCatchStatement)
return null;
if (block.Statements.Count != 1 || block.Statements.First () is VariableDeclarationStatement)
return null;
return block;
}

38
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/SpecializedCodeAction.cs

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
using System;
namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
/// <summary>
/// A specialized code action creates a code action assoziated with one special type of ast nodes.
/// </summary>
public abstract class SpecializedCodeAction<T> : ICodeActionProvider where T : AstNode
{
/// <summary>
/// Gets the action for the specified ast node.
/// </summary>
/// <returns>
/// The code action. May return <c>null</c>, if no action can be provided.
/// </returns>
/// <param name='context'>
/// The refactoring conext.
/// </param>
/// <param name='node'>
/// The AstNode it's ensured that the node is always != null, if called.
/// </param>
protected abstract CodeAction GetAction(RefactoringContext context, T node);
#region ICodeActionProvider implementation
public System.Collections.Generic.IEnumerable<CodeAction> GetActions(RefactoringContext context)
{
var node = context.GetNode<T>();
if (node == null)
yield break;
var action = GetAction(context, node);
if (action == null)
yield break;
yield return action;
}
#endregion
}
}

49
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssue.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
//
//
// InspectionIssue.cs
//
// Author:
@ -29,28 +29,58 @@ using System.Linq; @@ -29,28 +29,58 @@ using System.Linq;
namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
/// <summary>
/// A code issue marks a region of text with an issue and can provide solution actions for this issue.
/// </summary>
public class CodeIssue
{
/// <summary>
/// Gets the desription of the issue.
/// </summary>
public string Desription {
get;
private set;
}
/// <summary>
/// Gets the issue start location.
/// </summary>
public TextLocation Start {
get;
private set;
}
/// <summary>
/// Gets the issue end location.
/// </summary>
public TextLocation End {
get;
private set;
}
/// <summary>
/// Gets a list of potential solutions for the issue.
/// </summary>
public IList<CodeAction> Actions {
get;
private set;
}
/// <summary>
/// Initializes a new instance of the <see cref="ICSharpCode.NRefactory.CSharp.Refactoring.CodeIssue"/> class.
/// </summary>
/// <param name='description'>
/// The desription of the issue.
/// </param>
/// <param name='start'>
/// The issue start location.
/// </param>
/// <param name='end'>
/// the issue end location.
/// </param>
/// <param name='actions'>
/// A list of potential solutions for the issue.
/// </param>
public CodeIssue(string description, TextLocation start, TextLocation end, IEnumerable<CodeAction> actions = null)
{
Desription = description;
@ -62,6 +92,21 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -62,6 +92,21 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
Actions = EmptyList<CodeAction>.Instance;
}
/// <summary>
/// Initializes a new instance of the <see cref="ICSharpCode.NRefactory.CSharp.Refactoring.CodeIssue"/> class.
/// </summary>
/// <param name='description'>
/// The desription of the issue.
/// </param>
/// <param name='start'>
/// The issue start location.
/// </param>
/// <param name='end'>
/// the issue end location.
/// </param>
/// <param name='action'>
/// A potential solution for the issue.
/// </param>
public CodeIssue(string description, TextLocation start, TextLocation end, CodeAction action) : this (description, start, end, action != null ? new [] { action } : null)
{
}

6
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ConditionalToNullCoalescingIssue.cs

@ -55,11 +55,9 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -55,11 +55,9 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
),
};
public IEnumerable<CodeIssue> GetIssues (BaseRefactoringContext context)
public IEnumerable<CodeIssue> GetIssues(BaseRefactoringContext context)
{
var visitor = new GatherVisitor (context, this);
context.RootNode.AcceptVisitor (visitor);
return visitor.FoundIssues;
return new GatherVisitor(context, this).GetIssues();
}
class GatherVisitor : GatherVisitorBase

71
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/ExplicitConversionInForEachIssue.cs

@ -0,0 +1,71 @@ @@ -0,0 +1,71 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
[IssueDescription("Incorrect element type in foreach over generic collection",
Description= "Detects hidden explicit conversions in foreach loops.",
Category = IssueCategories.CodeQualityIssues,
Severity = Severity.Warning)]
public class ExplicitConversionInForEachIssue : ICodeIssueProvider
{
public IEnumerable<CodeIssue> GetIssues(BaseRefactoringContext context)
{
return new GatherVisitor(context).GetIssues();
}
class GatherVisitor : GatherVisitorBase
{
CSharpConversions conversions;
public GatherVisitor (BaseRefactoringContext ctx) : base (ctx)
{
}
public override void VisitForeachStatement(ForeachStatement foreachStatement)
{
base.VisitForeachStatement(foreachStatement);
var rr = ctx.Resolve(foreachStatement) as ForEachResolveResult;
if (rr == null)
return;
if (rr.ElementType.Kind == TypeKind.Unknown)
return;
if (ReflectionHelper.GetTypeCode(rr.ElementType) == TypeCode.Object)
return;
if (conversions == null) {
conversions = CSharpConversions.Get(ctx.Compilation);
}
Conversion c = conversions.ImplicitConversion(rr.ElementType, rr.ElementVariable.Type);
if (c.IsValid)
return;
var csResolver = ctx.GetResolverStateBefore(foreachStatement);
var builder = new TypeSystemAstBuilder(csResolver);
AstType elementType = builder.ConvertType(rr.ElementType);
AstType variableType = foreachStatement.VariableType;
string text = ctx.TranslateString("Collection element type '{0}' is not implicitly convertible to '{1}'");
AddIssue(variableType, string.Format(text, elementType.GetText(), variableType.GetText()));
}
}
}
}

23
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/GatherVisitorBase.cs

@ -29,17 +29,38 @@ using System.Collections.Generic; @@ -29,17 +29,38 @@ using System.Collections.Generic;
namespace ICSharpCode.NRefactory.CSharp
{
/// <summary>
/// A base class for writing issue provider visitor implementations.
/// </summary>
class GatherVisitorBase : DepthFirstAstVisitor
{
protected readonly BaseRefactoringContext ctx;
public readonly List<CodeIssue> FoundIssues = new List<CodeIssue> ();
/// <summary>
/// Initializes a new instance of the <see cref="ICSharpCode.NRefactory.CSharp.GatherVisitorBase"/> class.
/// </summary>
/// <param name='ctx'>
/// The refactoring context.
/// </param>
public GatherVisitorBase (BaseRefactoringContext ctx)
{
this.ctx = ctx;
}
/// <summary>
/// Gets all the issues using the context root node as base.
/// </summary>
/// <returns>
/// The issues.
/// </returns>
public IEnumerable<CodeIssue> GetIssues()
{
ctx.RootNode.AcceptVisitor(this);
return FoundIssues;
}
protected override void VisitChildren (AstNode node)
{
if (ctx.CancellationToken.IsCancellationRequested)

14
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/InconsistentNamingIssue/DefaultRules.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
//
//
// DefaultRules.cs
//
// Author:
@ -73,6 +73,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -73,6 +73,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
yield return new NamingRule(AffectedEntity.ReadonlyField) {
Name = "Static Readonly Fields",
VisibilityMask = Modifiers.Public | Modifiers.Protected | Modifiers.Internal,
NamingStyle = NamingStyle.PascalCase,
IncludeInstanceMembers = false
};
@ -94,7 +95,16 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -94,7 +95,16 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
Name = "Fields (Private)",
NamingStyle = NamingStyle.CamelCase,
AllowedPrefixes = new [] { "_", "m_" },
VisibilityMask = Modifiers.Private
VisibilityMask = Modifiers.Private,
IncludeStaticEntities = false
};
yield return new NamingRule(AffectedEntity.Field) {
Name = "Static Fields (Private)",
NamingStyle = NamingStyle.CamelCase,
VisibilityMask = Modifiers.Private,
IncludeStaticEntities = true,
IncludeInstanceMembers = false
};
yield return new NamingRule(AffectedEntity.ReadonlyField) {

22
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/InconsistentNamingIssue/NamingConventionService.cs

@ -35,6 +35,28 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -35,6 +35,28 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
get;
}
public string CheckName(RefactoringContext ctx, string name, AffectedEntity entity, Modifiers accessibilty = Modifiers.Private, bool isStatic = false)
{
foreach (var rule in Rules) {
if (!rule.AffectedEntity.HasFlag(entity)) {
continue;
}
if (!rule.VisibilityMask.HasFlag(accessibilty)) {
continue;
}
if (isStatic && !rule.IncludeStaticEntities || !isStatic && !rule.IncludeInstanceMembers) {
continue;
}
if (!rule.IsValid(name)) {
IList<string> suggestedNames;
var msg = rule.GetErrorMessage(ctx, name, out suggestedNames);
if (suggestedNames.Any ())
return suggestedNames [0];
}
}
return name;
}
public bool IsValidName(string name, AffectedEntity entity, Modifiers accessibilty = Modifiers.Private, bool isStatic = false)
{
foreach (var rule in Rules) {

6
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/NotImplementedExceptionIssue.cs

@ -37,11 +37,9 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -37,11 +37,9 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
[IssueDescription("Show NotImplementedExceptions", Description="Shows NotImplementedException throws in the quick task bar.", Category = IssueCategories.Notifications, Severity = Severity.Suggestion, IssueMarker = IssueMarker.None)]
public class NotImplementedExceptionIssue : ICodeIssueProvider
{
public IEnumerable<CodeIssue> GetIssues (BaseRefactoringContext context)
public IEnumerable<CodeIssue> GetIssues(BaseRefactoringContext context)
{
var visitor = new GatherVisitor (context, this);
context.RootNode.AcceptVisitor (visitor);
return visitor.FoundIssues;
return new GatherVisitor(context, this).GetIssues();
}
class GatherVisitor : GatherVisitorBase

10
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantInternalIssue.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
//
//
// RedundantInternalInspector.cs
//
// Author:
@ -34,18 +34,16 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -34,18 +34,16 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
/// <summary>
/// Finds redundant internal modifiers.
/// </summary>
[IssueDescription("Remove redunant 'internal' modifier",
[IssueDescription("Remove redundant 'internal' modifier",
Description="Removes 'internal' modifiers that are not required.",
Category = IssueCategories.Redundancies,
Severity = Severity.Hint,
IssueMarker = IssueMarker.GrayOut)]
public class RedundantInternalIssue : ICodeIssueProvider
{
public IEnumerable<CodeIssue> GetIssues (BaseRefactoringContext context)
public IEnumerable<CodeIssue> GetIssues(BaseRefactoringContext context)
{
var visitor = new GatherVisitor (context, this);
context.RootNode.AcceptVisitor (visitor);
return visitor.FoundIssues;
return new GatherVisitor(context, this).GetIssues();
}
class GatherVisitor : GatherVisitorBase

52
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantNamespaceUsageIssue.cs

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
//
//
// RedundantNamespaceUsageInspector.cs
//
//
// Author:
// Mike Krüger <mkrueger@xamarin.com>
//
@ -37,17 +37,15 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -37,17 +37,15 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
/// Finds redundant namespace usages.
/// </summary>
[IssueDescription("Remove redundant namespace usages",
Description = "Removes namespace usages that are obsolete.",
Category = IssueCategories.Redundancies,
Severity = Severity.Hint,
IssueMarker = IssueMarker.GrayOut)]
Description = "Removes namespace usages that are obsolete.",
Category = IssueCategories.Redundancies,
Severity = Severity.Hint,
IssueMarker = IssueMarker.GrayOut)]
public class RedundantNamespaceUsageIssue : ICodeIssueProvider
{
public IEnumerable<CodeIssue> GetIssues (BaseRefactoringContext context)
public IEnumerable<CodeIssue> GetIssues(BaseRefactoringContext context)
{
var visitor = new GatherVisitor (context, this);
context.RootNode.AcceptVisitor (visitor);
return visitor.FoundIssues;
return new GatherVisitor(context, this).GetIssues();
}
class GatherVisitor : GatherVisitorBase
@ -62,24 +60,40 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -62,24 +60,40 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression)
{
base.VisitMemberReferenceExpression(memberReferenceExpression);
var result = ctx.Resolve(memberReferenceExpression.Target);
HandleMemberReference(
memberReferenceExpression, memberReferenceExpression.Target, memberReferenceExpression.MemberNameToken, memberReferenceExpression.TypeArguments, SimpleNameLookupMode.Expression,
script => {
script.Replace(memberReferenceExpression, RefactoringAstHelper.RemoveTarget(memberReferenceExpression));
});
}
public override void VisitMemberType(MemberType memberType)
{
base.VisitMemberType(memberType);
HandleMemberReference(
memberType, memberType.Target, memberType.MemberNameToken, memberType.TypeArguments, SimpleNameLookupMode.Type,
script => {
script.Replace(memberType, RefactoringAstHelper.RemoveTarget(memberType));
});
}
void HandleMemberReference(AstNode wholeNode, AstNode targetNode, Identifier memberName, IEnumerable<AstType> typeArguments, SimpleNameLookupMode mode, Action<Script> action)
{
var result = ctx.Resolve(targetNode);
if (!(result is NamespaceResolveResult)) {
return;
}
var wholeResult = ctx.Resolve(memberReferenceExpression);
var wholeResult = ctx.Resolve(wholeNode);
if (!(wholeResult is TypeResolveResult)) {
return;
}
var state = ctx.GetResolverStateBefore(memberReferenceExpression);
var lookupName = state.LookupSimpleNameOrTypeName(memberReferenceExpression.MemberName, new List<IType> (), SimpleNameLookupMode.Expression);
var state = ctx.GetResolverStateBefore(wholeNode);
var resolvedTypeArguments = typeArguments.Select(ctx.ResolveType).ToList();
var lookupName = state.LookupSimpleNameOrTypeName(memberName.Name, resolvedTypeArguments, mode);
if (lookupName is TypeResolveResult && !lookupName.IsError && wholeResult.Type.Equals(lookupName.Type)) {
AddIssue(memberReferenceExpression.StartLocation, memberReferenceExpression.MemberNameToken.StartLocation, ctx.TranslateString("Remove redundant namespace usage"), script => {
script.Replace(memberReferenceExpression, RefactoringAstHelper.RemoveTarget(memberReferenceExpression));
}
);
AddIssue(wholeNode.StartLocation, memberName.StartLocation, ctx.TranslateString("Remove redundant namespace usage"), action);
}
}
}

6
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantPrivateIssue.cs

@ -41,11 +41,9 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -41,11 +41,9 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
IssueMarker = IssueMarker.GrayOut)]
public class RedundantPrivateIssue : ICodeIssueProvider
{
public IEnumerable<CodeIssue> GetIssues (BaseRefactoringContext context)
public IEnumerable<CodeIssue> GetIssues(BaseRefactoringContext context)
{
var visitor = new GatherVisitor (context, this);
context.RootNode.AcceptVisitor (visitor);
return visitor.FoundIssues;
return new GatherVisitor(context, this).GetIssues();
}
class GatherVisitor : GatherVisitorBase

6
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantThisIssue.cs

@ -45,11 +45,9 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -45,11 +45,9 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
IssueMarker = IssueMarker.GrayOut)]
public class RedundantThisIssue : ICodeIssueProvider
{
public IEnumerable<CodeIssue> GetIssues (BaseRefactoringContext context)
public IEnumerable<CodeIssue> GetIssues(BaseRefactoringContext context)
{
var visitor = new GatherVisitor (context, this);
context.RootNode.AcceptVisitor (visitor);
return visitor.FoundIssues;
return new GatherVisitor(context, this).GetIssues();
}
class GatherVisitor : GatherVisitorBase

76
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantUsingIssue.cs

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
//
//
// RedundantUsingInspector.cs
//
//
// Author:
// Mike Krüger <mkrueger@xamarin.com>
//
@ -38,13 +38,23 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -38,13 +38,23 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
/// Finds redundant using declarations.
/// </summary>
[IssueDescription("Remove unused usings",
Description = "Removes used declarations that are not required.",
Category = IssueCategories.Redundancies,
Severity = Severity.Hint,
IssueMarker = IssueMarker.GrayOut)]
Description = "Removes used declarations that are not required.",
Category = IssueCategories.Redundancies,
Severity = Severity.Hint,
IssueMarker = IssueMarker.GrayOut)]
public class RedundantUsingIssue : ICodeIssueProvider
{
public IEnumerable<CodeIssue> GetIssues (BaseRefactoringContext context)
List<string> namespacesToKeep = new List<string>();
/// <summary>
/// The list of namespaces that should be kept even if they are not being used.
/// Used in SharpDevelop to always keep the "System" namespace around.
/// </summary>
public IList<string> NamespacesToKeep {
get { return namespacesToKeep; }
}
public IEnumerable<CodeIssue> GetIssues(BaseRefactoringContext context)
{
var visitor = new GatherVisitor (context, this);
context.RootNode.AcceptVisitor (visitor);
@ -55,22 +65,20 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -55,22 +65,20 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
class GatherVisitor : GatherVisitorBase
{
readonly RedundantUsingIssue inspector;
Dictionary<UsingDeclaration, bool> usingDeclarations = new Dictionary<UsingDeclaration, bool> ();
Stack<List<UsingDeclaration>> usingStack = new Stack<List<UsingDeclaration>> ();
Dictionary<UsingDeclaration, bool> isInUse = new Dictionary<UsingDeclaration, bool>();
Dictionary<string, UsingDeclaration> namespaceToUsingDecl = new Dictionary<string, UsingDeclaration>();
public GatherVisitor (BaseRefactoringContext ctx, RedundantUsingIssue inspector) : base (ctx)
{
this.inspector = inspector;
usingStack.Push (new List<UsingDeclaration> ());
}
public void Collect()
{
foreach (var u in usingDeclarations.Where (u => !u.Value)) {
foreach (var u in isInUse.Where (u => !u.Value)) {
var decl = u.Key;
AddIssue(decl, ctx.TranslateString("Remove redundant usings"), script => {
foreach (var u2 in usingDeclarations.Where (a => !a.Value)) {
foreach (var u2 in isInUse.Where (a => !a.Value)) {
script.Remove (u2.Key);
}
}
@ -81,30 +89,35 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -81,30 +89,35 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
public override void VisitUsingDeclaration(UsingDeclaration usingDeclaration)
{
base.VisitUsingDeclaration(usingDeclaration);
usingDeclarations [usingDeclaration] = false;
usingStack.Peek().Add(usingDeclaration);
var nrr = ctx.Resolve(usingDeclaration.Import) as NamespaceResolveResult;
if (nrr != null) {
isInUse[usingDeclaration] = inspector.namespacesToKeep.Contains(nrr.NamespaceName);
namespaceToUsingDecl[nrr.NamespaceName] = usingDeclaration;
}
}
public override void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration)
{
usingStack.Push(new List<UsingDeclaration> (usingStack.Peek()));
var oldNamespaceToUsingDecl = new Dictionary<string, UsingDeclaration>(namespaceToUsingDecl);
base.VisitNamespaceDeclaration(namespaceDeclaration);
usingStack.Pop();
namespaceToUsingDecl = oldNamespaceToUsingDecl;
}
void UseNamespace(string ns)
{
foreach (var u in usingStack.Peek ()) {
if (u.Namespace == ns) {
usingDeclarations [u] = true;
}
UsingDeclaration decl;
if (namespaceToUsingDecl.TryGetValue(ns, out decl)) {
isInUse[decl] = true;
}
}
public override void VisitIdentifierExpression(IdentifierExpression identifierExpression)
{
base.VisitIdentifierExpression(identifierExpression);
UseNamespace(ctx.Resolve(identifierExpression).Type.Namespace);
var trr = ctx.Resolve(identifierExpression) as TypeResolveResult;
if (trr != null) {
UseNamespace(trr.Type.Namespace);
}
}
public override void VisitSimpleType(SimpleType simpleType)
@ -116,13 +129,24 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -116,13 +129,24 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
public override void VisitInvocationExpression (InvocationExpression invocationExpression)
{
base.VisitInvocationExpression (invocationExpression);
var mg = ctx.Resolve (invocationExpression) as CSharpInvocationResolveResult;
if (mg == null || !mg.IsExtensionMethodInvocation) {
return;
UseExtensionMethod(ctx.Resolve(invocationExpression));
}
void UseExtensionMethod(ResolveResult rr)
{
var mg = rr as CSharpInvocationResolveResult;
if (mg != null && mg.IsExtensionMethodInvocation) {
UseNamespace (mg.Member.DeclaringType.Namespace);
}
UseNamespace (mg.Member.DeclaringType.Namespace);
}
public override void VisitQueryExpression(QueryExpression queryExpression)
{
base.VisitQueryExpression(queryExpression);
foreach (var clause in queryExpression.Clauses) {
UseExtensionMethod(ctx.Resolve(clause));
}
}
}
}
}

6
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/StringIsNullOrEmptyIssue.cs

@ -70,11 +70,9 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -70,11 +70,9 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
),
};
public IEnumerable<CodeIssue> GetIssues (BaseRefactoringContext context)
public IEnumerable<CodeIssue> GetIssues(BaseRefactoringContext context)
{
var visitor = new GatherVisitor (context, this);
context.RootNode.AcceptVisitor (visitor);
return visitor.FoundIssues;
return new GatherVisitor(context, this).GetIssues();
}
class GatherVisitor : GatherVisitorBase

6
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/UseVarKeywordIssue.cs

@ -43,11 +43,9 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -43,11 +43,9 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
IssueMarker = IssueMarker.None)]
public class UseVarKeywordIssue : ICodeIssueProvider
{
public IEnumerable<CodeIssue> GetIssues (BaseRefactoringContext context)
public IEnumerable<CodeIssue> GetIssues(BaseRefactoringContext context)
{
var visitor = new GatherVisitor (context, this);
context.RootNode.AcceptVisitor (visitor);
return visitor.FoundIssues;
return new GatherVisitor(context, this).GetIssues();
}
class GatherVisitor : GatherVisitorBase

9
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/ICodeIssueProvider.cs

@ -28,8 +28,17 @@ using System.Collections.Generic; @@ -28,8 +28,17 @@ using System.Collections.Generic;
namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
/// <summary>
/// The code issue provider gets a list of all code issues in a compilation unit.
/// </summary>
public interface ICodeIssueProvider
{
/// <summary>
/// Gets all code issues inside a compilation unit.
/// </summary>
/// <param name='context'>
/// The refactoring context of the issues to get.
/// </param>
IEnumerable<CodeIssue> GetIssues (BaseRefactoringContext context);
}
}

2
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/RefactoringContext.cs

@ -47,7 +47,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -47,7 +47,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
public virtual AstType CreateShortType (IType fullType)
{
var csResolver = resolver.GetResolverStateBefore(GetNode());
var csResolver = Resolver.GetResolverStateBefore(GetNode());
var builder = new TypeSystemAstBuilder(csResolver);
return builder.ConvertType(fullType);
}

1
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/Script.cs

@ -26,7 +26,6 @@ @@ -26,7 +26,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.TypeSystem;

1
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Resolver/ResolveAtLocation.cs

@ -85,6 +85,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -85,6 +85,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
CSharpAstResolver resolver = new CSharpAstResolver(compilation, cu, parsedFile);
resolver.ApplyNavigator(new NodeListResolveVisitorNavigator(node), cancellationToken);
ResolveResult rr = resolver.Resolve(node, cancellationToken);
if (rr is MethodGroupResolveResult && parentInvocation != null)
return resolver.Resolve(parentInvocation);

15
src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs

@ -3608,6 +3608,21 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3608,6 +3608,21 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{
return null;
}
ResolveResult IAstVisitor<ResolveResult>.VisitNewLine (NewLineNode comment)
{
return null;
}
ResolveResult IAstVisitor<ResolveResult>.VisitWhitespace(WhitespaceNode whitespaceNode)
{
return null;
}
ResolveResult IAstVisitor<ResolveResult>.VisitText(TextNode textNode)
{
return null;
}
ResolveResult IAstVisitor<ResolveResult>.VisitPreProcessorDirective (PreProcessorDirective preProcessorDirective)
{

4
src/Libraries/NRefactory/ICSharpCode.NRefactory.ConsistencyCheck/RoundtripTest.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
@ -69,7 +69,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck @@ -69,7 +69,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck
// 2. Output
StringWriter w = new StringWriter();
cu.AcceptVisitor(new CSharpOutputVisitor(w, new CSharpFormattingOptions()));
cu.AcceptVisitor(new CSharpOutputVisitor(w, FormattingOptionsFactory.CreateMono ()));
string generatedCode = w.ToString().TrimEnd();
// 3. Compare output with original (modulo whitespaces)

32
src/Libraries/NRefactory/ICSharpCode.NRefactory.ConsistencyCheck/Xml/IncrementalXmlParserTests.cs

@ -182,7 +182,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck @@ -182,7 +182,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck
CompareResults(obj1.Children, obj2.Children);
}
sealed class ValidationVisitor : IAXmlVisitor
sealed class ValidationVisitor : AXmlVisitor
{
readonly ITextSource textSource;
@ -191,19 +191,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck @@ -191,19 +191,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck
this.textSource = textSource;
}
public void Visit(IList<AXmlObject> objects)
{
for (int i = 0; i < objects.Count; i++) {
objects[i].AcceptVisitor(this);
}
}
public void VisitDocument(AXmlDocument document)
{
Visit(document.Children);
}
public void VisitTag(AXmlTag tag)
public override void VisitTag(AXmlTag tag)
{
if (textSource.GetText(tag.StartOffset, tag.OpeningBracket.Length) != tag.OpeningBracket)
throw new InvalidOperationException();
@ -211,24 +199,14 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck @@ -211,24 +199,14 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck
throw new InvalidOperationException();
if (textSource.GetText(tag.EndOffset - tag.ClosingBracket.Length, tag.ClosingBracket.Length) != tag.ClosingBracket)
throw new InvalidOperationException();
Visit(tag.Children);
base.VisitTag(tag);
}
public void VisitAttribute(AXmlAttribute attribute)
public override void VisitAttribute(AXmlAttribute attribute)
{
if (textSource.GetText(attribute.NameSegment) != attribute.Name)
throw new InvalidOperationException();
Visit(attribute.Children);
}
public void VisitText(AXmlText text)
{
Visit(text.Children);
}
public void VisitElement(AXmlElement element)
{
Visit(element.Children);
base.VisitAttribute(attribute);
}
}
}

7
src/Libraries/NRefactory/ICSharpCode.NRefactory.GtkDemo/gtk-gui/ICSharpCode.NRefactory.GtkDemo.MainWindow.cs

@ -5,12 +5,19 @@ namespace ICSharpCode.NRefactory.GtkDemo @@ -5,12 +5,19 @@ namespace ICSharpCode.NRefactory.GtkDemo
public partial class MainWindow
{
private global::Gtk.VBox vbox1;
private global::Gtk.ScrolledWindow scrolledwindow1;
private global::Gtk.TextView textview1;
private global::Gtk.HBox hbox1;
private global::Gtk.Button buttonParse;
private global::Gtk.Button buttonGenerate;
private global::Gtk.ScrolledWindow GtkScrolledWindow1;
private global::Gtk.TreeView treeviewNodes;
protected virtual void Build ()

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save