Browse Source

Squashed 'NRefactory/' changes from 36c9cae..858d4cc

858d4cc Fixed NullReferenceException in ControlFlow.NodeCreationVisitor.VisitSwitchStatement.
f70a726 Fixed resolving "-2147483648".
dd59e41 Add missing mscorlib reference
f1a1ab3 Added ResolverTest to consistency check and fixed some crashing bugs in the resolver.
3e8eb1e Add NRefactory.ConsistencyCheck with round-tripping test. Added parser unit tests for bugs discovered by the round-tripping test.
93a5c13 FindReferences: add support for searching in a different compilation than the entity is defined in.
119bc9b Fix formatting tests on Windows with git autocrlf enabled.
37795e4 Fixed parsing of some statements, improved "foreach" context in code completion.
6b7acf5 Added foreach statement variable declaration test.
3d551ed Fixed parsing of some incomplete statements.
8007d25 Fix CSharpOutputVisitorTests.AssignmentInCollectionInitializer. Ignore some failing parser unit tests.
38b35b7 Fixed formatting unit tests on windows.
df4805f Fixed compiler warnings.
94bad6c Fixed "InactiveIf" unit test.
41f4589 Fixed unit test.
3e9a85d Fixed complex generic class unit test.
77a7581 Fixed constraints parsing #2.
8124aeb Fixed some more cases of "new" completion.
fa8e9a2 Fixed bug in "new" completion.
b84c06e Make CSharpResolver immutable.
92c8bd6 Fix NullReferenceException in DefaultResolvedField.ConstantValue when the field is not a constant.
1464b5d For IAssembly.GetTypeDefinition, treat ns==null the same as ns==string.Empty.
3b48632 Fixed bug in constraints parsing.
a781604 Corrected parameter index.
e90bf1c fixed "Bug 2072 - Duplicate entries in the code completion list".
fa5ec27 Resolve object create expression, if the parent is one. That causes a jump/tooltip for the constructor rather than the class on a object create expression.
831c059 Added unit test for reported md bug.
4bf1ddb Updated Gtk demo.
d7d9a55 Added mono compiler bug workaround.
48b6968 Updated mcs sources.
63367b9 Fixed some keyword cc tests.
0e92f47 Prevented a key already exists exception (but it's not a real fix for the problem).
d5880aa Fixed possible null reference exception.
27f18d7 Fixed possible null reference exception.
ae54fd5 Added GetTypeResolveContext implementation.
9606b56 Added GetTypeResolveContext to IParsedFile.
b1bfe5c Added full name constructor to defaultunresolvedTypeDefinition.

git-subtree-dir: NRefactory
git-subtree-split: 858d4cc673d3029460f6a009a3fb268884304c7f
pull/314/merge
Daniel Grunwald 14 years ago
parent
commit
8f45b7e9cf
  1. 2
      ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs
  2. 31
      ICSharpCode.NRefactory.CSharp/Ast/Expressions/ErrorExpression.cs
  3. 9
      ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/Constraint.cs
  4. 28
      ICSharpCode.NRefactory.CSharp/Ast/SimpleType.cs
  5. 13
      ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs
  6. 134
      ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs
  7. 51
      ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs
  8. 4
      ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs
  9. 2
      ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs
  10. 32
      ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs
  11. 2
      ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs
  12. 1
      ICSharpCode.NRefactory.CSharp/OutputVisitor/IOutputFormatter.cs
  13. 121
      ICSharpCode.NRefactory.CSharp/OutputVisitor/TextWriterOutputFormatter.cs
  14. 21
      ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs
  15. 18
      ICSharpCode.NRefactory.CSharp/Parser/mcs/assembly.cs
  16. 6971
      ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs
  17. 54
      ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.jay
  18. 24
      ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs
  19. 3
      ICSharpCode.NRefactory.CSharp/Parser/mcs/driver.cs
  20. 6
      ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs
  21. 25
      ICSharpCode.NRefactory.CSharp/Parser/mcs/generic.cs
  22. 3
      ICSharpCode.NRefactory.CSharp/Parser/mcs/location.cs
  23. 74
      ICSharpCode.NRefactory.CSharp/Parser/mcs/statement.cs
  24. 24
      ICSharpCode.NRefactory.CSharp/Parser/mcs/typespec.cs
  25. 28
      ICSharpCode.NRefactory.CSharp/Parser/mcs/visit.cs
  26. 2
      ICSharpCode.NRefactory.CSharp/Refactoring/TextReplaceAction.cs
  27. 2
      ICSharpCode.NRefactory.CSharp/Refactoring/TypeSystemAstBuilder.cs
  28. 2
      ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs
  29. 14
      ICSharpCode.NRefactory.CSharp/Resolver/CSharpOperators.cs
  30. 193
      ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs
  31. 5
      ICSharpCode.NRefactory.CSharp/Resolver/FindReferenceSearchScope.cs
  32. 378
      ICSharpCode.NRefactory.CSharp/Resolver/FindReferences.cs
  33. 21
      ICSharpCode.NRefactory.CSharp/Resolver/Log.cs
  34. 4
      ICSharpCode.NRefactory.CSharp/Resolver/ResolveAtLocation.cs
  35. 202
      ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs
  36. 5
      ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpAssembly.cs
  37. 25
      ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpParsedFile.cs
  38. 10
      ICSharpCode.NRefactory.CSharp/TypeSystem/ConstantValues.cs
  39. 4
      ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs
  40. 3
      ICSharpCode.NRefactory.ConsistencyCheck/.gitignore
  41. 176
      ICSharpCode.NRefactory.ConsistencyCheck/CSharpProject.cs
  42. 72
      ICSharpCode.NRefactory.ConsistencyCheck/ICSharpCode.NRefactory.ConsistencyCheck.csproj
  43. 91
      ICSharpCode.NRefactory.ConsistencyCheck/Program.cs
  44. 31
      ICSharpCode.NRefactory.ConsistencyCheck/Properties/AssemblyInfo.cs
  45. 8
      ICSharpCode.NRefactory.ConsistencyCheck/Readme.txt
  46. 83
      ICSharpCode.NRefactory.ConsistencyCheck/ResolverTest.cs
  47. 108
      ICSharpCode.NRefactory.ConsistencyCheck/RoundtripTest.cs
  48. 67
      ICSharpCode.NRefactory.ConsistencyCheck/Solution.cs
  49. 6
      ICSharpCode.NRefactory.ConsistencyCheck/app.config
  50. 2
      ICSharpCode.NRefactory.Demo/CSDemo.cs
  51. 51
      ICSharpCode.NRefactory.GtkDemo/MainWindow.cs
  52. 146
      ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/CodeCompletionBugTests.cs
  53. 82
      ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/KeywordTests.cs
  54. 27
      ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/ParameterCompletionTests.cs
  55. 33
      ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/VariableDeclarationStatementTests.cs
  56. 4
      ICSharpCode.NRefactory.Tests/CSharp/CodeDomConvertVisitorTests.cs
  57. 2
      ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ArrayCreateExpressionTests.cs
  58. 4
      ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/CastExpressionTests.cs
  59. 8
      ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/InvocationExpressionTests.cs
  60. 4
      ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/MemberReferenceExpressionTests.cs
  61. 24
      ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/PrimitiveExpressionTests.cs
  62. 14
      ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/TypeReferenceExpressionTests.cs
  63. 34
      ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/AttributeSectionTests.cs
  64. 2
      ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/DelegateDeclarationTests.cs
  65. 59
      ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/PreprocessorDirectiveTests.cs
  66. 30
      ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/TypeDeclarationTests.cs
  67. 2
      ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseSelfTests.cs
  68. 4
      ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/VariableDeclarationStatementTests.cs
  69. 6
      ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/MethodDeclarationTests.cs
  70. 7
      ICSharpCode.NRefactory.Tests/CSharp/Refactoring/TypeSystemAstBuilderTests.cs
  71. 6
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/BinaryOperatorTests.cs
  72. 9
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/CastTests.cs
  73. 73
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs
  74. 24
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/UnaryOperatorTests.cs
  75. 2
      ICSharpCode.NRefactory.Tests/FormattingTests/TestFormattingBugs.cs
  76. 24
      ICSharpCode.NRefactory.Tests/FormattingTests/TestSpacingVisitor.cs
  77. 14
      ICSharpCode.NRefactory.Tests/FormattingTests/TextEditorTestAdapter.cs
  78. 1
      ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs
  79. 2
      ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs
  80. 5
      ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs
  81. 36
      ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs
  82. 5
      ICSharpCode.NRefactory/TypeSystem/IParsedFile.cs
  83. 24
      ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractResolvedTypeParameter.cs
  84. 4
      ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractUnresolvedMember.cs
  85. 6
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedField.cs
  86. 76
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs
  87. 2
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedAssembly.cs
  88. 2
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedMethod.cs
  89. 18
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedTypeDefinition.cs
  90. 4
      ICSharpCode.NRefactory/TypeSystem/Implementation/FullNameAndTypeParameterCount.cs
  91. 12
      NRefactory.sln

2
ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs

@ -436,7 +436,7 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis
} }
} }
} }
if (constant.IsCompileTimeConstant && sectionMatchedByConstant == null) if (constant != null && constant.IsCompileTimeConstant && sectionMatchedByConstant == null)
sectionMatchedByConstant = defaultSection; sectionMatchedByConstant = defaultSection;
int gotoCaseOrDefaultInOuterScope = gotoCaseOrDefault.Count; int gotoCaseOrDefaultInOuterScope = gotoCaseOrDefault.Count;

31
ICSharpCode.NRefactory.CSharp/Ast/Expressions/ErrorExpression.cs

@ -27,16 +27,43 @@ using System;
namespace ICSharpCode.NRefactory.CSharp namespace ICSharpCode.NRefactory.CSharp
{ {
public class ErrorExpression : EmptyExpression public class ErrorExpression : Expression
{ {
TextLocation location;
public override TextLocation StartLocation {
get {
return location;
}
}
public override TextLocation EndLocation {
get {
return location;
}
}
public ErrorExpression () public ErrorExpression ()
{ {
} }
public ErrorExpression (TextLocation location) : base (location) public ErrorExpression (TextLocation location)
{ {
this.location = location;
} }
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data = default(T))
{
// nothing
return default(S);
}
protected internal override bool DoMatch (AstNode other, PatternMatching.Match match)
{
var o = other as ErrorExpression;
return o != null;
}
} }
} }

9
ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/Constraint.cs

@ -38,6 +38,7 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
public readonly static Role<CSharpTokenNode> ColonRole = TypeDeclaration.ColonRole; public readonly static Role<CSharpTokenNode> ColonRole = TypeDeclaration.ColonRole;
public readonly static Role<AstType> BaseTypeRole = TypeDeclaration.BaseTypeRole; public readonly static Role<AstType> BaseTypeRole = TypeDeclaration.BaseTypeRole;
public readonly static Role<SimpleType> TypeParameterRole = new Role<SimpleType> ("TypeParameter", SimpleType.Null);
public override NodeType NodeType { public override NodeType NodeType {
get { get {
@ -45,12 +46,12 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
public string TypeParameter { public SimpleType TypeParameter {
get { get {
return GetChildByRole (Roles.Identifier).Name; return GetChildByRole (TypeParameterRole);
} }
set { set {
SetChildByRole(Roles.Identifier, Identifier.Create (value, TextLocation.Empty)); SetChildByRole(TypeParameterRole, value);
} }
} }
@ -66,7 +67,7 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{ {
Constraint o = other as Constraint; Constraint o = other as Constraint;
return o != null && MatchString(this.TypeParameter, o.TypeParameter) && this.BaseTypes.DoMatch(o.BaseTypes, match); return o != null && this.TypeParameter.DoMatch (o.TypeParameter, match) && this.BaseTypes.DoMatch(o.BaseTypes, match);
} }
} }
} }

28
ICSharpCode.NRefactory.CSharp/Ast/SimpleType.cs

@ -33,6 +33,29 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
public class SimpleType : AstType public class SimpleType : AstType
{ {
#region Null
public new static readonly SimpleType Null = new NullSimpleType ();
sealed class NullSimpleType : SimpleType
{
public override bool IsNull {
get {
return true;
}
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data = default(T))
{
return default (S);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
}
#endregion
public SimpleType() public SimpleType()
{ {
} }
@ -42,6 +65,11 @@ namespace ICSharpCode.NRefactory.CSharp
this.Identifier = identifier; this.Identifier = identifier;
} }
public SimpleType (Identifier identifier)
{
this.IdentifierToken = identifier;
}
public SimpleType(string identifier, TextLocation location) public SimpleType(string identifier, TextLocation location)
{ {
SetChildByRole (Roles.Identifier, CSharp.Identifier.Create (identifier, location)); SetChildByRole (Roles.Identifier, CSharp.Identifier.Create (identifier, location));

13
ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs

@ -139,7 +139,18 @@ namespace ICSharpCode.NRefactory.CSharp
public IProjectContent UpdateProjectContent(IEnumerable<IParsedFile> oldFiles, IEnumerable<IParsedFile> newFiles) public IProjectContent UpdateProjectContent(IEnumerable<IParsedFile> oldFiles, IEnumerable<IParsedFile> newFiles)
{ {
throw new NotImplementedException(); CSharpProjectContent pc = new CSharpProjectContent(this);
if (oldFiles != null) {
foreach (var oldFile in oldFiles) {
pc.parsedFiles.Remove(oldFile.FileName);
}
}
if (newFiles != null) {
foreach (var newFile in newFiles) {
pc.parsedFiles.Add(newFile.FileName, newFile);
}
}
return pc;
} }
IAssembly IAssemblyReference.Resolve(ITypeResolveContext context) IAssembly IAssemblyReference.Resolve(ITypeResolveContext context)

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

@ -78,8 +78,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
offset--; offset--;
if (offset > 0) { if (offset > 0) {
var nonWsResult = MagicKeyCompletion (document.GetCharAt (offset), controlSpace); var nonWsResult = MagicKeyCompletion (document.GetCharAt (offset), controlSpace);
if (nonWsResult != null) if (nonWsResult != null) {
result = result.Concat (nonWsResult); var text = new HashSet<string> (result.Select (r => r.CompletionText));
result = result.Concat (nonWsResult.Where (r => !text.Contains (r.CompletionText)));
}
} }
} }
@ -243,9 +245,8 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
int tokenIndex = offset; int tokenIndex = offset;
string token = GetPreviousToken (ref tokenIndex, false); string token = GetPreviousToken (ref tokenIndex, false);
// check propose name, for context <variable name> <ctrl+space> (but only in control space context) // check propose name, for context <variable name> <ctrl+space> (but only in control space context)
IType isAsType = null; //IType isAsType = null;
var isAsExpression = GetExpressionAt (offset); var isAsExpression = GetExpressionAt (offset);
if (controlSpace && isAsExpression != null && isAsExpression.Item2 is VariableDeclarationStatement && token != "new") { if (controlSpace && isAsExpression != null && isAsExpression.Item2 is VariableDeclarationStatement && token != "new") {
var parent = isAsExpression.Item2 as VariableDeclarationStatement; var parent = isAsExpression.Item2 as VariableDeclarationStatement;
@ -431,12 +432,12 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
// Do not pop up completion on identifier identifier (should be handled by keyword completion). // Do not pop up completion on identifier identifier (should be handled by keyword completion).
tokenIndex = offset - 1; tokenIndex = offset - 1;
token = GetPreviousToken (ref tokenIndex, false); token = GetPreviousToken (ref tokenIndex, false);
if (identifierStart == null && !string.IsNullOrEmpty (token) && !(IsInsideComment (tokenIndex) || IsInsideString (tokenIndex))) { int prevTokenIndex = tokenIndex;
var prevToken2 = GetPreviousToken (ref prevTokenIndex, false);
if (identifierStart == null && !string.IsNullOrEmpty (token) && !(IsInsideComment (tokenIndex) || IsInsideString (tokenIndex)) && (prevToken2 == ";" || prevToken2 == "{" || prevToken2 == "}")) {
char last = token [token.Length - 1]; char last = token [token.Length - 1];
if (char.IsLetterOrDigit (last) || last == '_' || token == ">") { if (char.IsLetterOrDigit (last) || last == '_' || token == ">") {
return HandleKeywordCompletion (tokenIndex, token); return HandleKeywordCompletion (tokenIndex, token);
//return controlSpace ? DefaultControlSpaceItems () : null;
} }
} }
if (identifierStart == null) if (identifierStart == null)
@ -444,6 +445,24 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
CSharpResolver csResolver; CSharpResolver csResolver;
AstNode n = identifierStart.Item2; AstNode n = identifierStart.Item2;
// Handle foreach (type name _
if (n is IdentifierExpression) {
var prev = n.GetPrevNode () as ForeachStatement;
if (prev != null && prev.InExpression.IsNull) {
if (controlSpace) {
contextList.AddCustom ("in");
return contextList.Result;
}
return null;
}
}
if (n is Identifier && n.Parent is ForeachStatement) {
if (controlSpace)
return DefaultControlSpaceItems ();
return null;
}
if (n is ArrayInitializerExpression) { if (n is ArrayInitializerExpression) {
var initalizerResult = ResolveExpression (identifierStart.Item1, n.Parent, identifierStart.Item3); var initalizerResult = ResolveExpression (identifierStart.Item1, n.Parent, identifierStart.Item3);
@ -578,7 +597,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
if (cu == null) if (cu == null)
return null; return null;
var member = cu.GetNodeAt<EnumMemberDeclaration> (location); var member = cu.GetNodeAt<EnumMemberDeclaration> (location);
Console.WriteLine ("member:" + cu.GetNodeAt (location) +"/" + location);
Print (cu); Print (cu);
if (member != null && member.NameToken.EndLocation < location) if (member != null && member.NameToken.EndLocation < location)
return DefaultControlSpaceItems (); return DefaultControlSpaceItems ();
@ -622,6 +640,8 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
IEnumerable<ICompletionData> DefaultControlSpaceItems () IEnumerable<ICompletionData> DefaultControlSpaceItems ()
{ {
var wrapper = new CompletionDataWrapper (this); var wrapper = new CompletionDataWrapper (this);
if (offset >= document.TextLength)
offset = document.TextLength - 1;
while (offset > 1 && char.IsWhiteSpace (document.GetCharAt (offset))) { while (offset > 1 && char.IsWhiteSpace (document.GetCharAt (offset))) {
offset--; offset--;
} }
@ -636,6 +656,18 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
node = Unit.GetNodeAt (location); node = Unit.GetNodeAt (location);
rr = ResolveExpression (CSharpParsedFile, node, Unit); rr = ResolveExpression (CSharpParsedFile, node, Unit);
} }
if (node is Identifier && node.Parent is ForeachStatement) {
var foreachStmt = (ForeachStatement)node.Parent;
foreach (var possibleName in GenerateNameProposals (foreachStmt.VariableType)) {
if (possibleName.Length > 0)
wrapper.Result.Add (factory.CreateLiteralCompletionData (possibleName.ToString ()));
}
AutoSelect = false;
AutoCompleteEmptyMatch = false;
return wrapper.Result;
}
AddContextCompletion (wrapper, rr != null && (node is Expression) ? rr.Item2 : GetState (), node); AddContextCompletion (wrapper, rr != null && (node is Expression) ? rr.Item2 : GetState (), node);
@ -674,16 +706,16 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
AddTypesAndNamespaces (wrapper, state, node, typePred); AddTypesAndNamespaces (wrapper, state, node, typePred);
wrapper.Result.Add (factory.CreateLiteralCompletionData ("global")); wrapper.Result.Add (factory.CreateLiteralCompletionData ("global"));
if (state.CurrentMember != null) { if (currentMember != null) {
AddKeywords (wrapper, statementStartKeywords); AddKeywords (wrapper, statementStartKeywords);
AddKeywords (wrapper, expressionLevelKeywords); AddKeywords (wrapper, expressionLevelKeywords);
} else if (state.CurrentTypeDefinition != null) { } else if (currentType != null) {
AddKeywords (wrapper, typeLevelKeywords); AddKeywords (wrapper, typeLevelKeywords);
} else { } else {
AddKeywords (wrapper, globalLevelKeywords); AddKeywords (wrapper, globalLevelKeywords);
} }
var prop = currentMember as IUnresolvedProperty; var prop = currentMember as IUnresolvedProperty;
if (prop != null && prop.Setter.Region.IsInside (location)) if (prop != null && prop.Setter != null && prop.Setter.Region.IsInside (location))
wrapper.AddCustom ("value"); wrapper.AddCustom ("value");
if (currentMember is IUnresolvedEvent) if (currentMember is IUnresolvedEvent)
wrapper.AddCustom ("value"); wrapper.AddCustom ("value");
@ -977,6 +1009,51 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
if (newParentNode is VariableInitializer) if (newParentNode is VariableInitializer)
newParentNode = newParentNode.Parent; newParentNode = newParentNode.Parent;
} }
if (newParentNode is InvocationExpression) {
var invoke = (InvocationExpression)newParentNode;
var resolved = ResolveExpression (expressionOrVariableDeclaration.Item1, invoke, expressionOrVariableDeclaration.Item3);
if (resolved != null) {
var mgr = resolved.Item1 as CSharpInvocationResolveResult;
if (mgr != null) {
int i1 = 0;
foreach (var a in invoke.Arguments) {
if (a == expressionOrVariableDeclaration.Item2) {
if (mgr.Member.Parameters.Count > i1)
hintType = mgr.Member.Parameters[i1].Type;
break;
}
i1++;
}
}
}
}
if (newParentNode is ObjectCreateExpression) {
var invoke = (ObjectCreateExpression)newParentNode;
var resolved = ResolveExpression (expressionOrVariableDeclaration.Item1, invoke, expressionOrVariableDeclaration.Item3);
if (resolved != null) {
var mgr = resolved.Item1 as CSharpInvocationResolveResult;
if (mgr != null) {
int i1 = 0;
foreach (var a in invoke.Arguments) {
if (a == expressionOrVariableDeclaration.Item2) {
if (mgr.Member.Parameters.Count > i1)
hintType = mgr.Member.Parameters[i1].Type;
break;
}
i1++;
}
}
}
}
if (newParentNode is AssignmentExpression) {
var assign = (AssignmentExpression)newParentNode;
var resolved = ResolveExpression (expressionOrVariableDeclaration.Item1, assign.Left, expressionOrVariableDeclaration.Item3);
if (resolved != null) {
hintType = resolved.Item1.Type;
}
}
if (newParentNode is VariableDeclarationStatement) { if (newParentNode is VariableDeclarationStatement) {
var varDecl = (VariableDeclarationStatement)newParentNode; var varDecl = (VariableDeclarationStatement)newParentNode;
@ -1096,7 +1173,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
if (hintType != null) { if (hintType != null) {
if (hintType.Kind != TypeKind.Unknown) { if (hintType.Kind != TypeKind.Unknown) {
Console.WriteLine ("hint!");
var lookup = new MemberLookup (ctx.CurrentTypeDefinition, Compilation.MainAssembly); var lookup = new MemberLookup (ctx.CurrentTypeDefinition, Compilation.MainAssembly);
pred = t => { pred = t => {
// check if type is in inheritance tree. // check if type is in inheritance tree.
@ -1106,7 +1182,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
// check for valid constructors // check for valid constructors
if (t.GetConstructors ().Count () == 0) if (t.GetConstructors ().Count () == 0)
return true; return true;
Console.WriteLine ("check!");
bool isProtectedAllowed = currentType != null ? currentType.Resolve (ctx).GetDefinition ().IsDerivedFrom (t.GetDefinition ()) : false; bool isProtectedAllowed = currentType != null ? currentType.Resolve (ctx).GetDefinition ().IsDerivedFrom (t.GetDefinition ()) : false;
return t.GetConstructors ().Any (m => lookup.IsAccessible (m, isProtectedAllowed)); return t.GetConstructors ().Any (m => lookup.IsAccessible (m, isProtectedAllowed));
}; };
@ -1556,8 +1631,8 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
includeStaticMembers = mrr.Member.Name == mrr.Type.Name; includeStaticMembers = mrr.Member.Name == mrr.Type.Name;
} }
Console.WriteLine ("type:" + type +"/"+type.GetType ()); // Console.WriteLine ("type:" + type +"/"+type.GetType ());
Console.WriteLine ("IS PROT ALLOWED:" + isProtectedAllowed); // Console.WriteLine ("IS PROT ALLOWED:" + isProtectedAllowed);
// Console.WriteLine (resolveResult); // Console.WriteLine (resolveResult);
// Console.WriteLine (currentMember != null ? currentMember.IsStatic : "currentMember == null"); // Console.WriteLine (currentMember != null ? currentMember.IsStatic : "currentMember == null");
@ -1785,6 +1860,15 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
} }
} }
if (expr == null) {
var forStmt = tmpUnit.GetNodeAt<ForeachStatement> (location.Line, location.Column - 3);
if (forStmt != null && forStmt.EmbeddedStatement.IsNull) {
forStmt.VariableNameToken = Identifier.Create ("stub");
expr = forStmt.VariableNameToken;
baseUnit = tmpUnit;
}
}
if (expr == null) { if (expr == null) {
expr = tmpUnit.GetNodeAt<VariableInitializer> (location.Line, location.Column - 1); expr = tmpUnit.GetNodeAt<VariableInitializer> (location.Line, location.Column - 1);
@ -1841,14 +1925,27 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
var sb = new StringBuilder (text); var sb = new StringBuilder (text);
sb.Append ("a ();"); sb.Append ("a ();");
AppendMissingClosingBrackets (sb, text, false); AppendMissingClosingBrackets (sb, text, false);
var stream = new System.IO.StringReader (sb.ToString ()); var stream = new System.IO.StringReader (sb.ToString ());
var completionUnit = parser.Parse (stream, CSharpParsedFile.FileName, 0); var completionUnit = parser.Parse (stream, CSharpParsedFile.FileName, 0);
stream.Close (); stream.Close ();
var loc = document.GetLocation (offset); var loc = document.GetLocation (offset);
var expr = completionUnit.GetNodeAt (loc, n => n is Expression); var expr = completionUnit.GetNodeAt (loc, n => n is Expression);
if (expr == null) if (expr == null) {
return null; // try without ";"
sb = new StringBuilder (text);
sb.Append ("a ()");
AppendMissingClosingBrackets (sb, text, false);
stream = new System.IO.StringReader (sb.ToString ());
completionUnit = parser.Parse (stream, CSharpParsedFile.FileName, 0);
stream.Close ();
loc = document.GetLocation (offset);
expr = completionUnit.GetNodeAt (loc, n => n is Expression);
if (expr == null)
return null;
}
var tsvisitor = new TypeSystemConvertVisitor (CSharpParsedFile.FileName); var tsvisitor = new TypeSystemConvertVisitor (CSharpParsedFile.FileName);
completionUnit.AcceptVisitor (tsvisitor, null); completionUnit.AcceptVisitor (tsvisitor, null);
@ -2082,7 +2179,8 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
"true", "false", "typeof", "checked", "unchecked", "from", "break", "checked", "true", "false", "typeof", "checked", "unchecked", "from", "break", "checked",
"unchecked", "const", "continue", "do", "finally", "fixed", "for", "foreach", "unchecked", "const", "continue", "do", "finally", "fixed", "for", "foreach",
"goto", "if", "lock", "return", "stackalloc", "switch", "throw", "try", "unsafe", "goto", "if", "lock", "return", "stackalloc", "switch", "throw", "try", "unsafe",
"using", "while", "yield", "dynamic", "var" }; "using", "while", "yield", "dynamic", "var", "dynamic"
};
static string[] globalLevelKeywords = new string [] { static string[] globalLevelKeywords = new string [] {
"namespace", "using", "extern", "public", "internal", "namespace", "using", "extern", "public", "internal",
"class", "interface", "struct", "enum", "delegate", "class", "interface", "struct", "enum", "delegate",

51
ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs

@ -402,60 +402,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
} else { } else {
return null; return null;
} }
// Print (baseUnit);
/* var member = Unit.GetNodeAt<AttributedNode> (memberLocation);
var member2 = baseUnit.GetNodeAt<AttributedNode> (memberLocation);
member2.Remove ();
member.ReplaceWith (member2);
var tsvisitor = new TypeSystemConvertVisitor (ProjectContent, CSharpParsedFile.FileName);
baseUnit.AcceptVisitor (tsvisitor, null);*/
return Tuple.Create (CSharpParsedFile, (AstNode)expr, baseUnit);
/*
///////
if (currentMember == null && currentType == null)
return null;
CSharpParser parser = new CSharpParser ();
int startOffset;
if (currentMember != null) {
startOffset = document.Editor.LocationToOffset (currentMember.Region.BeginLine, currentMember.Region.BeginColumn);
} else {
startOffset = document.Editor.LocationToOffset (currentType.Region.BeginLine, currentType.Region.BeginColumn);
}
string memberText = Document.Editor.GetTextBetween (startOffset, Document.Editor.Caret.Offset - 1);
var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin;
StringBuilder wrapper = new StringBuilder ();
wrapper.Append ("class Stub {");
wrapper.AppendLine ();
wrapper.Append (memberText);
if (afterBracket) {
wrapper.Append ("();");
} else {
wrapper.Append ("x);");
}
wrapper.Append (" SomeCall (); } } }");
var stream = new System.IO.StringReader (wrapper.ToString ());
var baseUnit = parser.Parse (stream, memberLocation.Line - 2);
stream.Close ();
var expr = baseUnit.GetNodeAt<Expression> (document.Editor.Caret.Line, document.Editor.Caret.Column);
if (expr is InvocationExpression) {
expr = ((InvocationExpression)expr).Target;
}
if (expr == null)
return null;
var member = Unit.GetNodeAt<AttributedNode> (memberLocation); var member = Unit.GetNodeAt<AttributedNode> (memberLocation);
var member2 = baseUnit.GetNodeAt<AttributedNode> (memberLocation); var member2 = baseUnit.GetNodeAt<AttributedNode> (memberLocation);
member2.Remove (); member2.Remove ();
member.ReplaceWith (member2); member.ReplaceWith (member2);
var tsvisitor = new TypeSystemConvertVisitor (CSharpParsedFile.FileName);
var tsvisitor = new TypeSystemConvertVisitor (ProjectContext, Document.FileName);
Unit.AcceptVisitor (tsvisitor, null); Unit.AcceptVisitor (tsvisitor, null);
return Tuple.Create (tsvisitor.ParsedFile, expr, Unit);*/ return Tuple.Create (tsvisitor.ParsedFile, (AstNode)expr, Unit);
} }
protected Tuple<ResolveResult, CSharpResolver> ResolveExpression (CSharpParsedFile file, AstNode expr, CompilationUnit unit) protected Tuple<ResolveResult, CSharpResolver> ResolveExpression (CSharpParsedFile file, AstNode expr, CompilationUnit unit)

4
ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs

@ -194,6 +194,8 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
{ {
SetOffset (triggerOffset); SetOffset (triggerOffset);
var text = GetMemberTextToCaret (); var text = GetMemberTextToCaret ();
if (text.Item1.EndsWith ("("))
return 0;
var parameter = new Stack<int> (); var parameter = new Stack<int> ();
bool inSingleComment = false, inString = false, inVerbatimString = false, inChar = false, inMultiLineComment = false; bool inSingleComment = false, inString = false, inVerbatimString = false, inChar = false, inMultiLineComment = false;
@ -278,8 +280,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
} }
if (parameter.Count == 0) if (parameter.Count == 0)
return -1; return -1;
if (text.Item1.EndsWith ("("))
return 1;
return parameter.Pop () + 1; return parameter.Pop () + 1;
} }

2
ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs

@ -995,7 +995,7 @@ namespace ICSharpCode.NRefactory.CSharp
return; return;
} }
} }
//Console.WriteLine ("offset={0}, removedChars={1}, insertedText={2}", offset, removedChars, insertedText == null ? "<null>" : insertedText.Replace ("\n", "\\n").Replace ("\t", "\\t").Replace (" ", ".")); //Console.WriteLine ("offset={0}, removedChars={1}, insertedText={2}", offset, removedChars, insertedText == null ? "<null>" : insertedText.Replace ("\n", "\\n").Replace ("\r", "\\r").Replace ("\t", "\\t").Replace (" ", "."));
//Console.WriteLine (Environment.StackTrace); //Console.WriteLine (Environment.StackTrace);
changes.Add (factory.CreateTextReplaceAction (offset, removedChars, insertedText)); changes.Add (factory.CreateTextReplaceAction (offset, removedChars, insertedText));

32
ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs

@ -604,8 +604,14 @@ namespace ICSharpCode.NRefactory.CSharp
public object VisitArrayInitializerExpression (ArrayInitializerExpression arrayInitializerExpression, object data) public object VisitArrayInitializerExpression (ArrayInitializerExpression arrayInitializerExpression, object data)
{ {
StartNode (arrayInitializerExpression); StartNode (arrayInitializerExpression);
// "new List<int> { { 1 } }" and "new List<int> { 1 }" are the same semantically.
// We also use the same AST for both: we always use two nested ArrayInitializerExpressions
// for collection initializers, even if the user did not write nested brackets.
// The output visitor will output nested braces only if they are necessary,
// or if the braces tokens exist in the AST.
bool bracesAreOptional = arrayInitializerExpression.Elements.Count == 1 bool bracesAreOptional = arrayInitializerExpression.Elements.Count == 1
&& IsObjectInitializer(arrayInitializerExpression.Parent); && IsObjectOrCollectionInitializer(arrayInitializerExpression.Parent)
&& !CanBeConfusedWithObjectInitializer(arrayInitializerExpression.Elements.Single());
if (bracesAreOptional && arrayInitializerExpression.LBraceToken.IsNull) { if (bracesAreOptional && arrayInitializerExpression.LBraceToken.IsNull) {
arrayInitializerExpression.Elements.Single().AcceptVisitor(this, data); arrayInitializerExpression.Elements.Single().AcceptVisitor(this, data);
} else { } else {
@ -614,7 +620,15 @@ namespace ICSharpCode.NRefactory.CSharp
return EndNode (arrayInitializerExpression); return EndNode (arrayInitializerExpression);
} }
bool IsObjectInitializer(AstNode node) bool CanBeConfusedWithObjectInitializer(Expression expr)
{
// "int a; new List<int> { a = 1 };" is an object initalizers and invalid, but
// "int a; new List<int> { { a = 1 } };" is a valid collection initializer.
AssignmentExpression ae = expr as AssignmentExpression;
return ae != null && ae.Operator == AssignmentOperatorType.Assign;
}
bool IsObjectOrCollectionInitializer(AstNode node)
{ {
if (!(node is ArrayInitializerExpression)) if (!(node is ArrayInitializerExpression))
return false; return false;
@ -2315,18 +2329,8 @@ namespace ICSharpCode.NRefactory.CSharp
public object VisitPreProcessorDirective (PreProcessorDirective preProcessorDirective, object data) public object VisitPreProcessorDirective (PreProcessorDirective preProcessorDirective, object data)
{ {
if (lastWritten == LastWritten.Division) {
// When there's a comment starting after a division operator
// "1.0 / /*comment*/a", then we need to insert a space in front of the comment.
formatter.Space ();
}
formatter.StartNode (preProcessorDirective); formatter.StartNode (preProcessorDirective);
formatter.WriteToken ("#" + preProcessorDirective.Type.ToString ().ToLower ()); formatter.WritePreProcessorDirective(preProcessorDirective.Type, preProcessorDirective.Argument);
if (!string.IsNullOrEmpty(preProcessorDirective.Argument)) {
formatter.Space();
formatter.WriteToken(preProcessorDirective.Argument);
}
formatter.NewLine();
formatter.EndNode (preProcessorDirective); formatter.EndNode (preProcessorDirective);
lastWritten = LastWritten.Whitespace; lastWritten = LastWritten.Whitespace;
return null; return null;
@ -2357,7 +2361,7 @@ namespace ICSharpCode.NRefactory.CSharp
StartNode (constraint); StartNode (constraint);
Space (); Space ();
WriteKeyword ("where"); WriteKeyword ("where");
WriteIdentifier (constraint.TypeParameter); WriteIdentifier (constraint.TypeParameter.Identifier);
Space (); Space ();
WriteToken (":", Constraint.ColonRole); WriteToken (":", Constraint.ColonRole);
Space (); Space ();

2
ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs

@ -1269,7 +1269,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeTypeParameter tp = new CodeTypeParameter(tpDecl.Name); CodeTypeParameter tp = new CodeTypeParameter(tpDecl.Name);
tp.CustomAttributes.AddRange(Convert(tpDecl.Attributes)); tp.CustomAttributes.AddRange(Convert(tpDecl.Attributes));
foreach (Constraint constraint in constraints) { foreach (Constraint constraint in constraints) {
if (constraint.TypeParameter == tp.Name) { if (constraint.TypeParameter.Identifier == tp.Name) {
foreach (AstType baseType in constraint.BaseTypes) { foreach (AstType baseType in constraint.BaseTypes) {
if (baseType is PrimitiveType && ((PrimitiveType)baseType).Keyword == "new") { if (baseType is PrimitiveType && ((PrimitiveType)baseType).Keyword == "new") {
tp.HasConstructorConstraint = true; tp.HasConstructorConstraint = true;

1
ICSharpCode.NRefactory.CSharp/OutputVisitor/IOutputFormatter.cs

@ -55,5 +55,6 @@ namespace ICSharpCode.NRefactory.CSharp
void NewLine(); void NewLine();
void WriteComment(CommentType commentType, string content); void WriteComment(CommentType commentType, string content);
void WritePreProcessorDirective(PreProcessorDirectiveType type, string argument);
} }
} }

121
ICSharpCode.NRefactory.CSharp/OutputVisitor/TextWriterOutputFormatter.cs

@ -77,39 +77,39 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
bool isAtStartOfLine = needsIndent; bool isAtStartOfLine = needsIndent;
switch (style) { switch (style) {
case BraceStyle.DoNotChange: case BraceStyle.DoNotChange:
case BraceStyle.EndOfLine: case BraceStyle.EndOfLine:
WriteIndentation(); WriteIndentation();
if (!isAtStartOfLine) if (!isAtStartOfLine)
textWriter.Write(' '); textWriter.Write(' ');
textWriter.Write('{'); textWriter.Write('{');
break; break;
case BraceStyle.EndOfLineWithoutSpace: case BraceStyle.EndOfLineWithoutSpace:
WriteIndentation(); WriteIndentation();
textWriter.Write('{'); textWriter.Write('{');
break; break;
case BraceStyle.NextLine: case BraceStyle.NextLine:
if (!isAtStartOfLine) if (!isAtStartOfLine)
NewLine();
WriteIndentation();
textWriter.Write('{');
break;
case BraceStyle.NextLineShifted:
NewLine ();
Indent();
WriteIndentation();
textWriter.Write('{');
NewLine(); NewLine();
WriteIndentation(); return;
textWriter.Write('{'); case BraceStyle.NextLineShifted2:
break; NewLine ();
Indent();
case BraceStyle.NextLineShifted: WriteIndentation();
NewLine (); textWriter.Write('{');
Indent(); break;
WriteIndentation(); default:
textWriter.Write('{'); throw new ArgumentOutOfRangeException ();
NewLine();
return;
case BraceStyle.NextLineShifted2:
NewLine ();
Indent();
WriteIndentation();
textWriter.Write('{');
break;
default:
throw new ArgumentOutOfRangeException ();
} }
Indent(); Indent();
NewLine(); NewLine();
@ -118,27 +118,27 @@ namespace ICSharpCode.NRefactory.CSharp
public void CloseBrace(BraceStyle style) public void CloseBrace(BraceStyle style)
{ {
switch (style) { switch (style) {
case BraceStyle.DoNotChange: case BraceStyle.DoNotChange:
case BraceStyle.EndOfLine: case BraceStyle.EndOfLine:
case BraceStyle.EndOfLineWithoutSpace: case BraceStyle.EndOfLineWithoutSpace:
case BraceStyle.NextLine: case BraceStyle.NextLine:
Unindent(); Unindent();
WriteIndentation(); WriteIndentation();
textWriter.Write('}'); textWriter.Write('}');
break; break;
case BraceStyle.NextLineShifted: case BraceStyle.NextLineShifted:
WriteIndentation(); WriteIndentation();
textWriter.Write('}'); textWriter.Write('}');
Unindent(); Unindent();
break; break;
case BraceStyle.NextLineShifted2: case BraceStyle.NextLineShifted2:
Unindent(); Unindent();
WriteIndentation(); WriteIndentation();
textWriter.Write('}'); textWriter.Write('}');
Unindent(); Unindent();
break; break;
default: default:
throw new ArgumentOutOfRangeException (); throw new ArgumentOutOfRangeException ();
} }
} }
@ -193,6 +193,21 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
public void WritePreProcessorDirective(PreProcessorDirectiveType type, string argument)
{
// pre-processor directive must start on its own line
if (!needsIndent)
NewLine();
WriteIndentation();
textWriter.Write('#');
textWriter.Write(type.ToString().ToLowerInvariant());
if (!string.IsNullOrEmpty(argument)) {
textWriter.Write(' ');
textWriter.Write(argument);
}
NewLine();
}
public virtual void StartNode(AstNode node) public virtual void StartNode(AstNode node)
{ {
} }

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

@ -1353,7 +1353,7 @@ namespace ICSharpCode.NRefactory.CSharp
if (location != null) if (location != null)
result.AddChild (new CSharpTokenNode (Convert (location[0]), 1), IfElseStatement.Roles.LPar); result.AddChild (new CSharpTokenNode (Convert (location[0]), 1), IfElseStatement.Roles.LPar);
result.AddChild ((Expression)ifStatement.Expr.Accept (this), IfElseStatement.Roles.Condition); result.AddChild ((Expression)ifStatement.Expr.Accept (this), IfElseStatement.Roles.Condition);
if (location != null) if (location != null && location.Count > 1)
result.AddChild (new CSharpTokenNode (Convert (location[1]), 1), IfElseStatement.Roles.RPar); result.AddChild (new CSharpTokenNode (Convert (location[1]), 1), IfElseStatement.Roles.RPar);
if (ifStatement.TrueStatement != null) if (ifStatement.TrueStatement != null)
@ -1376,10 +1376,11 @@ namespace ICSharpCode.NRefactory.CSharp
result.AddChild ((Statement)doStatement.EmbeddedStatement.Accept (this), WhileStatement.Roles.EmbeddedStatement); result.AddChild ((Statement)doStatement.EmbeddedStatement.Accept (this), WhileStatement.Roles.EmbeddedStatement);
if (location != null) if (location != null)
result.AddChild (new CSharpTokenNode (Convert (location[0]), "while".Length), DoWhileStatement.WhileKeywordRole); result.AddChild (new CSharpTokenNode (Convert (location[0]), "while".Length), DoWhileStatement.WhileKeywordRole);
if (location != null) if (location != null && location.Count > 1)
result.AddChild (new CSharpTokenNode (Convert (location[1]), 1), DoWhileStatement.Roles.LPar); result.AddChild (new CSharpTokenNode (Convert (location[1]), 1), DoWhileStatement.Roles.LPar);
result.AddChild ((Expression)doStatement.expr.Accept (this), DoWhileStatement.Roles.Condition); if (doStatement.expr != null)
if (location != null) { result.AddChild ((Expression)doStatement.expr.Accept (this), DoWhileStatement.Roles.Condition);
if (location != null && location.Count > 2) {
result.AddChild (new CSharpTokenNode (Convert (location[2]), 1), DoWhileStatement.Roles.RPar); result.AddChild (new CSharpTokenNode (Convert (location[2]), 1), DoWhileStatement.Roles.RPar);
result.AddChild (new CSharpTokenNode (Convert (location[3]), 1), DoWhileStatement.Roles.Semicolon); result.AddChild (new CSharpTokenNode (Convert (location[3]), 1), DoWhileStatement.Roles.Semicolon);
} }
@ -1848,8 +1849,10 @@ namespace ICSharpCode.NRefactory.CSharp
result.AddChild (new CSharpTokenNode (Convert (tryCatchStatement.loc), "try".Length), TryCatchStatement.TryKeywordRole); result.AddChild (new CSharpTokenNode (Convert (tryCatchStatement.loc), "try".Length), TryCatchStatement.TryKeywordRole);
if (tryCatchStatement.Block != null) if (tryCatchStatement.Block != null)
result.AddChild ((BlockStatement)tryCatchStatement.Block.Accept (this), TryCatchStatement.TryBlockRole); result.AddChild ((BlockStatement)tryCatchStatement.Block.Accept (this), TryCatchStatement.TryBlockRole);
foreach (Catch ctch in tryCatchStatement.Specific) { if (tryCatchStatement.Specific != null) {
result.AddChild (ConvertCatch (ctch), TryCatchStatement.CatchClauseRole); foreach (Catch ctch in tryCatchStatement.Specific) {
result.AddChild (ConvertCatch (ctch), TryCatchStatement.CatchClauseRole);
}
} }
if (tryCatchStatement.General != null) if (tryCatchStatement.General != null)
result.AddChild (ConvertCatch (tryCatchStatement.General), TryCatchStatement.CatchClauseRole); result.AddChild (ConvertCatch (tryCatchStatement.General), TryCatchStatement.CatchClauseRole);
@ -1891,13 +1894,13 @@ namespace ICSharpCode.NRefactory.CSharp
if (foreachStatement.Variable != null) if (foreachStatement.Variable != null)
result.AddChild (Identifier.Create (foreachStatement.Variable.Name, Convert (foreachStatement.Variable.Location)), ForeachStatement.Roles.Identifier); result.AddChild (Identifier.Create (foreachStatement.Variable.Name, Convert (foreachStatement.Variable.Location)), ForeachStatement.Roles.Identifier);
if (location != null) if (location != null && location.Count > 1)
result.AddChild (new CSharpTokenNode (Convert (location [1]), "in".Length), ForeachStatement.Roles.InKeyword); result.AddChild (new CSharpTokenNode (Convert (location [1]), "in".Length), ForeachStatement.Roles.InKeyword);
if (foreachStatement.Expr != null) if (foreachStatement.Expr != null)
result.AddChild ((Expression)foreachStatement.Expr.Accept (this), ForeachStatement.Roles.Expression); result.AddChild ((Expression)foreachStatement.Expr.Accept (this), ForeachStatement.Roles.Expression);
if (location != null) if (location != null && location.Count > 2)
result.AddChild (new CSharpTokenNode (Convert (location [2]), 1), ForeachStatement.Roles.RPar); result.AddChild (new CSharpTokenNode (Convert (location [2]), 1), ForeachStatement.Roles.RPar);
if (foreachStatement.Statement != null) if (foreachStatement.Statement != null)
result.AddChild ((Statement)foreachStatement.Statement.Accept (this), ForeachStatement.Roles.EmbeddedStatement); result.AddChild ((Statement)foreachStatement.Statement.Accept (this), ForeachStatement.Roles.EmbeddedStatement);
@ -2414,7 +2417,7 @@ namespace ICSharpCode.NRefactory.CSharp
var location = LocationsBag.GetLocations (c); var location = LocationsBag.GetLocations (c);
var constraint = new Constraint (); var constraint = new Constraint ();
constraint.AddChild (new CSharpTokenNode (Convert (c.Location), "where".Length), InvocationExpression.Roles.Keyword); constraint.AddChild (new CSharpTokenNode (Convert (c.Location), "where".Length), InvocationExpression.Roles.Keyword);
constraint.AddChild (Identifier.Create (c.TypeParameter.Value, Convert (c.TypeParameter.Location)), InvocationExpression.Roles.Identifier); constraint.AddChild (new SimpleType (Identifier.Create (c.TypeParameter.Value, Convert (c.TypeParameter.Location))), Constraint.TypeParameterRole);
if (location != null) if (location != null)
constraint.AddChild (new CSharpTokenNode (Convert (location [0]), 1), Constraint.ColonRole); constraint.AddChild (new CSharpTokenNode (Convert (location [0]), 1), Constraint.ColonRole);
var commaLocs = LocationsBag.GetLocations (c.ConstraintExpressions); var commaLocs = LocationsBag.GetLocations (c.ConstraintExpressions);

18
ICSharpCode.NRefactory.CSharp/Parser/mcs/assembly.cs

@ -318,17 +318,16 @@ namespace Mono.CSharp
string assembly_name = a.GetString (); string assembly_name = a.GetString ();
if (assembly_name.Length == 0) if (assembly_name.Length == 0)
return; return;
#if STATIC
AssemblyName aname = null; ParsedAssemblyName aname;
try { ParseAssemblyResult r = Fusion.ParseAssemblyName (assembly_name, out aname);
aname = new AssemblyName (assembly_name); if (r != ParseAssemblyResult.OK) {
} catch (Exception) {
Report.Warning (1700, 3, a.Location, "Assembly reference `{0}' is invalid and cannot be resolved", Report.Warning (1700, 3, a.Location, "Assembly reference `{0}' is invalid and cannot be resolved",
assembly_name); assembly_name);
return; return;
} }
if (aname.Version != null || aname.CultureInfo != null || aname.ProcessorArchitecture != ProcessorArchitecture.None) { if (aname.Version != null || aname.Culture != null || aname.ProcessorArchitecture != ProcessorArchitecture.None) {
Report.Error (1725, a.Location, Report.Error (1725, a.Location,
"Friend assembly reference `{0}' is invalid. InternalsVisibleTo declarations cannot have a version, culture or processor architecture specified", "Friend assembly reference `{0}' is invalid. InternalsVisibleTo declarations cannot have a version, culture or processor architecture specified",
assembly_name); assembly_name);
@ -336,13 +335,13 @@ namespace Mono.CSharp
return; return;
} }
// TODO: GetPublicKey () does not work on .NET when AssemblyName is constructed from a string if (public_key != null && !aname.HasPublicKey) {
if (public_key != null && aname.GetPublicKey () == null) {
Report.Error (1726, a.Location, Report.Error (1726, a.Location,
"Friend assembly reference `{0}' is invalid. Strong named assemblies must specify a public key in their InternalsVisibleTo declarations", "Friend assembly reference `{0}' is invalid. Strong named assemblies must specify a public key in their InternalsVisibleTo declarations",
assembly_name); assembly_name);
return; return;
} }
#endif
} else if (a.Type == pa.RuntimeCompatibility) { } else if (a.Type == pa.RuntimeCompatibility) {
wrap_non_exception_throws_custom = true; wrap_non_exception_throws_custom = true;
} else if (a.Type == pa.AssemblyFileVersion) { } else if (a.Type == pa.AssemblyFileVersion) {
@ -486,6 +485,7 @@ namespace Mono.CSharp
} }
#else #else
var args = new PermissionSet[3]; var args = new PermissionSet[3];
#pragma warning disable 618
declarative_security.TryGetValue (SecurityAction.RequestMinimum, out args[0]); declarative_security.TryGetValue (SecurityAction.RequestMinimum, out args[0]);
declarative_security.TryGetValue (SecurityAction.RequestOptional, out args[1]); declarative_security.TryGetValue (SecurityAction.RequestOptional, out args[1]);
declarative_security.TryGetValue (SecurityAction.RequestRefuse, out args[2]); declarative_security.TryGetValue (SecurityAction.RequestRefuse, out args[2]);
@ -827,7 +827,7 @@ namespace Mono.CSharp
Compiler.TimeReporter.Stop (TimeReporter.TimerType.OutputSave); Compiler.TimeReporter.Stop (TimeReporter.TimerType.OutputSave);
// Save debug symbols file // Save debug symbols file
if (symbol_writer != null) { if (symbol_writer != null && Compiler.Report.Errors == 0) {
// TODO: it should run in parallel // TODO: it should run in parallel
Compiler.TimeReporter.Start (TimeReporter.TimerType.DebugSave); Compiler.TimeReporter.Start (TimeReporter.TimerType.DebugSave);
symbol_writer.WriteSymbolFile (SymbolWriter.GetGuid (module.Builder)); symbol_writer.WriteSymbolFile (SymbolWriter.GetGuid (module.Builder));

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

File diff suppressed because it is too large Load Diff

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

@ -151,19 +151,6 @@ namespace Mono.CSharp
List<Location> attributeCommas = new List<Location> (); List<Location> attributeCommas = new List<Location> ();
List<Location> attributeArgumentCommas = new List<Location> (); List<Location> attributeArgumentCommas = new List<Location> ();
List<Location> parameterListCommas = new List<Location> (); List<Location> parameterListCommas = new List<Location> ();
object lastYYVal;
// Can be used for code completion to get the last valid expression before an error.
// needs a hack in yyparse to make it work add
// lastYYVal = yyVal;
// after the big switch/case (somewhere around line 3915)
public object LastYYVal {
get {
return lastYYVal;
}
}
%} %}
%token EOF %token EOF
@ -5165,6 +5152,12 @@ if_statement
if ($7 is EmptyStatement) if ($7 is EmptyStatement)
Warning_EmptyStatement (GetLocation ($7)); Warning_EmptyStatement (GetLocation ($7));
} }
| IF open_parens_any boolean_expression error {
var eloc = GetLocation ($3);
report.Error (1026, eloc, "Expected a ')'");
$$ = new If ((BooleanExpression) $3, null, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($2));
}
; ;
switch_statement switch_statement
@ -5276,6 +5269,18 @@ do_statement
$$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1)); $$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($3), GetLocation ($4), GetLocation ($6), GetLocation ($7)); lbag.AddStatement ($$, GetLocation ($3), GetLocation ($4), GetLocation ($6), GetLocation ($7));
} }
| DO embedded_statement error
{
var loc = GetLocation ($1);
report.Error (-100, loc, "Expected `while'");
$$ = new Do ((Statement) $2, null, loc);
}
| DO embedded_statement
WHILE open_parens_any boolean_expression error
{
$$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($3), GetLocation ($4));
}
; ;
for_statement for_statement
@ -5403,6 +5408,27 @@ foreach_statement
lbag.AddStatement (f, GetLocation ($2), GetLocation ($5), GetLocation ($7)); lbag.AddStatement (f, GetLocation ($2), GetLocation ($5), GetLocation ($7));
$$ = end_block (GetLocation ($7)); $$ = end_block (GetLocation ($7));
} }
| FOREACH open_parens_any type identifier_inside_body error
{
start_block (GetLocation ($2));
current_block.IsCompilerGenerated = true;
var lt = $4 as Tokenizer.LocatedToken;
var li = lt != null ? new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ForeachVariable | LocalVariable.Flags.Used, lt.Location) : null;
Foreach f = new Foreach ((Expression) $3, li, null, null, GetLocation ($1));
current_block.AddStatement (f);
lbag.AddStatement (f, GetLocation ($2));
$$ = end_block (GetLocation ($5));
}
| FOREACH open_parens_any type error
{
Foreach f = new Foreach ((Expression) $3, null, null, null, GetLocation ($1));
current_block.AddStatement (f);
lbag.AddStatement (f, GetLocation ($2));
$$ = f;
}
; ;
jump_statement jump_statement
@ -5521,7 +5547,7 @@ try_statement
| TRY block error | TRY block error
{ {
report.Error (1524, GetLocation ($1), "Expected catch or finally"); report.Error (1524, GetLocation ($1), "Expected catch or finally");
$$ = null; $$ = new TryCatch ((Block) $2, null, GetLocation ($1), false);
} }
; ;

24
ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs

@ -836,7 +836,6 @@ namespace Mono.CSharp
} }
return res; return res;
return res;
} }
static PreprocessorDirective GetPreprocessorDirective (char[] id, int id_len) static PreprocessorDirective GetPreprocessorDirective (char[] id, int id_len)
@ -1825,11 +1824,11 @@ namespace Mono.CSharp
{ {
// skip over white space // skip over white space
do { do {
endLine = line;
endCol = col;
c = get_char (); c = get_char ();
} while (c == ' ' || c == '\t'); } while (c == ' ' || c == '\t');
endLine = line;
endCol = col;
int pos = 0; int pos = 0;
while (c != -1 && c >= 'a' && c <= 'z') { while (c != -1 && c >= 'a' && c <= 'z') {
id_builder[pos++] = (char) c; id_builder[pos++] = (char) c;
@ -1870,17 +1869,13 @@ namespace Mono.CSharp
return cmd; return cmd;
} }
// skip over white space // skip over white space
while (c == ' ' || c == '\t') while (c == ' ' || c == '\t') {
c = get_char (); c = get_char ();
}
int has_identifier_argument = (int)(cmd & PreprocessorDirective.RequiresArgument); int has_identifier_argument = (int)(cmd & PreprocessorDirective.RequiresArgument);
int pos = 0; int pos = 0;
endLine = line;
endCol = col;
while (c != -1 && c != '\n' && c != '\r') { while (c != -1 && c != '\n' && c != '\r') {
if (c == '\\' && has_identifier_argument >= 0) { if (c == '\\' && has_identifier_argument >= 0) {
if (has_identifier_argument != 0) { if (has_identifier_argument != 0) {
@ -1914,9 +1909,9 @@ namespace Mono.CSharp
break; break;
} }
endLine = line; endLine = line;
endCol = col; endCol = col + 1;
if (pos == value_builder.Length) if (pos == value_builder.Length)
Array.Resize (ref value_builder, pos * 2); Array.Resize (ref value_builder, pos * 2);
@ -1935,7 +1930,7 @@ namespace Mono.CSharp
arg = arg.Trim (simple_whitespaces); arg = arg.Trim (simple_whitespaces);
} }
if (position_stack.Count == 0) if (position_stack.Count == 0)
sbag.AddPreProcessorDirective (startLine, startCol, endLine, endCol + 1, cmd, arg); sbag.AddPreProcessorDirective (startLine, startCol, endLine, endCol, cmd, arg);
return cmd; return cmd;
} }
@ -3348,7 +3343,7 @@ namespace Mono.CSharp
if (ParsePreprocessingDirective (true)) if (ParsePreprocessingDirective (true))
continue; continue;
sbag.StartComment (SpecialsBag.CommentType.Multi, false, line, col); sbag.StartComment (SpecialsBag.CommentType.InactiveCode, false, line, 1);
bool directive_expected = false; bool directive_expected = false;
while ((c = get_char ()) != -1) { while ((c = get_char ()) != -1) {
if (col == 1) { if (col == 1) {
@ -3359,6 +3354,7 @@ namespace Mono.CSharp
// Eror_WrongPreprocessorLocation (); // Eror_WrongPreprocessorLocation ();
// return Token.ERROR; // return Token.ERROR;
// } // }
sbag.PushCommentChar (c);
continue; continue;
} }

3
ICSharpCode.NRefactory.CSharp/Parser/mcs/driver.cs

@ -462,8 +462,7 @@ namespace Mono.CSharp
ModuleCompiled = RootContext.ToplevelTypes, ModuleCompiled = RootContext.ToplevelTypes,
LocationsBag = parser.LocationsBag, LocationsBag = parser.LocationsBag,
UsingsBag = parser.UsingsBag, UsingsBag = parser.UsingsBag,
SpecialsBag = parser.Lexer.sbag, SpecialsBag = parser.Lexer.sbag
LastYYValue = parser.LastYYVal
}; };
} finally { } finally {
Reset (); Reset ();

6
ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs

@ -6044,7 +6044,7 @@ namespace Mono.CSharp
// The number of constants in array initializers // The number of constants in array initializers
int const_initializers_count; int const_initializers_count;
bool only_constant_initializers; // bool only_constant_initializers;
public List<Expression> Arguments { public List<Expression> Arguments {
get { return this.arguments; } get { return this.arguments; }
@ -6179,7 +6179,7 @@ namespace Mono.CSharp
++const_initializers_count; ++const_initializers_count;
} }
} else { } else {
only_constant_initializers = false; // only_constant_initializers = false;
} }
array_data.Add (element); array_data.Add (element);
@ -6284,7 +6284,7 @@ namespace Mono.CSharp
protected bool ResolveInitializers (ResolveContext ec) protected bool ResolveInitializers (ResolveContext ec)
{ {
only_constant_initializers = true; // only_constant_initializers = true;
if (arguments != null) { if (arguments != null) {
bool res = true; bool res = true;

25
ICSharpCode.NRefactory.CSharp/Parser/mcs/generic.cs

@ -3264,7 +3264,7 @@ namespace Mono.CSharp {
return LowerBoundInference (u_ac.Element, v_i); return LowerBoundInference (u_ac.Element, v_i);
} }
if (TypeManager.IsGenericType (v)) { if (v.IsGenericOrParentIsGeneric) {
// //
// if V is a constructed type C<V1..Vk> and there is a unique type C<U1..Uk> // if V is a constructed type C<V1..Vk> and there is a unique type C<U1..Uk>
// such that U is identical to, inherits from (directly or indirectly), // such that U is identical to, inherits from (directly or indirectly),
@ -3292,8 +3292,8 @@ namespace Mono.CSharp {
} }
} }
TypeSpec [] unique_candidate_targs = null; TypeSpec[] unique_candidate_targs = null;
TypeSpec[] ga_v = TypeManager.GetTypeArguments (v); var ga_v = TypeSpec.GetAllTypeArguments (v);
foreach (TypeSpec u_candidate in u_candidates) { foreach (TypeSpec u_candidate in u_candidates) {
// //
// The unique set of types U1..Uk means that if we have an interface I<T>, // The unique set of types U1..Uk means that if we have an interface I<T>,
@ -3301,7 +3301,7 @@ namespace Mono.CSharp {
// type I<T> by applying type U because T could be int or long // type I<T> by applying type U because T could be int or long
// //
if (unique_candidate_targs != null) { if (unique_candidate_targs != null) {
TypeSpec[] second_unique_candidate_targs = TypeManager.GetTypeArguments (u_candidate); TypeSpec[] second_unique_candidate_targs = TypeSpec.GetAllTypeArguments (u_candidate);
if (TypeSpecComparer.Equals (unique_candidate_targs, second_unique_candidate_targs)) { if (TypeSpecComparer.Equals (unique_candidate_targs, second_unique_candidate_targs)) {
unique_candidate_targs = second_unique_candidate_targs; unique_candidate_targs = second_unique_candidate_targs;
continue; continue;
@ -3327,15 +3327,25 @@ namespace Mono.CSharp {
for (int i = 0; i < unique_candidate_targs.Length; ++i) for (int i = 0; i < unique_candidate_targs.Length; ++i)
unique_candidate_targs[i] = u_candidate; unique_candidate_targs[i] = u_candidate;
} else { } else {
unique_candidate_targs = TypeManager.GetTypeArguments (u_candidate); unique_candidate_targs = TypeSpec.GetAllTypeArguments (u_candidate);
} }
} }
if (unique_candidate_targs != null) { if (unique_candidate_targs != null) {
var ga_open_v = open_v.TypeParameters;
int score = 0; int score = 0;
int tp_index = -1;
TypeParameterSpec[] tps = null;
for (int i = 0; i < unique_candidate_targs.Length; ++i) { for (int i = 0; i < unique_candidate_targs.Length; ++i) {
Variance variance = ga_open_v [i].Variance; if (tp_index < 0) {
while (v.Arity == 0)
v = v.DeclaringType;
tps = v.MemberDefinition.TypeParameters;
tp_index = tps.Length - 1;
}
Variance variance = tps [tp_index--].Variance;
TypeSpec u_i = unique_candidate_targs [i]; TypeSpec u_i = unique_candidate_targs [i];
if (variance == Variance.None || TypeSpec.IsValueType (u_i)) { if (variance == Variance.None || TypeSpec.IsValueType (u_i)) {
@ -3349,6 +3359,7 @@ namespace Mono.CSharp {
++score; ++score;
} }
} }
return score; return score;
} }
} }

3
ICSharpCode.NRefactory.CSharp/Parser/mcs/location.cs

@ -477,7 +477,8 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format ("
{ {
Single, Single,
Multi, Multi,
Documentation Documentation,
InactiveCode
} }
public class Comment public class Comment

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

@ -667,6 +667,37 @@ namespace Mono.CSharp {
} }
} }
public class StatementErrorExpression : Statement
{
readonly Expression expr;
public StatementErrorExpression (Expression expr)
{
this.expr = expr;
}
public Expression Expression {
get {
return expr;
}
}
protected override void DoEmit (EmitContext ec)
{
throw new NotSupportedException ();
}
protected override void CloneTo (CloneContext clonectx, Statement target)
{
throw new NotImplementedException ();
}
public override object Accept (StructuralVisitor visitor)
{
return visitor.Visit (this);
}
}
// //
// Simple version of statement list not requiring a block // Simple version of statement list not requiring a block
// //
@ -5181,11 +5212,13 @@ namespace Mono.CSharp {
this.Block = block; this.Block = block;
this.Specific = catch_clauses; this.Specific = catch_clauses;
this.inside_try_finally = inside_try_finally; this.inside_try_finally = inside_try_finally;
Catch c = catch_clauses [0]; if (catch_clauses != null) {
if (c.IsGeneral) { Catch c = catch_clauses [0];
this.General = c; if (c.IsGeneral) {
catch_clauses.RemoveAt (0); this.General = c;
catch_clauses.RemoveAt (0);
}
} }
} }
@ -6161,35 +6194,4 @@ namespace Mono.CSharp {
return visitor.Visit (this); return visitor.Visit (this);
} }
} }
public class StatementErrorExpression : Statement
{
readonly Expression expr;
public Expression Expression {
get {
return expr;
}
}
public StatementErrorExpression (Expression expr)
{
this.expr = expr;
}
protected override void DoEmit (EmitContext ec)
{
throw new NotImplementedException ();
}
protected override void CloneTo (CloneContext clonectx, Statement target)
{
throw new NotImplementedException ();
}
public override object Accept (StructuralVisitor visitor)
{
return visitor.Visit (this);
}
}
} }

24
ICSharpCode.NRefactory.CSharp/Parser/mcs/typespec.cs

@ -390,6 +390,30 @@ namespace Mono.CSharp
return true; return true;
} }
//
// Returns all type arguments, usefull for nested types
//
public static TypeSpec[] GetAllTypeArguments (TypeSpec type)
{
IList<TypeSpec> targs = TypeSpec.EmptyTypes;
do {
if (type.Arity > 0) {
if (targs.Count == 0) {
targs = type.TypeArguments;
} else {
var list = targs as List<TypeSpec> ?? new List<TypeSpec> (targs);
list.AddRange (type.TypeArguments);
targs = list;
}
}
type = type.declaringType;
} while (type != null);
return targs as TypeSpec[] ?? ((List<TypeSpec>) targs).ToArray ();
}
public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa) public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa)
{ {
if (Kind != MemberKind.Class) if (Kind != MemberKind.Class)

28
ICSharpCode.NRefactory.CSharp/Parser/mcs/visit.cs

@ -7,6 +7,7 @@
// Dual licensed under the terms of the MIT X11 or GNU GPL // Dual licensed under the terms of the MIT X11 or GNU GPL
// //
// Copyright (c) 2010 Novell, Inc (http://www.novell.com) // Copyright (c) 2010 Novell, Inc (http://www.novell.com)
// Copyright 2011 Xamarin Inc
// //
using System; using System;
@ -178,7 +179,7 @@ namespace Mono.CSharp
{ {
return null; return null;
} }
public virtual object Visit (EmptyExpression emptyExpression) public virtual object Visit (EmptyExpression emptyExpression)
{ {
return null; return null;
@ -200,73 +201,66 @@ namespace Mono.CSharp
return null; return null;
} }
public virtual object Visit (While whileStatement) public virtual object Visit (While whileStatement)
{ {
return null; return null;
} }
public virtual object Visit (For forStatement) public virtual object Visit (For forStatement)
{ {
return null; return null;
} }
public virtual object Visit (StatementExpression statementExpression) public virtual object Visit (StatementExpression statementExpression)
{ {
return null; return null;
} }
public virtual object Visit (StatementErrorExpression errorStatement)
{
return null;
}
public virtual object Visit (Return returnStatement) public virtual object Visit (Return returnStatement)
{ {
return null; return null;
} }
public virtual object Visit (Goto gotoStatement) public virtual object Visit (Goto gotoStatement)
{ {
return null; return null;
} }
public virtual object Visit (LabeledStatement labeledStatement) public virtual object Visit (LabeledStatement labeledStatement)
{ {
return null; return null;
} }
public virtual object Visit (GotoDefault gotoDefault) public virtual object Visit (GotoDefault gotoDefault)
{ {
return null; return null;
} }
public virtual object Visit (GotoCase gotoCase) public virtual object Visit (GotoCase gotoCase)
{ {
return null; return null;
} }
public virtual object Visit (Throw throwStatement) public virtual object Visit (Throw throwStatement)
{ {
return null; return null;
} }
public virtual object Visit (Break breakStatement) public virtual object Visit (Break breakStatement)
{ {
return null; return null;
} }
public virtual object Visit (Continue continueStatement) public virtual object Visit (Continue continueStatement)
{ {
return null; return null;
} }
public virtual object Visit (Block blockStatement) public virtual object Visit (Block blockStatement)
{ {
return null; return null;
@ -287,19 +281,16 @@ namespace Mono.CSharp
return null; return null;
} }
public virtual object Visit (Unchecked uncheckedStatement) public virtual object Visit (Unchecked uncheckedStatement)
{ {
return null; return null;
} }
public virtual object Visit (Checked checkedStatement) public virtual object Visit (Checked checkedStatement)
{ {
return null; return null;
} }
public virtual object Visit (Unsafe unsafeStatement) public virtual object Visit (Unsafe unsafeStatement)
{ {
return null; return null;
@ -317,7 +308,6 @@ namespace Mono.CSharp
return null; return null;
} }
public virtual object Visit (TryCatch tryCatchStatement) public virtual object Visit (TryCatch tryCatchStatement)
{ {
return null; return null;
@ -445,7 +435,6 @@ namespace Mono.CSharp
return null; return null;
} }
public virtual object Visit (Conditional conditionalExpression) public virtual object Visit (Conditional conditionalExpression)
{ {
return null; return null;
@ -646,10 +635,5 @@ namespace Mono.CSharp
{ {
return null; return null;
} }
public virtual object Visit (StatementErrorExpression statementErrorExpression)
{
return null;
}
} }
} }

2
ICSharpCode.NRefactory.CSharp/Refactoring/TextReplaceAction.cs

@ -128,7 +128,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
/// </returns> /// </returns>
public override string ToString () public override string ToString ()
{ {
return string.Format ("[TextReplaceAction: Offset={0}, RemovedChars={1}, InsertedText={2}]", Offset, RemovedChars, InsertedText == null ? "<null>" : InsertedText.Replace ("\t", "\\t").Replace ("\n", "\\n")); return string.Format ("[TextReplaceAction: Offset={0}, RemovedChars={1}, InsertedText={2}]", Offset, RemovedChars, InsertedText == null ? "<null>" : InsertedText.Replace ("\t", "\\t").Replace ("\n", "\\n").Replace ("\r", "\\r"));
} }
} }
} }

2
ICSharpCode.NRefactory.CSharp/Refactoring/TypeSystemAstBuilder.cs

@ -682,7 +682,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
return null; return null;
} }
Constraint c = new Constraint(); Constraint c = new Constraint();
c.TypeParameter = tp.Name; c.TypeParameter = new SimpleType (tp.Name);
if (tp.HasReferenceTypeConstraint) { if (tp.HasReferenceTypeConstraint) {
c.BaseTypes.Add(new PrimitiveType("class")); c.BaseTypes.Add(new PrimitiveType("class"));
} else if (tp.HasValueTypeConstraint) { } else if (tp.HasValueTypeConstraint) {

2
ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs

@ -70,7 +70,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
throw new ArgumentNullException("resolver"); throw new ArgumentNullException("resolver");
if (rootNode == null) if (rootNode == null)
throw new ArgumentNullException("rootNode"); throw new ArgumentNullException("rootNode");
this.initialResolverState = resolver.Clone(); this.initialResolverState = resolver;
this.rootNode = rootNode; this.rootNode = rootNode;
this.parsedFile = parsedFile; this.parsedFile = parsedFile;
} }

14
ICSharpCode.NRefactory.CSharp/Resolver/CSharpOperators.cs

@ -289,6 +289,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public override object Invoke(CSharpResolver resolver, object input) public override object Invoke(CSharpResolver resolver, object input)
{ {
if (input == null)
return null;
return func((T)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T)), input)); return func((T)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T)), input));
} }
@ -456,6 +458,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public override object Invoke(CSharpResolver resolver, object lhs, object rhs) public override object Invoke(CSharpResolver resolver, object lhs, object rhs)
{ {
if (lhs == null || rhs == null)
return null;
Func<T1, T2, T1> func = resolver.CheckForOverflow ? checkedFunc : uncheckedFunc; Func<T1, T2, T1> func = resolver.CheckForOverflow ? checkedFunc : uncheckedFunc;
return func((T1)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T1)), lhs), return func((T1)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T1)), lhs),
(T2)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T2)), rhs)); (T2)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T2)), rhs));
@ -692,6 +696,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public override object Invoke(CSharpResolver resolver, object lhs, object rhs) public override object Invoke(CSharpResolver resolver, object lhs, object rhs)
{ {
if (lhs == null && rhs == null)
return !Negate; // ==: true; !=: false
if (lhs == null || rhs == null)
return Negate; // ==: false; !=: true
lhs = resolver.CSharpPrimitiveCast(Type, lhs); lhs = resolver.CSharpPrimitiveCast(Type, lhs);
rhs = resolver.CSharpPrimitiveCast(Type, rhs); rhs = resolver.CSharpPrimitiveCast(Type, rhs);
bool equal; bool equal;
@ -734,10 +742,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public override object Invoke(CSharpResolver resolver, object lhs, object rhs) public override object Invoke(CSharpResolver resolver, object lhs, object rhs)
{ {
if (lhs == null && rhs == null)
return !baseMethod.Negate; // ==: true; !=: false
if (lhs == null || rhs == null)
return baseMethod.Negate; // ==: false; !=: true
return baseMethod.Invoke(resolver, lhs, rhs); return baseMethod.Invoke(resolver, lhs, rhs);
} }
@ -809,6 +813,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public override object Invoke(CSharpResolver resolver, object lhs, object rhs) public override object Invoke(CSharpResolver resolver, object lhs, object rhs)
{ {
if (lhs == null || rhs == null)
return null;
return func((T1)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T1)), lhs), return func((T1)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T1)), lhs),
(T2)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T2)), rhs)); (T2)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T2)), rhs));
} }

193
ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs

@ -43,7 +43,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
readonly ICompilation compilation; readonly ICompilation compilation;
internal readonly Conversions conversions; internal readonly Conversions conversions;
CSharpTypeResolveContext context; readonly CSharpTypeResolveContext context;
readonly bool checkForOverflow;
readonly bool isWithinLambdaExpression;
#region Constructor #region Constructor
public CSharpResolver(ICompilation compilation) public CSharpResolver(ICompilation compilation)
@ -65,6 +67,18 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (context.CurrentTypeDefinition != null) if (context.CurrentTypeDefinition != null)
currentTypeDefinitionCache = new TypeDefinitionCache(context.CurrentTypeDefinition); currentTypeDefinitionCache = new TypeDefinitionCache(context.CurrentTypeDefinition);
} }
private CSharpResolver(ICompilation compilation, Conversions conversions, CSharpTypeResolveContext context, bool checkForOverflow, bool isWithinLambdaExpression, TypeDefinitionCache currentTypeDefinitionCache, ImmutableStack<IVariable> localVariableStack, ObjectInitializerContext objectInitializerStack)
{
this.compilation = compilation;
this.conversions = conversions;
this.context = context;
this.checkForOverflow = checkForOverflow;
this.isWithinLambdaExpression = isWithinLambdaExpression;
this.currentTypeDefinitionCache = currentTypeDefinitionCache;
this.localVariableStack = localVariableStack;
this.objectInitializerStack = objectInitializerStack;
}
#endregion #endregion
#region Properties #region Properties
@ -82,53 +96,101 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
get { return context; } get { return context; }
} }
CSharpResolver WithContext(CSharpTypeResolveContext newContext)
{
return new CSharpResolver(compilation, conversions, newContext, checkForOverflow, isWithinLambdaExpression, currentTypeDefinitionCache, localVariableStack, objectInitializerStack);
}
/// <summary>
/// Gets whether the current context is <c>checked</c>.
/// </summary>
public bool CheckForOverflow {
get { return checkForOverflow; }
}
/// <summary>
/// Sets whether the current context is <c>checked</c>.
/// </summary>
public CSharpResolver WithCheckForOverflow(bool checkForOverflow)
{
return new CSharpResolver(compilation, conversions, context, checkForOverflow, isWithinLambdaExpression, currentTypeDefinitionCache, localVariableStack, objectInitializerStack);
}
/// <summary>
/// Gets whether the resolver is currently within a lambda expression.
/// </summary>
public bool IsWithinLambdaExpression {
get { return isWithinLambdaExpression; }
}
/// <summary> /// <summary>
/// Gets/Sets whether the current context is <c>checked</c>. /// Sets whether the resolver is currently within a lambda expression.
/// </summary> /// </summary>
public bool CheckForOverflow { get; set; } public CSharpResolver WithIsWithinLambdaExpression(bool isWithinLambdaExpression)
{
return new CSharpResolver(compilation, conversions, context, checkForOverflow, isWithinLambdaExpression, currentTypeDefinitionCache, localVariableStack, objectInitializerStack);
}
/// <summary> /// <summary>
/// Gets/Sets the current member definition that is used to look up identifiers as parameters /// Gets the current member definition that is used to look up identifiers as parameters
/// or type parameters. /// or type parameters.
/// </summary> /// </summary>
/// <remarks>Don't forget to also set CurrentTypeDefinition when setting CurrentMember;
/// setting one of the properties does not automatically set the other.</remarks>
public IMember CurrentMember { public IMember CurrentMember {
get { return context.CurrentMember; } get { return context.CurrentMember; }
set {
context = context.WithCurrentMember(value);
}
} }
/// <summary> /// <summary>
/// Gets/Sets the current using scope that is used to look up identifiers as class names. /// Sets the current member definition.
/// </summary>
/// <remarks>Don't forget to also set CurrentTypeDefinition when setting CurrentMember;
/// setting one of the properties does not automatically set the other.</remarks>
public CSharpResolver WithCurrentMember(IMember member)
{
return WithContext(context.WithCurrentMember(member));
}
/// <summary>
/// Gets the current using scope that is used to look up identifiers as class names.
/// </summary> /// </summary>
public ResolvedUsingScope CurrentUsingScope { public ResolvedUsingScope CurrentUsingScope {
get { return context.CurrentUsingScope; } get { return context.CurrentUsingScope; }
set { }
context = context.WithUsingScope(value);
} /// <summary>
/// Sets the current using scope that is used to look up identifiers as class names.
/// </summary>
public CSharpResolver WithCurrentUsingScope(ResolvedUsingScope usingScope)
{
return WithContext(context.WithUsingScope(usingScope));
} }
#endregion #endregion
#region Per-CurrentTypeDefinition Cache #region Per-CurrentTypeDefinition Cache
TypeDefinitionCache currentTypeDefinitionCache; readonly TypeDefinitionCache currentTypeDefinitionCache;
/// <summary> /// <summary>
/// Gets/Sets the current type definition that is used to look up identifiers as simple members. /// Gets the current type definition.
/// </summary> /// </summary>
public ITypeDefinition CurrentTypeDefinition { public ITypeDefinition CurrentTypeDefinition {
get { return context.CurrentTypeDefinition; } get { return context.CurrentTypeDefinition; }
set { }
context = context.WithCurrentTypeDefinition(value);
if (value == null) { /// <summary>
currentTypeDefinitionCache = null; /// Sets the current type definition.
} else { /// </summary>
if (currentTypeDefinitionCache == null || currentTypeDefinitionCache.TypeDefinition != value) { public CSharpResolver WithCurrentTypeDefinition(ITypeDefinition typeDefinition)
currentTypeDefinitionCache = new TypeDefinitionCache(value); {
} if (this.CurrentTypeDefinition == typeDefinition)
} return this;
}
TypeDefinitionCache newTypeDefinitionCache;
if (typeDefinition != null)
newTypeDefinitionCache = new TypeDefinitionCache(typeDefinition);
else
newTypeDefinitionCache = null;
return new CSharpResolver(compilation, conversions, context.WithCurrentTypeDefinition(typeDefinition),
checkForOverflow, isWithinLambdaExpression, newTypeDefinitionCache, localVariableStack, objectInitializerStack);
} }
sealed class TypeDefinitionCache sealed class TypeDefinitionCache
@ -151,36 +213,43 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// The beginning of a block is marked by a null entry. // The beginning of a block is marked by a null entry.
// This data structure is used to allow efficient cloning of the resolver with its local variable context. // This data structure is used to allow efficient cloning of the resolver with its local variable context.
ImmutableStack<IVariable> localVariableStack = ImmutableStack<IVariable>.Empty; readonly ImmutableStack<IVariable> localVariableStack = ImmutableStack<IVariable>.Empty;
CSharpResolver WithLocalVariableStack(ImmutableStack<IVariable> stack)
{
return new CSharpResolver(compilation, conversions, context, checkForOverflow, isWithinLambdaExpression, currentTypeDefinitionCache, stack, objectInitializerStack);
}
/// <summary> /// <summary>
/// Opens a new scope for local variables. /// Opens a new scope for local variables.
/// </summary> /// </summary>
public void PushBlock() public CSharpResolver PushBlock()
{ {
localVariableStack = localVariableStack.Push(null); return WithLocalVariableStack(localVariableStack.Push(null));
} }
/// <summary> /// <summary>
/// Closes the current scope for local variables; removing all variables in that scope. /// Closes the current scope for local variables; removing all variables in that scope.
/// </summary> /// </summary>
public void PopBlock() public CSharpResolver PopBlock()
{ {
var stack = localVariableStack;
IVariable removedVar; IVariable removedVar;
do { do {
removedVar = localVariableStack.Peek(); removedVar = stack.Peek();
localVariableStack = localVariableStack.Pop(); stack = stack.Pop();
} while (removedVar != null); } while (removedVar != null);
return WithLocalVariableStack(stack);
} }
/// <summary> /// <summary>
/// Adds a new variable or lambda parameter to the current block. /// Adds a new variable or lambda parameter to the current block.
/// </summary> /// </summary>
public void AddVariable(IVariable variable) public CSharpResolver AddVariable(IVariable variable)
{ {
if (variable == null) if (variable == null)
throw new ArgumentNullException("variable"); throw new ArgumentNullException("variable");
localVariableStack = localVariableStack.Push(variable); return WithLocalVariableStack(localVariableStack.Push(variable));
} }
/// <summary> /// <summary>
@ -191,11 +260,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return localVariableStack.Where(v => v != null); return localVariableStack.Where(v => v != null);
} }
} }
/// <summary>
/// Gets whether the resolver is currently within a lambda expression.
/// </summary>
public bool IsWithinLambdaExpression { get; set; }
#endregion #endregion
#region Object Initializer Context #region Object Initializer Context
@ -211,23 +275,28 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
} }
ObjectInitializerContext objectInitializerStack; readonly ObjectInitializerContext objectInitializerStack;
CSharpResolver WithObjectInitializerStack(ObjectInitializerContext stack)
{
return new CSharpResolver(compilation, conversions, context, checkForOverflow, isWithinLambdaExpression, currentTypeDefinitionCache, localVariableStack, stack);
}
/// <summary> /// <summary>
/// Pushes the type of the object that is currently being initialized. /// Pushes the type of the object that is currently being initialized.
/// </summary> /// </summary>
public void PushInitializerType(IType type) public CSharpResolver PushInitializerType(IType type)
{ {
if (type == null) if (type == null)
throw new ArgumentNullException("type"); throw new ArgumentNullException("type");
objectInitializerStack = new ObjectInitializerContext(type, objectInitializerStack); return WithObjectInitializerStack(new ObjectInitializerContext(type, objectInitializerStack));
} }
public void PopInitializerType() public CSharpResolver PopInitializerType()
{ {
if (objectInitializerStack == null) if (objectInitializerStack == null)
throw new InvalidOperationException(); throw new InvalidOperationException();
objectInitializerStack = objectInitializerStack.prev; return WithObjectInitializerStack(objectInitializerStack.prev);
} }
/// <summary> /// <summary>
@ -244,9 +313,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// <summary> /// <summary>
/// Creates a copy of this CSharp resolver. /// Creates a copy of this CSharp resolver.
/// </summary> /// </summary>
[Obsolete("CSharpResolver is immutable, cloning is no longer necessary")]
public CSharpResolver Clone() public CSharpResolver Clone()
{ {
return (CSharpResolver)MemberwiseClone(); return this;
} }
#endregion #endregion
@ -323,7 +393,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
break; break;
case UnaryOperatorType.BitNot: case UnaryOperatorType.BitNot:
if (type.Kind == TypeKind.Enum) { if (type.Kind == TypeKind.Enum) {
if (expression.IsCompileTimeConstant && !isNullable) { if (expression.IsCompileTimeConstant && !isNullable && expression.ConstantValue != null) {
// evaluate as (E)(~(U)x); // evaluate as (E)(~(U)x);
var U = compilation.FindType(expression.ConstantValue.GetType()); var U = compilation.FindType(expression.ConstantValue.GetType());
var unpackedEnum = new ConstantResolveResult(U, expression.ConstantValue); var unpackedEnum = new ConstantResolveResult(U, expression.ConstantValue);
@ -345,12 +415,17 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
CSharpOperators.UnaryOperatorMethod m = (CSharpOperators.UnaryOperatorMethod)builtinOperatorOR.BestCandidate; CSharpOperators.UnaryOperatorMethod m = (CSharpOperators.UnaryOperatorMethod)builtinOperatorOR.BestCandidate;
IType resultType = m.ReturnType; IType resultType = m.ReturnType;
if (builtinOperatorOR.BestCandidateErrors != OverloadResolutionErrors.None) { if (builtinOperatorOR.BestCandidateErrors != OverloadResolutionErrors.None) {
// If there are any user-defined operators, prefer those over the built-in operators. if (userDefinedOperatorOR.BestCandidate != null) {
// It'll be a more informative error. // If there are any user-defined operators, prefer those over the built-in operators.
if (userDefinedOperatorOR.BestCandidate != null) // It'll be a more informative error.
return CreateResolveResultForUserDefinedOperator(userDefinedOperatorOR); return CreateResolveResultForUserDefinedOperator(userDefinedOperatorOR);
else } else if (builtinOperatorOR.BestCandidateAmbiguousWith != null) {
// If the best candidate is ambiguous, just use the input type instead
// of picking one of the ambiguous overloads.
return new ErrorResolveResult(expression.Type);
} else {
return new ErrorResolveResult(resultType); return new ErrorResolveResult(resultType);
}
} else if (expression.IsCompileTimeConstant && m.CanEvaluateAtCompileTime) { } else if (expression.IsCompileTimeConstant && m.CanEvaluateAtCompileTime) {
object val; object val;
try { try {
@ -1255,7 +1330,16 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult LookInCurrentType(string identifier, IList<IType> typeArguments, SimpleNameLookupMode lookupMode, bool parameterizeResultType) ResolveResult LookInCurrentType(string identifier, IList<IType> typeArguments, SimpleNameLookupMode lookupMode, bool parameterizeResultType)
{ {
int k = typeArguments.Count; int k = typeArguments.Count;
MemberLookup lookup = CreateMemberLookup(); MemberLookup lookup;
if (lookupMode == SimpleNameLookupMode.BaseTypeReference && this.CurrentTypeDefinition != null) {
// When looking up a base type reference, treat us as being outside the current type definition
// for accessibility purposes.
// This avoids a stack overflow when referencing a protected class nested inside the base class
// of a parent class. (NameLookupTests.InnerClassInheritingFromProtectedBaseInnerClassShouldNotCauseStackOverflow)
lookup = new MemberLookup(this.CurrentTypeDefinition.DeclaringTypeDefinition, this.Compilation.MainAssembly, false);
} else {
lookup = CreateMemberLookup();
}
// look in current type definitions // look in current type definitions
for (ITypeDefinition t = this.CurrentTypeDefinition; t != null; t = t.DeclaringTypeDefinition) { for (ITypeDefinition t = this.CurrentTypeDefinition; t != null; t = t.DeclaringTypeDefinition) {
if (k == 0) { if (k == 0) {
@ -1306,7 +1390,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ITypeDefinition def = n.GetTypeDefinition(identifier, k); ITypeDefinition def = n.GetTypeDefinition(identifier, k);
if (def != null) { if (def != null) {
IType result = def; IType result = def;
if (parameterizeResultType) { if (parameterizeResultType && k > 0) {
result = new ParameterizedType(def, typeArguments); result = new ParameterizedType(def, typeArguments);
} }
if (u.HasAlias(identifier)) if (u.HasAlias(identifier))
@ -1410,7 +1494,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (mgrr != null) { if (mgrr != null) {
Debug.Assert(mgrr.extensionMethods == null); Debug.Assert(mgrr.extensionMethods == null);
// set the values that are necessary to make MethodGroupResolveResult.GetExtensionMethods() work // set the values that are necessary to make MethodGroupResolveResult.GetExtensionMethods() work
mgrr.resolver = this.Clone(); mgrr.resolver = this;
} }
} }
return result; return result;
@ -1451,9 +1535,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// </summary> /// </summary>
public MemberLookup CreateMemberLookup() public MemberLookup CreateMemberLookup()
{ {
ITypeDefinition currentTypeDefinition = this.CurrentTypeDefinition;
bool isInEnumMemberInitializer = this.CurrentMember != null && this.CurrentMember.EntityType == EntityType.Field bool isInEnumMemberInitializer = this.CurrentMember != null && this.CurrentMember.EntityType == EntityType.Field
&& this.CurrentTypeDefinition != null && this.CurrentTypeDefinition.Kind == TypeKind.Enum; && currentTypeDefinition != null && currentTypeDefinition.Kind == TypeKind.Enum;
return new MemberLookup(this.CurrentTypeDefinition, this.Compilation.MainAssembly, isInEnumMemberInitializer); return new MemberLookup(currentTypeDefinition, this.Compilation.MainAssembly, isInEnumMemberInitializer);
} }
#endregion #endregion

5
ICSharpCode.NRefactory.CSharp/Resolver/FindReferenceSearchScope.cs

@ -27,7 +27,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public interface IFindReferenceSearchScope public interface IFindReferenceSearchScope
{ {
/// <summary> /// <summary>
/// Gets the parent compilation for this search scope. /// Gets the compilation in which the entity being search for was defined.
/// This is not necessarily the same compilation as is being searched in.
/// </summary> /// </summary>
ICompilation Compilation { get; } ICompilation Compilation { get; }
@ -51,6 +52,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// Creates a navigator that can find references to this entity and reports /// Creates a navigator that can find references to this entity and reports
/// them to the specified callback. /// them to the specified callback.
/// </summary> /// </summary>
IResolveVisitorNavigator GetNavigator(FoundReferenceCallback callback); IResolveVisitorNavigator GetNavigator(ICompilation compilation, FoundReferenceCallback callback);
} }
} }

378
ICSharpCode.NRefactory.CSharp/Resolver/FindReferences.cs

@ -20,6 +20,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using ICSharpCode.NRefactory.CSharp.Refactoring;
using ICSharpCode.NRefactory.CSharp.TypeSystem; using ICSharpCode.NRefactory.CSharp.TypeSystem;
using ICSharpCode.NRefactory.Semantics; using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
@ -93,24 +94,39 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#endregion #endregion
#region class SearchScope #region class SearchScope
abstract class SearchScope : IResolveVisitorNavigator, IFindReferenceSearchScope sealed class SearchScope : IFindReferenceSearchScope
{ {
protected string searchTerm; readonly Func<ICompilation, FindReferenceNavigator> factory;
internal ICompilation compilation;
internal Accessibility accessibility;
internal ITypeDefinition topLevelTypeDefinition;
FoundReferenceCallback callback; public SearchScope(Func<ICompilation, FindReferenceNavigator> factory)
{
this.factory = factory;
}
ICompilation IFindReferenceSearchScope.Compilation { public SearchScope(string searchTerm, Func<ICompilation, FindReferenceNavigator> factory)
get { return compilation; } {
this.searchTerm = searchTerm;
this.factory = factory;
} }
IResolveVisitorNavigator IFindReferenceSearchScope.GetNavigator(FoundReferenceCallback callback) internal string searchTerm;
internal ICompilation declarationCompilation;
internal Accessibility accessibility;
internal ITypeDefinition topLevelTypeDefinition;
IResolveVisitorNavigator IFindReferenceSearchScope.GetNavigator(ICompilation compilation, FoundReferenceCallback callback)
{ {
SearchScope n = (SearchScope)MemberwiseClone(); FindReferenceNavigator n = factory(compilation);
n.callback = callback; if (n != null) {
return n; n.callback = callback;
return n;
} else {
return new ConstantModeResolveVisitorNavigator(ResolveVisitorNavigationMode.Skip, null);
}
}
ICompilation IFindReferenceSearchScope.Compilation {
get { return declarationCompilation; }
} }
string IFindReferenceSearchScope.SearchTerm { string IFindReferenceSearchScope.SearchTerm {
@ -124,6 +140,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ITypeDefinition IFindReferenceSearchScope.TopLevelTypeDefinition { ITypeDefinition IFindReferenceSearchScope.TopLevelTypeDefinition {
get { return topLevelTypeDefinition; } get { return topLevelTypeDefinition; }
} }
}
abstract class FindReferenceNavigator : IResolveVisitorNavigator
{
internal FoundReferenceCallback callback;
internal abstract bool CanMatch(AstNode node); internal abstract bool CanMatch(AstNode node);
internal abstract bool IsMatch(ResolveResult rr); internal abstract bool IsMatch(ResolveResult rr);
@ -143,12 +164,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
} }
void IResolveVisitorNavigator.ProcessConversion(Expression expression, ResolveResult result, Conversion conversion, IType targetType) public virtual void ProcessConversion(Expression expression, ResolveResult result, Conversion conversion, IType targetType)
{
ProcessConversion(expression, result, conversion, targetType);
}
internal virtual void ProcessConversion(Expression expression, ResolveResult result, Conversion conversion, IType targetType)
{ {
} }
@ -173,33 +189,33 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
SearchScope additionalScope = null; SearchScope additionalScope = null;
switch (entity.EntityType) { switch (entity.EntityType) {
case EntityType.TypeDefinition: case EntityType.TypeDefinition:
scope = new FindTypeDefinitionReferences((ITypeDefinition)entity, this.FindTypeReferencesEvenIfAliased); scope = FindTypeDefinitionReferences((ITypeDefinition)entity, this.FindTypeReferencesEvenIfAliased);
break; break;
case EntityType.Field: case EntityType.Field:
if (entity.DeclaringTypeDefinition != null && entity.DeclaringTypeDefinition.Kind == TypeKind.Enum) if (entity.DeclaringTypeDefinition != null && entity.DeclaringTypeDefinition.Kind == TypeKind.Enum)
scope = new FindEnumMemberReferences((IField)entity); scope = FindMemberReferences(entity, m => new FindEnumMemberReferences((IField)m));
else else
scope = new FindFieldReferences((IField)entity); scope = FindMemberReferences(entity, m => new FindFieldReferences((IField)m));
break; break;
case EntityType.Property: case EntityType.Property:
scope = new FindPropertyReferences((IProperty)entity); scope = FindMemberReferences(entity, m => new FindPropertyReferences((IProperty)m));
break; break;
case EntityType.Event: case EntityType.Event:
scope = new FindEventReferences((IEvent)entity); scope = FindMemberReferences(entity, m => new FindEventReferences((IEvent)m));
break; break;
case EntityType.Method: case EntityType.Method:
scope = GetSearchScopeForMethod((IMethod)entity); scope = GetSearchScopeForMethod((IMethod)entity);
break; break;
case EntityType.Indexer: case EntityType.Indexer:
scope = new FindIndexerReferences((IProperty)entity); scope = FindIndexerReferences((IProperty)entity);
break; break;
case EntityType.Operator: case EntityType.Operator:
scope = GetSearchScopeForOperator((IMethod)entity); scope = GetSearchScopeForOperator((IMethod)entity);
break; break;
case EntityType.Constructor: case EntityType.Constructor:
IMethod ctor = (IMethod)entity; IMethod ctor = (IMethod)((IMethod)entity).MemberDefinition;
scope = new FindObjectCreateReferences(ctor); scope = FindObjectCreateReferences(ctor);
additionalScope = new FindChainedConstructorReferences(ctor); additionalScope = FindChainedConstructorReferences(ctor);
break; break;
case EntityType.Destructor: case EntityType.Destructor:
return EmptyList<IFindReferenceSearchScope>.Instance; return EmptyList<IFindReferenceSearchScope>.Instance;
@ -208,12 +224,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
if (scope.accessibility == Accessibility.None) if (scope.accessibility == Accessibility.None)
scope.accessibility = effectiveAccessibility; scope.accessibility = effectiveAccessibility;
scope.compilation = entity.Compilation; scope.declarationCompilation = entity.Compilation;
scope.topLevelTypeDefinition = topLevelTypeDefinition; scope.topLevelTypeDefinition = topLevelTypeDefinition;
if (additionalScope != null) { if (additionalScope != null) {
if (additionalScope.accessibility == Accessibility.None) if (additionalScope.accessibility == Accessibility.None)
additionalScope.accessibility = effectiveAccessibility; additionalScope.accessibility = effectiveAccessibility;
additionalScope.compilation = entity.Compilation; additionalScope.declarationCompilation = entity.Compilation;
additionalScope.topLevelTypeDefinition = topLevelTypeDefinition; additionalScope.topLevelTypeDefinition = topLevelTypeDefinition;
return new[] { scope, additionalScope }; return new[] { scope, additionalScope };
} else { } else {
@ -284,11 +300,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// <param name="context">The type resolve context to use for resolving the file.</param> /// <param name="context">The type resolve context to use for resolving the file.</param>
/// <param name="callback">Callback used to report the references that were found.</param> /// <param name="callback">Callback used to report the references that were found.</param>
public void FindReferencesInFile(IFindReferenceSearchScope searchScope, CSharpParsedFile parsedFile, CompilationUnit compilationUnit, public void FindReferencesInFile(IFindReferenceSearchScope searchScope, CSharpParsedFile parsedFile, CompilationUnit compilationUnit,
FoundReferenceCallback callback, CancellationToken cancellationToken) ICompilation compilation, FoundReferenceCallback callback, CancellationToken cancellationToken)
{ {
if (searchScope == null) if (searchScope == null)
throw new ArgumentNullException("searchScope"); throw new ArgumentNullException("searchScope");
FindReferencesInFile(new[] { searchScope }, parsedFile, compilationUnit, callback, cancellationToken); FindReferencesInFile(new[] { searchScope }, parsedFile, compilationUnit, compilation, callback, cancellationToken);
} }
/// <summary> /// <summary>
@ -300,7 +316,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// <param name="callback">Callback used to report the references that were found.</param> /// <param name="callback">Callback used to report the references that were found.</param>
/// <param name="cancellationToken">Cancellation token.</param> /// <param name="cancellationToken">Cancellation token.</param>
public void FindReferencesInFile(IList<IFindReferenceSearchScope> searchScopes, CSharpParsedFile parsedFile, CompilationUnit compilationUnit, public void FindReferencesInFile(IList<IFindReferenceSearchScope> searchScopes, CSharpParsedFile parsedFile, CompilationUnit compilationUnit,
FoundReferenceCallback callback, CancellationToken cancellationToken) ICompilation compilation, FoundReferenceCallback callback, CancellationToken cancellationToken)
{ {
if (searchScopes == null) if (searchScopes == null)
throw new ArgumentNullException("searchScopes"); throw new ArgumentNullException("searchScopes");
@ -308,41 +324,61 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
throw new ArgumentNullException("parsedFile"); throw new ArgumentNullException("parsedFile");
if (compilationUnit == null) if (compilationUnit == null)
throw new ArgumentNullException("compilationUnit"); throw new ArgumentNullException("compilationUnit");
if (compilation == null)
throw new ArgumentNullException("compilation");
if (callback == null)
throw new ArgumentNullException("callback");
if (searchScopes.Count == 0) if (searchScopes.Count == 0)
return; return;
ICompilation compilation = searchScopes[0].Compilation;
IResolveVisitorNavigator navigator; IResolveVisitorNavigator navigator;
if (searchScopes.Count == 1) { if (searchScopes.Count == 1) {
navigator = searchScopes[0].GetNavigator(callback); navigator = searchScopes[0].GetNavigator(compilation, callback);
} else { } else {
IResolveVisitorNavigator[] navigators = new IResolveVisitorNavigator[searchScopes.Count]; IResolveVisitorNavigator[] navigators = new IResolveVisitorNavigator[searchScopes.Count];
for (int i = 0; i < navigators.Length; i++) { for (int i = 0; i < navigators.Length; i++) {
if (searchScopes[i].Compilation != compilation) navigators[i] = searchScopes[i].GetNavigator(compilation, callback);
throw new InvalidOperationException("All search scopes must belong to the same compilation");
navigators[i] = searchScopes[i].GetNavigator(callback);
} }
navigator = new CompositeResolveVisitorNavigator(navigators); navigator = new CompositeResolveVisitorNavigator(navigators);
} }
cancellationToken.ThrowIfCancellationRequested();
navigator = new DetectSkippableNodesNavigator(navigator, compilationUnit); navigator = new DetectSkippableNodesNavigator(navigator, compilationUnit);
cancellationToken.ThrowIfCancellationRequested();
CSharpAstResolver resolver = new CSharpAstResolver(compilation, compilationUnit, parsedFile); CSharpAstResolver resolver = new CSharpAstResolver(compilation, compilationUnit, parsedFile);
resolver.ApplyNavigator(navigator); resolver.ApplyNavigator(navigator, cancellationToken);
} }
#endregion #endregion
#region Find TypeDefinition References #region Find TypeDefinition References
sealed class FindTypeDefinitionReferences : SearchScope SearchScope FindTypeDefinitionReferences(ITypeDefinition typeDefinition, bool findTypeReferencesEvenIfAliased)
{
string searchTerm = null;
if (!findTypeReferencesEvenIfAliased && ReflectionHelper.GetTypeCode(typeDefinition) == TypeCode.Empty) {
// not a built-in type
searchTerm = typeDefinition.Name;
}
return new SearchScope(
searchTerm,
delegate (ICompilation compilation) {
ITypeDefinition imported = compilation.Import(typeDefinition);
if (imported != null)
return new FindTypeDefinitionReferencesNavigator(imported, searchTerm);
else
return null;
});
}
sealed class FindTypeDefinitionReferencesNavigator : FindReferenceNavigator
{ {
ITypeDefinition typeDefinition; readonly ITypeDefinition typeDefinition;
readonly string searchTerm;
public FindTypeDefinitionReferences(ITypeDefinition typeDefinition, bool findTypeReferencesEvenIfAliased) public FindTypeDefinitionReferencesNavigator(ITypeDefinition typeDefinition, string searchTerm)
{ {
this.typeDefinition = typeDefinition; this.typeDefinition = typeDefinition;
if (!findTypeReferencesEvenIfAliased && ReflectionHelper.GetTypeCode(typeDefinition) == TypeCode.Empty) { this.searchTerm = searchTerm;
// not a built-in type
this.searchTerm = typeDefinition.Name;
}
} }
internal override bool CanMatch(AstNode node) internal override bool CanMatch(AstNode node)
@ -378,11 +414,24 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#endregion #endregion
#region Find Member References #region Find Member References
class FindMemberReferences : SearchScope SearchScope FindMemberReferences(IEntity member, Func<IMember, FindMemberReferencesNavigator> factory)
{
string searchTerm = member.Name;
IMember memberDefinition = ((IMember)member).MemberDefinition;
return new SearchScope(
searchTerm,
delegate(ICompilation compilation) {
IMember imported = compilation.Import(memberDefinition);
return imported != null ? factory(imported) : null;
});
}
class FindMemberReferencesNavigator : FindReferenceNavigator
{ {
readonly IMember member; readonly IMember member;
readonly string searchTerm;
public FindMemberReferences(IMember member) public FindMemberReferencesNavigator(IMember member)
{ {
this.member = member.MemberDefinition; this.member = member.MemberDefinition;
this.searchTerm = member.Name; this.searchTerm = member.Name;
@ -416,7 +465,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
} }
sealed class FindFieldReferences : FindMemberReferences sealed class FindFieldReferences : FindMemberReferencesNavigator
{ {
public FindFieldReferences(IField field) : base(field) public FindFieldReferences(IField field) : base(field)
{ {
@ -431,7 +480,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
} }
sealed class FindEnumMemberReferences : FindMemberReferences sealed class FindEnumMemberReferences : FindMemberReferencesNavigator
{ {
public FindEnumMemberReferences(IField field) : base(field) public FindEnumMemberReferences(IField field) : base(field)
{ {
@ -443,7 +492,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
} }
sealed class FindPropertyReferences : FindMemberReferences sealed class FindPropertyReferences : FindMemberReferencesNavigator
{ {
public FindPropertyReferences(IProperty property) : base(property) public FindPropertyReferences(IProperty property) : base(property)
{ {
@ -455,7 +504,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
} }
sealed class FindEventReferences : FindMemberReferences sealed class FindEventReferences : FindMemberReferencesNavigator
{ {
public FindEventReferences(IEvent ev) : base(ev) public FindEventReferences(IEvent ev) : base(ev)
{ {
@ -474,46 +523,67 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#region Find Method References #region Find Method References
SearchScope GetSearchScopeForMethod(IMethod method) SearchScope GetSearchScopeForMethod(IMethod method)
{ {
method = (IMethod)method.MemberDefinition;
Type specialNodeType;
switch (method.Name) { switch (method.Name) {
case "Add": case "Add":
return new FindMethodReferences(method, typeof(ArrayInitializerExpression)); specialNodeType = typeof(ArrayInitializerExpression);
break;
case "Where": case "Where":
return new FindMethodReferences(method, typeof(QueryWhereClause)); specialNodeType = typeof(QueryWhereClause);
break;
case "Select": case "Select":
return new FindMethodReferences(method, typeof(QuerySelectClause)); specialNodeType = typeof(QuerySelectClause);
break;
case "SelectMany": case "SelectMany":
return new FindMethodReferences(method, typeof(QueryFromClause)); specialNodeType = typeof(QueryFromClause);
break;
case "Join": case "Join":
case "GroupJoin": case "GroupJoin":
return new FindMethodReferences(method, typeof(QueryJoinClause)); specialNodeType = typeof(QueryJoinClause);
break;
case "OrderBy": case "OrderBy":
case "OrderByDescending": case "OrderByDescending":
case "ThenBy": case "ThenBy":
case "ThenByDescending": case "ThenByDescending":
return new FindMethodReferences(method, typeof(QueryOrdering)); specialNodeType = typeof(QueryOrdering);
break;
case "GroupBy": case "GroupBy":
return new FindMethodReferences(method, typeof(QueryGroupClause)); specialNodeType = typeof(QueryGroupClause);
break;
case "Invoke": case "Invoke":
if (method.DeclaringTypeDefinition != null && method.DeclaringTypeDefinition.Kind == TypeKind.Delegate) if (method.DeclaringTypeDefinition != null && method.DeclaringTypeDefinition.Kind == TypeKind.Delegate)
return new FindMethodReferences(method, typeof(InvocationExpression)); specialNodeType = typeof(InvocationExpression);
else else
return new FindMethodReferences(method); specialNodeType = null;
break;
default: default:
return new FindMethodReferences(method); specialNodeType = null;
break;
} }
// Use searchTerm only if specialNodeType==null
string searchTerm = (specialNodeType == null) ? method.Name : null;
return new SearchScope(
searchTerm,
delegate (ICompilation compilation) {
IMethod imported = compilation.Import(method);
if (imported != null)
return new FindMethodReferences(imported, specialNodeType);
else
return null;
});
} }
sealed class FindMethodReferences : SearchScope sealed class FindMethodReferences : FindReferenceNavigator
{ {
readonly IMethod method; readonly IMethod method;
readonly Type specialNodeType; readonly Type specialNodeType;
public FindMethodReferences(IMethod method, Type specialNodeType = null) public FindMethodReferences(IMethod method, Type specialNodeType)
{ {
this.method = (IMethod)method.MemberDefinition; this.method = method;
this.specialNodeType = specialNodeType; this.specialNodeType = specialNodeType;
if (specialNodeType == null)
this.searchTerm = method.Name;
} }
internal override bool CanMatch(AstNode node) internal override bool CanMatch(AstNode node)
@ -549,13 +619,26 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#endregion #endregion
#region Find Indexer References #region Find Indexer References
sealed class FindIndexerReferences : SearchScope SearchScope FindIndexerReferences(IProperty indexer)
{
indexer = (IProperty)indexer.MemberDefinition;
return new SearchScope(
delegate (ICompilation compilation) {
IProperty imported = compilation.Import(indexer);
if (imported != null)
return new FindIndexerReferencesNavigator(imported);
else
return null;
});
}
sealed class FindIndexerReferencesNavigator : FindReferenceNavigator
{ {
readonly IProperty indexer; readonly IProperty indexer;
public FindIndexerReferences(IProperty indexer) public FindIndexerReferencesNavigator(IProperty indexer)
{ {
this.indexer = (IProperty)indexer.MemberDefinition; this.indexer = indexer;
} }
internal override bool CanMatch(AstNode node) internal override bool CanMatch(AstNode node)
@ -576,73 +659,88 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{ {
OperatorType? opType = OperatorDeclaration.GetOperatorType(op.Name); OperatorType? opType = OperatorDeclaration.GetOperatorType(op.Name);
if (opType == null) if (opType == null)
return new FindMethodReferences(op); return GetSearchScopeForMethod(op);
switch (opType.Value) { switch (opType.Value) {
case OperatorType.LogicalNot: case OperatorType.LogicalNot:
return new FindUnaryOperator(op, UnaryOperatorType.Not); return FindUnaryOperator(op, UnaryOperatorType.Not);
case OperatorType.OnesComplement: case OperatorType.OnesComplement:
return new FindUnaryOperator(op, UnaryOperatorType.BitNot); return FindUnaryOperator(op, UnaryOperatorType.BitNot);
case OperatorType.UnaryPlus: case OperatorType.UnaryPlus:
return new FindUnaryOperator(op, UnaryOperatorType.Plus); return FindUnaryOperator(op, UnaryOperatorType.Plus);
case OperatorType.UnaryNegation: case OperatorType.UnaryNegation:
return new FindUnaryOperator(op, UnaryOperatorType.Minus); return FindUnaryOperator(op, UnaryOperatorType.Minus);
case OperatorType.Increment: case OperatorType.Increment:
return new FindUnaryOperator(op, UnaryOperatorType.Increment); return FindUnaryOperator(op, UnaryOperatorType.Increment);
case OperatorType.Decrement: case OperatorType.Decrement:
return new FindUnaryOperator(op, UnaryOperatorType.Decrement); return FindUnaryOperator(op, UnaryOperatorType.Decrement);
case OperatorType.True: case OperatorType.True:
case OperatorType.False: case OperatorType.False:
// TODO: implement search for op_True/op_False correctly // TODO: implement search for op_True/op_False correctly
return new FindMethodReferences(op); return GetSearchScopeForMethod(op);
case OperatorType.Addition: case OperatorType.Addition:
return new FindBinaryOperator(op, BinaryOperatorType.Add); return FindBinaryOperator(op, BinaryOperatorType.Add);
case OperatorType.Subtraction: case OperatorType.Subtraction:
return new FindBinaryOperator(op, BinaryOperatorType.Subtract); return FindBinaryOperator(op, BinaryOperatorType.Subtract);
case OperatorType.Multiply: case OperatorType.Multiply:
return new FindBinaryOperator(op, BinaryOperatorType.Multiply); return FindBinaryOperator(op, BinaryOperatorType.Multiply);
case OperatorType.Division: case OperatorType.Division:
return new FindBinaryOperator(op, BinaryOperatorType.Divide); return FindBinaryOperator(op, BinaryOperatorType.Divide);
case OperatorType.Modulus: case OperatorType.Modulus:
return new FindBinaryOperator(op, BinaryOperatorType.Modulus); return FindBinaryOperator(op, BinaryOperatorType.Modulus);
case OperatorType.BitwiseAnd: case OperatorType.BitwiseAnd:
// TODO: an overloaded bitwise operator can also be called using the corresponding logical operator // TODO: an overloaded bitwise operator can also be called using the corresponding logical operator
// (if op_True/op_False is defined) // (if op_True/op_False is defined)
return new FindBinaryOperator(op, BinaryOperatorType.BitwiseAnd); return FindBinaryOperator(op, BinaryOperatorType.BitwiseAnd);
case OperatorType.BitwiseOr: case OperatorType.BitwiseOr:
return new FindBinaryOperator(op, BinaryOperatorType.BitwiseOr); return FindBinaryOperator(op, BinaryOperatorType.BitwiseOr);
case OperatorType.ExclusiveOr: case OperatorType.ExclusiveOr:
return new FindBinaryOperator(op, BinaryOperatorType.ExclusiveOr); return FindBinaryOperator(op, BinaryOperatorType.ExclusiveOr);
case OperatorType.LeftShift: case OperatorType.LeftShift:
return new FindBinaryOperator(op, BinaryOperatorType.ShiftLeft); return FindBinaryOperator(op, BinaryOperatorType.ShiftLeft);
case OperatorType.RightShift: case OperatorType.RightShift:
return new FindBinaryOperator(op, BinaryOperatorType.ShiftRight); return FindBinaryOperator(op, BinaryOperatorType.ShiftRight);
case OperatorType.Equality: case OperatorType.Equality:
return new FindBinaryOperator(op, BinaryOperatorType.Equality); return FindBinaryOperator(op, BinaryOperatorType.Equality);
case OperatorType.Inequality: case OperatorType.Inequality:
return new FindBinaryOperator(op, BinaryOperatorType.InEquality); return FindBinaryOperator(op, BinaryOperatorType.InEquality);
case OperatorType.GreaterThan: case OperatorType.GreaterThan:
return new FindBinaryOperator(op, BinaryOperatorType.GreaterThan); return FindBinaryOperator(op, BinaryOperatorType.GreaterThan);
case OperatorType.LessThan: case OperatorType.LessThan:
return new FindBinaryOperator(op, BinaryOperatorType.LessThan); return FindBinaryOperator(op, BinaryOperatorType.LessThan);
case OperatorType.GreaterThanOrEqual: case OperatorType.GreaterThanOrEqual:
return new FindBinaryOperator(op, BinaryOperatorType.GreaterThanOrEqual); return FindBinaryOperator(op, BinaryOperatorType.GreaterThanOrEqual);
case OperatorType.LessThanOrEqual: case OperatorType.LessThanOrEqual:
return new FindBinaryOperator(op, BinaryOperatorType.LessThanOrEqual); return FindBinaryOperator(op, BinaryOperatorType.LessThanOrEqual);
case OperatorType.Implicit: case OperatorType.Implicit:
return new FindImplicitOperator(op); return FindOperator(op, m => new FindImplicitOperatorNavigator(m));
case OperatorType.Explicit: case OperatorType.Explicit:
return new FindExplicitOperator(op); return FindOperator(op, m => new FindExplicitOperatorNavigator(m));
default: default:
throw new InvalidOperationException("Invalid value for OperatorType"); throw new InvalidOperationException("Invalid value for OperatorType");
} }
} }
sealed class FindUnaryOperator : SearchScope SearchScope FindOperator(IMethod op, Func<IMethod, FindReferenceNavigator> factory)
{
op = (IMethod)op.MemberDefinition;
return new SearchScope(
delegate (ICompilation compilation) {
IMethod imported = compilation.Import(op);
return imported != null ? factory(imported) : null;
});
}
SearchScope FindUnaryOperator(IMethod op, UnaryOperatorType operatorType)
{
return FindOperator(op, m => new FindUnaryOperatorNavigator(m, operatorType));
}
sealed class FindUnaryOperatorNavigator : FindReferenceNavigator
{ {
readonly IMethod op; readonly IMethod op;
readonly UnaryOperatorType operatorType; readonly UnaryOperatorType operatorType;
public FindUnaryOperator(IMethod op, UnaryOperatorType operatorType) public FindUnaryOperatorNavigator(IMethod op, UnaryOperatorType operatorType)
{ {
this.op = op; this.op = op;
this.operatorType = operatorType; this.operatorType = operatorType;
@ -669,12 +767,17 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
} }
sealed class FindBinaryOperator : SearchScope SearchScope FindBinaryOperator(IMethod op, BinaryOperatorType operatorType)
{
return FindOperator(op, m => new FindBinaryOperatorNavigator(m, operatorType));
}
sealed class FindBinaryOperatorNavigator : FindReferenceNavigator
{ {
readonly IMethod op; readonly IMethod op;
readonly BinaryOperatorType operatorType; readonly BinaryOperatorType operatorType;
public FindBinaryOperator(IMethod op, BinaryOperatorType operatorType) public FindBinaryOperatorNavigator(IMethod op, BinaryOperatorType operatorType)
{ {
this.op = op; this.op = op;
this.operatorType = operatorType; this.operatorType = operatorType;
@ -696,11 +799,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
} }
sealed class FindImplicitOperator : SearchScope sealed class FindImplicitOperatorNavigator : FindReferenceNavigator
{ {
readonly IMethod op; readonly IMethod op;
public FindImplicitOperator(IMethod op) public FindImplicitOperatorNavigator(IMethod op)
{ {
this.op = op; this.op = op;
} }
@ -716,7 +819,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return mrr != null && op == mrr.Member.MemberDefinition; return mrr != null && op == mrr.Member.MemberDefinition;
} }
internal override void ProcessConversion(Expression expression, ResolveResult result, Conversion conversion, IType targetType) public override void ProcessConversion(Expression expression, ResolveResult result, Conversion conversion, IType targetType)
{ {
if (conversion.IsUserDefined && conversion.Method.MemberDefinition == op) { if (conversion.IsUserDefined && conversion.Method.MemberDefinition == op) {
ReportMatch(expression, result); ReportMatch(expression, result);
@ -724,11 +827,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
} }
sealed class FindExplicitOperator : SearchScope sealed class FindExplicitOperatorNavigator : FindReferenceNavigator
{ {
readonly IMethod op; readonly IMethod op;
public FindExplicitOperator(IMethod op) public FindExplicitOperatorNavigator(IMethod op)
{ {
this.op = op; this.op = op;
} }
@ -747,17 +850,32 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#endregion #endregion
#region Find Constructor References #region Find Constructor References
sealed class FindObjectCreateReferences : SearchScope SearchScope FindObjectCreateReferences(IMethod ctor)
{
ctor = (IMethod)ctor.MemberDefinition;
string searchTerm = null;
if (ReflectionHelper.GetTypeCode(ctor.DeclaringTypeDefinition) == TypeCode.Empty) {
// not a built-in type
searchTerm = ctor.DeclaringTypeDefinition.Name;
}
return new SearchScope(
searchTerm,
delegate (ICompilation compilation) {
IMethod imported = compilation.Import(ctor);
if (imported != null)
return new FindObjectCreateReferencesNavigator(ctor);
else
return null;
});
}
sealed class FindObjectCreateReferencesNavigator : FindReferenceNavigator
{ {
readonly IMethod ctor; readonly IMethod ctor;
public FindObjectCreateReferences(IMethod ctor) public FindObjectCreateReferencesNavigator(IMethod ctor)
{ {
this.ctor = (IMethod)ctor.MemberDefinition; this.ctor = ctor;
if (ReflectionHelper.GetTypeCode(ctor.DeclaringTypeDefinition) == TypeCode.Empty) {
// not a built-in type
this.searchTerm = ctor.DeclaringTypeDefinition.Name;
}
} }
internal override bool CanMatch(AstNode node) internal override bool CanMatch(AstNode node)
@ -772,18 +890,32 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
} }
sealed class FindChainedConstructorReferences : SearchScope SearchScope FindChainedConstructorReferences(IMethod ctor)
{
ctor = (IMethod)ctor.MemberDefinition;
SearchScope searchScope = new SearchScope(
delegate (ICompilation compilation) {
IMethod imported = compilation.Import(ctor);
if (imported != null)
return new FindChainedConstructorReferencesNavigator(imported);
else
return null;
});
if (ctor.DeclaringTypeDefinition.IsSealed)
searchScope.accessibility = Accessibility.Private;
else
searchScope.accessibility = Accessibility.Protected;
searchScope.accessibility = MergeAccessibility(GetEffectiveAccessibility(ctor), searchScope.accessibility);
return searchScope;
}
sealed class FindChainedConstructorReferencesNavigator : FindReferenceNavigator
{ {
readonly IMethod ctor; readonly IMethod ctor;
public FindChainedConstructorReferences(IMethod ctor) public FindChainedConstructorReferencesNavigator(IMethod ctor)
{ {
this.ctor = (IMethod)ctor.MemberDefinition; this.ctor = ctor;
if (ctor.DeclaringTypeDefinition.IsSealed)
this.accessibility = Accessibility.Private;
else
this.accessibility = Accessibility.Protected;
this.accessibility = MergeAccessibility(GetEffectiveAccessibility(ctor), this.accessibility);
} }
internal override bool CanMatch(AstNode node) internal override bool CanMatch(AstNode node)
@ -814,12 +946,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{ {
if (variable == null) if (variable == null)
throw new ArgumentNullException("variable"); throw new ArgumentNullException("variable");
var navigator = new FindLocalReferencesNavigator(variable); var searchScope = new SearchScope(c => new FindLocalReferencesNavigator(variable));
navigator.compilation = compilation; searchScope.declarationCompilation = compilation;
FindReferencesInFile(navigator, parsedFile, compilationUnit, callback, cancellationToken); FindReferencesInFile(searchScope, parsedFile, compilationUnit, compilation, callback, cancellationToken);
} }
class FindLocalReferencesNavigator : SearchScope class FindLocalReferencesNavigator : FindReferenceNavigator
{ {
readonly IVariable variable; readonly IVariable variable;

21
ICSharpCode.NRefactory.CSharp/Resolver/Log.cs

@ -36,20 +36,31 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
static class Log static class Log
{ {
const bool logEnabled = false; const bool logEnabled = false;
#if __MonoCS__
[Conditional("DEBUG")]
#else
[Conditional(logEnabled ? "DEBUG" : "LOG_DISABLED")] [Conditional(logEnabled ? "DEBUG" : "LOG_DISABLED")]
#endif
internal static void WriteLine(string text) internal static void WriteLine(string text)
{ {
Debug.WriteLine(text); Debug.WriteLine(text);
} }
#if __MonoCS__
[Conditional("DEBUG")]
#else
[Conditional(logEnabled ? "DEBUG" : "LOG_DISABLED")] [Conditional(logEnabled ? "DEBUG" : "LOG_DISABLED")]
#endif
internal static void WriteLine(string format, params object[] args) internal static void WriteLine(string format, params object[] args)
{ {
Debug.WriteLine(format, args); Debug.WriteLine(format, args);
} }
#if __MonoCS__
[Conditional("DEBUG")]
#else
[Conditional(logEnabled ? "DEBUG" : "LOG_DISABLED")] [Conditional(logEnabled ? "DEBUG" : "LOG_DISABLED")]
#endif
internal static void WriteCollection<T>(string text, IEnumerable<T> lines) internal static void WriteCollection<T>(string text, IEnumerable<T> lines)
{ {
#if DEBUG #if DEBUG
@ -65,13 +76,21 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#endif #endif
} }
#if __MonoCS__
[Conditional("DEBUG")]
#else
[Conditional(logEnabled ? "DEBUG" : "LOG_DISABLED")] [Conditional(logEnabled ? "DEBUG" : "LOG_DISABLED")]
#endif
public static void Indent() public static void Indent()
{ {
Debug.Indent(); Debug.Indent();
} }
#if __MonoCS__
[Conditional("DEBUG")]
#else
[Conditional(logEnabled ? "DEBUG" : "LOG_DISABLED")] [Conditional(logEnabled ? "DEBUG" : "LOG_DISABLED")]
#endif
public static void Unindent() public static void Unindent()
{ {
Debug.Unindent(); Debug.Unindent();

4
ICSharpCode.NRefactory.CSharp/Resolver/ResolveAtLocation.cs

@ -58,6 +58,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return null; return null;
} }
if (resolvableNode != null && resolvableNode.Parent is ObjectCreateExpression) {
resolvableNode = resolvableNode.Parent;
}
InvocationExpression parentInvocation = null; InvocationExpression parentInvocation = null;
if ((resolvableNode is IdentifierExpression || resolvableNode is MemberReferenceExpression || resolvableNode is PointerReferenceExpression)) { if ((resolvableNode is IdentifierExpression || resolvableNode is MemberReferenceExpression || resolvableNode is PointerReferenceExpression)) {
// we also need to resolve the invocation // we also need to resolve the invocation

202
ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs

@ -97,7 +97,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{ {
if (resolver == null) if (resolver == null)
throw new ArgumentNullException("resolver"); throw new ArgumentNullException("resolver");
this.resolver = resolver.Clone(); this.resolver = resolver;
this.parsedFile = parsedFile; this.parsedFile = parsedFile;
this.navigator = navigator ?? new ConstantModeResolveVisitorNavigator(ResolveVisitorNavigationMode.Skip, null); this.navigator = navigator ?? new ConstantModeResolveVisitorNavigator(ResolveVisitorNavigationMode.Skip, null);
this.voidResult = new ResolveResult(resolver.Compilation.FindType(KnownTypeCode.Void)); this.voidResult = new ResolveResult(resolver.Compilation.FindType(KnownTypeCode.Void));
@ -219,7 +219,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{ {
// It's possible that we re-visit an expression that we scanned over earlier, // It's possible that we re-visit an expression that we scanned over earlier,
// so we might have to overwrite an existing state. // so we might have to overwrite an existing state.
resolverBeforeDict[node] = resolver.Clone(); resolverBeforeDict[node] = resolver;
} }
void StoreResult(AstNode node, ResolveResult result) void StoreResult(AstNode node, ResolveResult result)
@ -383,7 +383,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
AstNode parent; AstNode parent;
CSharpResolver storedResolver = GetPreviouslyScannedContext(nodeToResolve, out parent); CSharpResolver storedResolver = GetPreviouslyScannedContext(nodeToResolve, out parent);
ResetContext( ResetContext(
storedResolver.Clone(), storedResolver,
delegate { delegate {
navigator = new NodeListResolveVisitorNavigator(node, nodeToResolve); navigator = new NodeListResolveVisitorNavigator(node, nodeToResolve);
if (parent == nodeToResolve) { if (parent == nodeToResolve) {
@ -442,7 +442,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
AstNode parent; AstNode parent;
CSharpResolver storedResolver = GetPreviouslyScannedContext(node, out parent); CSharpResolver storedResolver = GetPreviouslyScannedContext(node, out parent);
ResetContext( ResetContext(
storedResolver.Clone(), storedResolver,
delegate { delegate {
navigator = new NodeListResolveVisitorNavigator(new[] { node }, scanOnly: true); navigator = new NodeListResolveVisitorNavigator(new[] { node }, scanOnly: true);
Debug.Assert(!resolverEnabled); Debug.Assert(!resolverEnabled);
@ -462,23 +462,23 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#region Track UsingScope #region Track UsingScope
ResolveResult IAstVisitor<object, ResolveResult>.VisitCompilationUnit(CompilationUnit unit, object data) ResolveResult IAstVisitor<object, ResolveResult>.VisitCompilationUnit(CompilationUnit unit, object data)
{ {
ResolvedUsingScope previousUsingScope = resolver.CurrentUsingScope; CSharpResolver previousResolver = resolver;
try { try {
if (parsedFile != null) if (parsedFile != null)
resolver.CurrentUsingScope = parsedFile.RootUsingScope.Resolve(resolver.Compilation); resolver = resolver.WithCurrentUsingScope(parsedFile.RootUsingScope.Resolve(resolver.Compilation));
ScanChildren(unit); ScanChildren(unit);
return voidResult; return voidResult;
} finally { } finally {
resolver.CurrentUsingScope = previousUsingScope; resolver = previousResolver;
} }
} }
ResolveResult IAstVisitor<object, ResolveResult>.VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration, object data) ResolveResult IAstVisitor<object, ResolveResult>.VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration, object data)
{ {
ResolvedUsingScope previousUsingScope = resolver.CurrentUsingScope; CSharpResolver previousResolver = resolver;
try { try {
if (parsedFile != null) { if (parsedFile != null) {
resolver.CurrentUsingScope = parsedFile.GetUsingScope(namespaceDeclaration.StartLocation).Resolve(resolver.Compilation); resolver = resolver.WithCurrentUsingScope(parsedFile.GetUsingScope(namespaceDeclaration.StartLocation).Resolve(resolver.Compilation));
} }
ScanChildren(namespaceDeclaration); ScanChildren(namespaceDeclaration);
// merge undecided lambdas before leaving the using scope so that // merge undecided lambdas before leaving the using scope so that
@ -489,7 +489,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
else else
return null; return null;
} finally { } finally {
resolver.CurrentUsingScope = previousUsingScope; resolver = previousResolver;
} }
} }
#endregion #endregion
@ -497,7 +497,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#region Track CurrentTypeDefinition #region Track CurrentTypeDefinition
ResolveResult VisitTypeOrDelegate(AstNode typeDeclaration, string name, int typeParameterCount) ResolveResult VisitTypeOrDelegate(AstNode typeDeclaration, string name, int typeParameterCount)
{ {
ITypeDefinition previousTypeDefinition = resolver.CurrentTypeDefinition; CSharpResolver previousResolver = resolver;
try { try {
ITypeDefinition newTypeDefinition = null; ITypeDefinition newTypeDefinition = null;
if (resolver.CurrentTypeDefinition != null) { if (resolver.CurrentTypeDefinition != null) {
@ -512,7 +512,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
newTypeDefinition = resolver.CurrentUsingScope.Namespace.GetTypeDefinition(name, typeParameterCount); newTypeDefinition = resolver.CurrentUsingScope.Namespace.GetTypeDefinition(name, typeParameterCount);
} }
if (newTypeDefinition != null) if (newTypeDefinition != null)
resolver.CurrentTypeDefinition = newTypeDefinition; resolver = resolver.WithCurrentTypeDefinition(newTypeDefinition);
for (AstNode child = typeDeclaration.FirstChild; child != null; child = child.NextSibling) { for (AstNode child = typeDeclaration.FirstChild; child != null; child = child.NextSibling) {
if (child.Role == TypeDeclaration.BaseTypeRole) { if (child.Role == TypeDeclaration.BaseTypeRole) {
@ -530,7 +530,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return newTypeDefinition != null ? new TypeResolveResult(newTypeDefinition) : errorResult; return newTypeDefinition != null ? new TypeResolveResult(newTypeDefinition) : errorResult;
} finally { } finally {
resolver.CurrentTypeDefinition = previousTypeDefinition; resolver = previousResolver;
} }
} }
@ -564,13 +564,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult VisitFieldOrEventDeclaration(AttributedNode fieldOrEventDeclaration) ResolveResult VisitFieldOrEventDeclaration(AttributedNode fieldOrEventDeclaration)
{ {
//int initializerCount = fieldOrEventDeclaration.GetChildrenByRole(FieldDeclaration.Roles.Variable).Count; //int initializerCount = fieldOrEventDeclaration.GetChildrenByRole(FieldDeclaration.Roles.Variable).Count;
CSharpResolver oldResolver = resolver;
for (AstNode node = fieldOrEventDeclaration.FirstChild; node != null; node = node.NextSibling) { for (AstNode node = fieldOrEventDeclaration.FirstChild; node != null; node = node.NextSibling) {
if (node.Role == FieldDeclaration.Roles.Variable) { if (node.Role == FieldDeclaration.Roles.Variable) {
resolver.CurrentMember = GetMemberFromLocation(node.StartLocation); resolver = resolver.WithCurrentMember(GetMemberFromLocation(node.StartLocation));
Scan(node); Scan(node);
resolver.CurrentMember = null; resolver = oldResolver;
} else { } else {
Scan(node); Scan(node);
} }
@ -643,8 +644,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult VisitMethodMember(AttributedNode member) ResolveResult VisitMethodMember(AttributedNode member)
{ {
CSharpResolver oldResolver = resolver;
try { try {
resolver.CurrentMember = GetMemberFromLocation(member.StartLocation); resolver = resolver.WithCurrentMember(GetMemberFromLocation(member.StartLocation));
ScanChildren(member); ScanChildren(member);
@ -653,7 +655,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
else else
return errorResult; return errorResult;
} finally { } finally {
resolver.CurrentMember = null; resolver = oldResolver;
} }
} }
@ -680,15 +682,16 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// handle properties/indexers // handle properties/indexers
ResolveResult VisitPropertyMember(MemberDeclaration propertyOrIndexerDeclaration) ResolveResult VisitPropertyMember(MemberDeclaration propertyOrIndexerDeclaration)
{ {
CSharpResolver oldResolver = resolver;
try { try {
resolver.CurrentMember = GetMemberFromLocation(propertyOrIndexerDeclaration.StartLocation); resolver = resolver.WithCurrentMember(GetMemberFromLocation(propertyOrIndexerDeclaration.StartLocation));
for (AstNode node = propertyOrIndexerDeclaration.FirstChild; node != null; node = node.NextSibling) { for (AstNode node = propertyOrIndexerDeclaration.FirstChild; node != null; node = node.NextSibling) {
if (node.Role == PropertyDeclaration.SetterRole && resolver.CurrentMember != null) { if (node.Role == PropertyDeclaration.SetterRole && resolver.CurrentMember != null) {
resolver.PushBlock(); resolver = resolver.PushBlock();
resolver.AddVariable(new DefaultParameter(resolver.CurrentMember.ReturnType, "value")); resolver = resolver.AddVariable(new DefaultParameter(resolver.CurrentMember.ReturnType, "value"));
Scan(node); Scan(node);
resolver.PopBlock(); resolver = resolver.PopBlock();
} else { } else {
Scan(node); Scan(node);
} }
@ -698,7 +701,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
else else
return errorResult; return errorResult;
} finally { } finally {
resolver.CurrentMember = null; resolver = oldResolver;
} }
} }
@ -714,14 +717,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult IAstVisitor<object, ResolveResult>.VisitCustomEventDeclaration(CustomEventDeclaration eventDeclaration, object data) ResolveResult IAstVisitor<object, ResolveResult>.VisitCustomEventDeclaration(CustomEventDeclaration eventDeclaration, object data)
{ {
CSharpResolver oldResolver = resolver;
try { try {
resolver.CurrentMember = GetMemberFromLocation(eventDeclaration.StartLocation); resolver = resolver.WithCurrentMember(GetMemberFromLocation(eventDeclaration.StartLocation));
if (resolver.CurrentMember != null) { if (resolver.CurrentMember != null) {
resolver.PushBlock(); resolver = resolver.PushBlock();
resolver.AddVariable(new DefaultParameter(resolver.CurrentMember.ReturnType, "value")); resolver = resolver.AddVariable(new DefaultParameter(resolver.CurrentMember.ReturnType, "value"));
ScanChildren(eventDeclaration); ScanChildren(eventDeclaration);
resolver.PopBlock();
} else { } else {
ScanChildren(eventDeclaration); ScanChildren(eventDeclaration);
} }
@ -731,7 +734,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
else else
return errorResult; return errorResult;
} finally { } finally {
resolver.CurrentMember = null; resolver = oldResolver;
} }
} }
@ -794,6 +797,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult IAstVisitor<object, ResolveResult>.VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration, object data) ResolveResult IAstVisitor<object, ResolveResult>.VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration, object data)
{ {
CSharpResolver oldResolver = resolver;
try { try {
// Scan enum member attributes before setting resolver.CurrentMember, so that // Scan enum member attributes before setting resolver.CurrentMember, so that
// enum values used as attribute arguments have the correct type. // enum values used as attribute arguments have the correct type.
@ -801,7 +805,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
foreach (var attributeSection in enumMemberDeclaration.Attributes) foreach (var attributeSection in enumMemberDeclaration.Attributes)
Scan(attributeSection); Scan(attributeSection);
resolver.CurrentMember = GetMemberFromLocation(enumMemberDeclaration.StartLocation); resolver = resolver.WithCurrentMember(GetMemberFromLocation(enumMemberDeclaration.StartLocation));
if (resolverEnabled && resolver.CurrentTypeDefinition != null) { if (resolverEnabled && resolver.CurrentTypeDefinition != null) {
ResolveAndProcessConversion(enumMemberDeclaration.Initializer, resolver.CurrentTypeDefinition.EnumUnderlyingType); ResolveAndProcessConversion(enumMemberDeclaration.Initializer, resolver.CurrentTypeDefinition.EnumUnderlyingType);
@ -814,7 +818,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return errorResult; return errorResult;
} }
} finally { } finally {
resolver.CurrentMember = null; resolver = oldResolver;
} }
} }
#endregion #endregion
@ -822,9 +826,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#region Track CheckForOverflow #region Track CheckForOverflow
ResolveResult IAstVisitor<object, ResolveResult>.VisitCheckedExpression(CheckedExpression checkedExpression, object data) ResolveResult IAstVisitor<object, ResolveResult>.VisitCheckedExpression(CheckedExpression checkedExpression, object data)
{ {
bool oldCheckForOverflow = resolver.CheckForOverflow; CSharpResolver oldResolver = resolver;
try { try {
resolver.CheckForOverflow = true; resolver = resolver.WithCheckForOverflow(true);
if (resolverEnabled) { if (resolverEnabled) {
return Resolve(checkedExpression.Expression); return Resolve(checkedExpression.Expression);
} else { } else {
@ -832,15 +836,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return null; return null;
} }
} finally { } finally {
resolver.CheckForOverflow = oldCheckForOverflow; resolver = oldResolver;
} }
} }
ResolveResult IAstVisitor<object, ResolveResult>.VisitUncheckedExpression(UncheckedExpression uncheckedExpression, object data) ResolveResult IAstVisitor<object, ResolveResult>.VisitUncheckedExpression(UncheckedExpression uncheckedExpression, object data)
{ {
bool oldCheckForOverflow = resolver.CheckForOverflow; CSharpResolver oldResolver = resolver;
try { try {
resolver.CheckForOverflow = false; resolver = resolver.WithCheckForOverflow(false);
if (resolverEnabled) { if (resolverEnabled) {
return Resolve(uncheckedExpression.Expression); return Resolve(uncheckedExpression.Expression);
} else { } else {
@ -848,31 +852,31 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return null; return null;
} }
} finally { } finally {
resolver.CheckForOverflow = oldCheckForOverflow; resolver = oldResolver;
} }
} }
ResolveResult IAstVisitor<object, ResolveResult>.VisitCheckedStatement(CheckedStatement checkedStatement, object data) ResolveResult IAstVisitor<object, ResolveResult>.VisitCheckedStatement(CheckedStatement checkedStatement, object data)
{ {
bool oldCheckForOverflow = resolver.CheckForOverflow; CSharpResolver oldResolver = resolver;
try { try {
resolver.CheckForOverflow = true; resolver = resolver.WithCheckForOverflow(true);
ScanChildren(checkedStatement); ScanChildren(checkedStatement);
return voidResult; return voidResult;
} finally { } finally {
resolver.CheckForOverflow = oldCheckForOverflow; resolver = oldResolver;
} }
} }
ResolveResult IAstVisitor<object, ResolveResult>.VisitUncheckedStatement(UncheckedStatement uncheckedStatement, object data) ResolveResult IAstVisitor<object, ResolveResult>.VisitUncheckedStatement(UncheckedStatement uncheckedStatement, object data)
{ {
bool oldCheckForOverflow = resolver.CheckForOverflow; CSharpResolver oldResolver = resolver;
try { try {
resolver.CheckForOverflow = false; resolver = resolver.WithCheckForOverflow(false);
ScanChildren(uncheckedStatement); ScanChildren(uncheckedStatement);
return voidResult; return voidResult;
} finally { } finally {
resolver.CheckForOverflow = oldCheckForOverflow; resolver = oldResolver;
} }
} }
#endregion #endregion
@ -910,7 +914,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
var property = new DefaultUnresolvedProperty { var property = new DefaultUnresolvedProperty {
Name = name, Name = name,
Accessibility = Accessibility.Public, Accessibility = Accessibility.Public,
ReturnType = new VarTypeReference(this, resolver.Clone(), resolveExpr), ReturnType = new VarTypeReference(this, resolver, resolveExpr),
Getter = DefaultUnresolvedAccessor.GetFromAccessibility(Accessibility.Public) Getter = DefaultUnresolvedAccessor.GetFromAccessibility(Accessibility.Public)
}; };
properties.Add(property); properties.Add(property);
@ -1261,7 +1265,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
void HandleObjectInitializer(IType type, ArrayInitializerExpression initializer) void HandleObjectInitializer(IType type, ArrayInitializerExpression initializer)
{ {
StoreCurrentState(initializer); StoreCurrentState(initializer);
resolver.PushInitializerType(type); resolver = resolver.PushInitializerType(type);
foreach (Expression element in initializer.Elements) { foreach (Expression element in initializer.Elements) {
ArrayInitializerExpression aie = element as ArrayInitializerExpression; ArrayInitializerExpression aie = element as ArrayInitializerExpression;
if (aie != null) { if (aie != null) {
@ -1294,7 +1298,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
Scan(element); Scan(element);
} }
} }
resolver.PopInitializerType(); resolver = resolver.PopInitializerType();
if (!resolveResultCache.ContainsKey(initializer)) if (!resolveResultCache.ContainsKey(initializer))
StoreResult(initializer, voidResult); StoreResult(initializer, voidResult);
} }
@ -1390,6 +1394,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (resolverEnabled) { if (resolverEnabled) {
Expression expr = unaryOperatorExpression.Expression; Expression expr = unaryOperatorExpression.Expression;
ResolveResult input = Resolve(expr); ResolveResult input = Resolve(expr);
ITypeDefinition inputTypeDef = input.Type.GetDefinition();
if (input.IsCompileTimeConstant && expr is PrimitiveExpression && inputTypeDef != null) {
// Special cases for int.MinValue and long.MinValue
if (inputTypeDef.KnownTypeCode == KnownTypeCode.UInt32 && 2147483648.Equals(input.ConstantValue)) {
return new ConstantResolveResult(resolver.Compilation.FindType(KnownTypeCode.Int32), -2147483648);
} else if (inputTypeDef.KnownTypeCode == KnownTypeCode.UInt64 && 9223372036854775808.Equals(input.ConstantValue)) {
return new ConstantResolveResult(resolver.Compilation.FindType(KnownTypeCode.Int64), -9223372036854775808);
}
}
ResolveResult rr = resolver.ResolveUnaryOperator(unaryOperatorExpression.Operator, input); ResolveResult rr = resolver.ResolveUnaryOperator(unaryOperatorExpression.Operator, input);
OperatorResolveResult uorr = rr as OperatorResolveResult; OperatorResolveResult uorr = rr as OperatorResolveResult;
if (uorr != null && uorr.Operands.Count == 1) { if (uorr != null && uorr.Operands.Count == 1) {
@ -1673,10 +1686,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
AstNodeCollection<ParameterDeclaration> parameterDeclarations, AstNodeCollection<ParameterDeclaration> parameterDeclarations,
AstNode body, bool isAnonymousMethod, bool hasParameterList, bool isAsync) AstNode body, bool isAnonymousMethod, bool hasParameterList, bool isAsync)
{ {
CSharpResolver oldResolver = resolver;
List<IParameter> parameters = (hasParameterList || parameterDeclarations.Any()) ? new List<IParameter>() : null; List<IParameter> parameters = (hasParameterList || parameterDeclarations.Any()) ? new List<IParameter>() : null;
resolver.PushBlock();
bool oldIsWithinLambdaExpression = resolver.IsWithinLambdaExpression; bool oldIsWithinLambdaExpression = resolver.IsWithinLambdaExpression;
resolver.IsWithinLambdaExpression = true; resolver = resolver.WithIsWithinLambdaExpression(true);
foreach (var pd in parameterDeclarations) { foreach (var pd in parameterDeclarations) {
IType type = ResolveType(pd.Type); IType type = ResolveType(pd.Type);
if (pd.ParameterModifier == ParameterModifier.Ref || pd.ParameterModifier == ParameterModifier.Out) if (pd.ParameterModifier == ParameterModifier.Ref || pd.ParameterModifier == ParameterModifier.Out)
@ -1685,17 +1698,16 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
IParameter p = new DefaultParameter(type, pd.Name, MakeRegion(pd), IParameter p = new DefaultParameter(type, pd.Name, MakeRegion(pd),
isRef: pd.ParameterModifier == ParameterModifier.Ref, isRef: pd.ParameterModifier == ParameterModifier.Ref,
isOut: pd.ParameterModifier == ParameterModifier.Out); isOut: pd.ParameterModifier == ParameterModifier.Out);
resolver.AddVariable(p); resolver = resolver.AddVariable(p);
parameters.Add(p); parameters.Add(p);
Scan(pd); Scan(pd);
} }
var lambda = new ExplicitlyTypedLambda(parameters, isAnonymousMethod, isAsync, resolver.Clone(), this, body); var lambda = new ExplicitlyTypedLambda(parameters, isAnonymousMethod, isAsync, resolver, this, body);
// Don't scan the lambda body here - we'll do that later when analyzing the ExplicitlyTypedLambda. // Don't scan the lambda body here - we'll do that later when analyzing the ExplicitlyTypedLambda.
resolver.PopBlock(); resolver = oldResolver;
resolver.IsWithinLambdaExpression = oldIsWithinLambdaExpression;
return lambda; return lambda;
} }
@ -1907,7 +1919,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
private ImplicitlyTypedLambda(ResolveVisitor parentVisitor) private ImplicitlyTypedLambda(ResolveVisitor parentVisitor)
{ {
this.parentVisitor = parentVisitor; this.parentVisitor = parentVisitor;
this.storedContext = parentVisitor.resolver.Clone(); this.storedContext = parentVisitor.resolver;
this.parsedFile = parentVisitor.parsedFile; this.parsedFile = parentVisitor.parsedFile;
this.bodyResult = parentVisitor.voidResult; this.bodyResult = parentVisitor.voidResult;
} }
@ -1976,7 +1988,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return h; return h;
} }
var resolveAll = new ConstantModeResolveVisitorNavigator(ResolveVisitorNavigationMode.Resolve, null); var resolveAll = new ConstantModeResolveVisitorNavigator(ResolveVisitorNavigationMode.Resolve, null);
ResolveVisitor visitor = new ResolveVisitor(storedContext.Clone(), parsedFile, resolveAll); ResolveVisitor visitor = new ResolveVisitor(storedContext, parsedFile, resolveAll);
var newHypothesis = new LambdaTypeHypothesis(this, parameterTypes, visitor, lambda != null ? lambda.Parameters : null); var newHypothesis = new LambdaTypeHypothesis(this, parameterTypes, visitor, lambda != null ? lambda.Parameters : null);
hypotheses.Add(newHypothesis); hypotheses.Add(newHypothesis);
return newHypothesis; return newHypothesis;
@ -2073,15 +2085,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
Log.WriteLine("Analyzing " + ToString() + "..."); Log.WriteLine("Analyzing " + ToString() + "...");
Log.Indent(); Log.Indent();
bool oldInsideLambda = visitor.resolver.IsWithinLambdaExpression; CSharpResolver oldResolver = visitor.resolver;
visitor.resolver.PushBlock(); visitor.resolver = visitor.resolver.WithIsWithinLambdaExpression(true);
visitor.resolver.IsWithinLambdaExpression = true;
lambdaParameters = new IParameter[parameterTypes.Length]; lambdaParameters = new IParameter[parameterTypes.Length];
if (parameterDeclarations != null) { if (parameterDeclarations != null) {
int i = 0; int i = 0;
foreach (var pd in parameterDeclarations) { foreach (var pd in parameterDeclarations) {
lambdaParameters[i] = new DefaultParameter(parameterTypes[i], pd.Name, visitor.MakeRegion(pd)); lambdaParameters[i] = new DefaultParameter(parameterTypes[i], pd.Name, visitor.MakeRegion(pd));
visitor.resolver.AddVariable(lambdaParameters[i]); visitor.resolver = visitor.resolver.AddVariable(lambdaParameters[i]);
i++; i++;
visitor.Scan(pd); visitor.Scan(pd);
} }
@ -2089,13 +2100,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
for (int i = 0; i < parameterTypes.Length; i++) { for (int i = 0; i < parameterTypes.Length; i++) {
var p = lambda.Parameters[i]; var p = lambda.Parameters[i];
lambdaParameters[i] = new DefaultParameter(parameterTypes[i], p.Name, p.Region); lambdaParameters[i] = new DefaultParameter(parameterTypes[i], p.Name, p.Region);
visitor.resolver.AddVariable(lambdaParameters[i]); visitor.resolver = visitor.resolver.AddVariable(lambdaParameters[i]);
} }
} }
visitor.AnalyzeLambda(lambda.BodyExpression, lambda.IsAsync, out success, out isValidAsVoidMethod, out inferredReturnType, out returnExpressions, out returnValues); visitor.AnalyzeLambda(lambda.BodyExpression, lambda.IsAsync, out success, out isValidAsVoidMethod, out inferredReturnType, out returnExpressions, out returnValues);
visitor.resolver.PopBlock(); visitor.resolver = oldResolver;
visitor.resolver.IsWithinLambdaExpression = false;
Log.Unindent(); Log.Unindent();
Log.WriteLine("Finished analyzing " + ToString()); Log.WriteLine("Finished analyzing " + ToString());
} }
@ -2200,7 +2210,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (parent != null && resolverBeforeDict.TryGetValue(parent, out storedResolver)) { if (parent != null && resolverBeforeDict.TryGetValue(parent, out storedResolver)) {
Log.WriteLine("Trying to resolve '" + parent + "' in order to merge the lambda..."); Log.WriteLine("Trying to resolve '" + parent + "' in order to merge the lambda...");
Log.Indent(); Log.Indent();
ResetContext(storedResolver.Clone(), delegate { Resolve(parent); }); ResetContext(storedResolver, delegate { Resolve(parent); });
Log.Unindent(); Log.Unindent();
} else { } else {
Log.WriteLine("Could not find a suitable parent for '" + lambda); Log.WriteLine("Could not find a suitable parent for '" + lambda);
@ -2392,15 +2402,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#region Local Variable Scopes (Block Statements) #region Local Variable Scopes (Block Statements)
ResolveResult IAstVisitor<object, ResolveResult>.VisitBlockStatement(BlockStatement blockStatement, object data) ResolveResult IAstVisitor<object, ResolveResult>.VisitBlockStatement(BlockStatement blockStatement, object data)
{ {
resolver.PushBlock(); resolver = resolver.PushBlock();
ScanChildren(blockStatement); ScanChildren(blockStatement);
resolver.PopBlock(); resolver = resolver.PopBlock();
return voidResult; return voidResult;
} }
ResolveResult IAstVisitor<object, ResolveResult>.VisitUsingStatement(UsingStatement usingStatement, object data) ResolveResult IAstVisitor<object, ResolveResult>.VisitUsingStatement(UsingStatement usingStatement, object data)
{ {
resolver.PushBlock(); resolver = resolver.PushBlock();
if (resolverEnabled) { if (resolverEnabled) {
for (AstNode child = usingStatement.FirstChild; child != null; child = child.NextSibling) { for (AstNode child = usingStatement.FirstChild; child != null; child = child.NextSibling) {
if (child.Role == UsingStatement.ResourceAcquisitionRole && child is Expression) { if (child.Role == UsingStatement.ResourceAcquisitionRole && child is Expression) {
@ -2412,28 +2422,28 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} else { } else {
ScanChildren(usingStatement); ScanChildren(usingStatement);
} }
resolver.PopBlock(); resolver = resolver.PopBlock();
return voidResult; return voidResult;
} }
ResolveResult IAstVisitor<object, ResolveResult>.VisitFixedStatement(FixedStatement fixedStatement, object data) ResolveResult IAstVisitor<object, ResolveResult>.VisitFixedStatement(FixedStatement fixedStatement, object data)
{ {
resolver.PushBlock(); resolver = resolver.PushBlock();
AstType type = fixedStatement.Type; AstType type = fixedStatement.Type;
for (AstNode node = fixedStatement.FirstChild; node != null; node = node.NextSibling) { for (AstNode node = fixedStatement.FirstChild; node != null; node = node.NextSibling) {
if (node.Role == FixedStatement.Roles.Variable) { if (node.Role == FixedStatement.Roles.Variable) {
VariableInitializer vi = (VariableInitializer)node; VariableInitializer vi = (VariableInitializer)node;
resolver.AddVariable(MakeVariable(type, vi.NameToken)); resolver = resolver.AddVariable(MakeVariable(type, vi.NameToken));
} }
Scan(node); Scan(node);
} }
resolver.PopBlock(); resolver = resolver.PopBlock();
return voidResult; return voidResult;
} }
ResolveResult IAstVisitor<object, ResolveResult>.VisitForeachStatement(ForeachStatement foreachStatement, object data) ResolveResult IAstVisitor<object, ResolveResult>.VisitForeachStatement(ForeachStatement foreachStatement, object data)
{ {
resolver.PushBlock(); resolver = resolver.PushBlock();
IVariable v; IVariable v;
if (IsVar(foreachStatement.VariableType)) { if (IsVar(foreachStatement.VariableType)) {
if (navigator.Scan(foreachStatement.VariableType) == ResolveVisitorNavigationMode.Resolve) { if (navigator.Scan(foreachStatement.VariableType) == ResolveVisitorNavigationMode.Resolve) {
@ -2451,33 +2461,33 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
v = MakeVariable(foreachStatement.VariableType, foreachStatement.VariableNameToken); v = MakeVariable(foreachStatement.VariableType, foreachStatement.VariableNameToken);
} }
StoreCurrentState(foreachStatement.VariableNameToken); StoreCurrentState(foreachStatement.VariableNameToken);
resolver.AddVariable(v); resolver = resolver.AddVariable(v);
StoreResult(foreachStatement.VariableNameToken, new LocalResolveResult(v)); StoreResult(foreachStatement.VariableNameToken, new LocalResolveResult(v));
Scan(foreachStatement.EmbeddedStatement); Scan(foreachStatement.EmbeddedStatement);
resolver.PopBlock(); resolver = resolver.PopBlock();
return voidResult; return voidResult;
} }
ResolveResult IAstVisitor<object, ResolveResult>.VisitSwitchStatement(SwitchStatement switchStatement, object data) ResolveResult IAstVisitor<object, ResolveResult>.VisitSwitchStatement(SwitchStatement switchStatement, object data)
{ {
resolver.PushBlock(); resolver = resolver.PushBlock();
ScanChildren(switchStatement); ScanChildren(switchStatement);
resolver.PopBlock(); resolver = resolver.PopBlock();
return voidResult; return voidResult;
} }
ResolveResult IAstVisitor<object, ResolveResult>.VisitCatchClause(CatchClause catchClause, object data) ResolveResult IAstVisitor<object, ResolveResult>.VisitCatchClause(CatchClause catchClause, object data)
{ {
resolver.PushBlock(); resolver = resolver.PushBlock();
if (!string.IsNullOrEmpty(catchClause.VariableName)) { if (!string.IsNullOrEmpty(catchClause.VariableName)) {
DomRegion region = MakeRegion(catchClause.VariableNameToken); DomRegion region = MakeRegion(catchClause.VariableNameToken);
StoreCurrentState(catchClause.VariableNameToken); StoreCurrentState(catchClause.VariableNameToken);
IVariable v = MakeVariable(catchClause.Type, catchClause.VariableNameToken); IVariable v = MakeVariable(catchClause.Type, catchClause.VariableNameToken);
resolver.AddVariable(v); resolver = resolver.AddVariable(v);
StoreResult(catchClause.VariableNameToken, new LocalResolveResult(v)); StoreResult(catchClause.VariableNameToken, new LocalResolveResult(v));
} }
ScanChildren(catchClause); ScanChildren(catchClause);
resolver.PopBlock(); resolver = resolver.PopBlock();
return voidResult; return voidResult;
} }
#endregion #endregion
@ -2504,7 +2514,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
v = MakeImplicitlyTypedVariable(vi.NameToken, vi.Initializer, false); v = MakeImplicitlyTypedVariable(vi.NameToken, vi.Initializer, false);
} }
StoreCurrentState(vi); StoreCurrentState(vi);
resolver.AddVariable(v); resolver = resolver.AddVariable(v);
if (needResolve) { if (needResolve) {
ResolveResult result; ResolveResult result;
if (!resolveResultCache.TryGetValue(vi, out result)) { if (!resolveResultCache.TryGetValue(vi, out result)) {
@ -2519,9 +2529,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
VariableInitializer vi = (VariableInitializer)node; VariableInitializer vi = (VariableInitializer)node;
if (isConst) { if (isConst) {
resolver.AddVariable(MakeConstant(type, vi.NameToken, vi.Initializer)); resolver = resolver.AddVariable(MakeConstant(type, vi.NameToken, vi.Initializer));
} else { } else {
resolver.AddVariable(MakeVariable(type, vi.NameToken)); resolver = resolver.AddVariable(MakeVariable(type, vi.NameToken));
} }
} }
Scan(node); Scan(node);
@ -2534,9 +2544,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#region Condition Statements #region Condition Statements
ResolveResult IAstVisitor<object, ResolveResult>.VisitForStatement(ForStatement forStatement, object data) ResolveResult IAstVisitor<object, ResolveResult>.VisitForStatement(ForStatement forStatement, object data)
{ {
resolver.PushBlock(); resolver = resolver.PushBlock();
HandleConditionStatement(forStatement); HandleConditionStatement(forStatement);
resolver.PopBlock(); resolver = resolver.PopBlock();
return voidResult; return voidResult;
} }
@ -2690,17 +2700,17 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
IVariable MakeVariable(AstType type, Identifier variableName) IVariable MakeVariable(AstType type, Identifier variableName)
{ {
return new ExplicitlyTypedVariable(this, resolver.Clone(), MakeRegion(variableName), type, variableName.Name, null); return new ExplicitlyTypedVariable(this, resolver, MakeRegion(variableName), type, variableName.Name, null);
} }
IVariable MakeConstant(AstType type, Identifier variableName, Expression initializer) IVariable MakeConstant(AstType type, Identifier variableName, Expression initializer)
{ {
return new ExplicitlyTypedVariable(this, resolver.Clone(), MakeRegion(variableName), type, variableName.Name, initializer); return new ExplicitlyTypedVariable(this, resolver, MakeRegion(variableName), type, variableName.Name, initializer);
} }
IVariable MakeImplicitlyTypedVariable(Identifier variableName, Expression initializer, bool isForEach) IVariable MakeImplicitlyTypedVariable(Identifier variableName, Expression initializer, bool isForEach)
{ {
return new ImplicitlyTypedVariable(this, resolver.Clone(), MakeRegion(variableName), variableName.Name, initializer, isForEach); return new ImplicitlyTypedVariable(this, resolver, MakeRegion(variableName), variableName.Name, initializer, isForEach);
} }
sealed class SimpleVariable : IVariable sealed class SimpleVariable : IVariable
@ -3005,10 +3015,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
var nonConstructorArguments = attribute.Arguments.Where(a => a is NamedExpression); var nonConstructorArguments = attribute.Arguments.Where(a => a is NamedExpression);
// Scan the non-constructor arguments // Scan the non-constructor arguments
resolver.PushInitializerType(type); resolver = resolver.PushInitializerType(type);
foreach (var arg in nonConstructorArguments) foreach (var arg in nonConstructorArguments)
Scan(arg); Scan(arg);
resolver.PopInitializerType(); resolver = resolver.PopInitializerType();
if (resolverEnabled) { if (resolverEnabled) {
// Resolve the ctor arguments and find the matching ctor overload // Resolve the ctor arguments and find the matching ctor overload
@ -3081,6 +3091,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
var typeArguments = GetTypeArguments(simpleType.TypeArguments); var typeArguments = GetTypeArguments(simpleType.TypeArguments);
Identifier identifier = simpleType.IdentifierToken; Identifier identifier = simpleType.IdentifierToken;
if (string.IsNullOrEmpty(identifier.Name))
return new TypeResolveResult(SpecialType.UnboundTypeArgument);
ResolveResult rr = resolver.LookupSimpleNameOrTypeName(identifier.Name, typeArguments, currentTypeLookupMode); ResolveResult rr = resolver.LookupSimpleNameOrTypeName(identifier.Name, typeArguments, currentTypeLookupMode);
if (simpleType.Parent is Attribute && !identifier.IsVerbatim) { if (simpleType.Parent is Attribute && !identifier.IsVerbatim) {
var withSuffix = resolver.LookupSimpleNameOrTypeName(identifier.Name + "Attribute", typeArguments, currentTypeLookupMode); var withSuffix = resolver.LookupSimpleNameOrTypeName(identifier.Name + "Attribute", typeArguments, currentTypeLookupMode);
@ -3141,7 +3153,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#region Query Expressions #region Query Expressions
ResolveResult IAstVisitor<object, ResolveResult>.VisitQueryExpression(QueryExpression queryExpression, object data) ResolveResult IAstVisitor<object, ResolveResult>.VisitQueryExpression(QueryExpression queryExpression, object data)
{ {
resolver.PushBlock(); resolver = resolver.PushBlock();
ResolveResult oldQueryResult = currentQueryResult; ResolveResult oldQueryResult = currentQueryResult;
try { try {
currentQueryResult = null; currentQueryResult = null;
@ -3151,7 +3163,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return currentQueryResult; return currentQueryResult;
} finally { } finally {
currentQueryResult = oldQueryResult; currentQueryResult = oldQueryResult;
resolver.PopBlock(); resolver = resolver.PopBlock();
} }
} }
@ -3259,7 +3271,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} }
StoreCurrentState(queryFromClause.IdentifierToken); StoreCurrentState(queryFromClause.IdentifierToken);
resolver.AddVariable(v); resolver = resolver.AddVariable(v);
StoreResult(queryFromClause.IdentifierToken, new LocalResolveResult(v)); StoreResult(queryFromClause.IdentifierToken, new LocalResolveResult(v));
if (resolverEnabled && currentQueryResult != null) { if (resolverEnabled && currentQueryResult != null) {
@ -3289,7 +3301,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
IType variableType = GetTypeForQueryVariable(rr.Type); IType variableType = GetTypeForQueryVariable(rr.Type);
StoreCurrentState(queryContinuationClause.IdentifierToken); StoreCurrentState(queryContinuationClause.IdentifierToken);
IVariable v = MakeVariable(variableType, queryContinuationClause.IdentifierToken); IVariable v = MakeVariable(variableType, queryContinuationClause.IdentifierToken);
resolver.AddVariable(v); resolver = resolver.AddVariable(v);
StoreResult(queryContinuationClause.IdentifierToken, new LocalResolveResult(v)); StoreResult(queryContinuationClause.IdentifierToken, new LocalResolveResult(v));
return rr; return rr;
} }
@ -3299,7 +3311,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult expr = Resolve(queryLetClause.Expression); ResolveResult expr = Resolve(queryLetClause.Expression);
StoreCurrentState(queryLetClause.IdentifierToken); StoreCurrentState(queryLetClause.IdentifierToken);
IVariable v = MakeVariable(expr.Type, queryLetClause.IdentifierToken); IVariable v = MakeVariable(expr.Type, queryLetClause.IdentifierToken);
resolver.AddVariable(v); resolver = resolver.AddVariable(v);
StoreResult(queryLetClause.IdentifierToken, new LocalResolveResult(v)); StoreResult(queryLetClause.IdentifierToken, new LocalResolveResult(v));
if (resolverEnabled && currentQueryResult != null) { if (resolverEnabled && currentQueryResult != null) {
// resolve the .Select() call // resolve the .Select() call
@ -3334,10 +3346,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult onResult = Resolve(queryJoinClause.OnExpression); ResolveResult onResult = Resolve(queryJoinClause.OnExpression);
// scan the 'Equals' expression in a context that contains only the variable 'v' // scan the 'Equals' expression in a context that contains only the variable 'v'
CSharpResolver resolverOutsideQuery = resolver.Clone(); CSharpResolver resolverOutsideQuery = resolver;
resolverOutsideQuery.PopBlock(); // pop all variables from the current query expression resolverOutsideQuery = resolverOutsideQuery.PopBlock(); // pop all variables from the current query expression
IVariable v = MakeVariable(variableType, queryJoinClause.JoinIdentifierToken); IVariable v = MakeVariable(variableType, queryJoinClause.JoinIdentifierToken);
resolverOutsideQuery.AddVariable(v); resolverOutsideQuery = resolverOutsideQuery.AddVariable(v);
ResolveResult equalsResult = errorResult; ResolveResult equalsResult = errorResult;
ResetContext(resolverOutsideQuery, delegate { ResetContext(resolverOutsideQuery, delegate {
equalsResult = Resolve(queryJoinClause.EqualsExpression); equalsResult = Resolve(queryJoinClause.EqualsExpression);
@ -3348,7 +3360,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (queryJoinClause.IsGroupJoin) { if (queryJoinClause.IsGroupJoin) {
return ResolveGroupJoin(queryJoinClause, inResult, onResult, equalsResult); return ResolveGroupJoin(queryJoinClause, inResult, onResult, equalsResult);
} else { } else {
resolver.AddVariable(v); resolver = resolver.AddVariable(v);
if (resolverEnabled && currentQueryResult != null) { if (resolverEnabled && currentQueryResult != null) {
QuerySelectClause selectClause = GetNextQueryClause(queryJoinClause) as QuerySelectClause; QuerySelectClause selectClause = GetNextQueryClause(queryJoinClause) as QuerySelectClause;
ResolveResult selectResult; ResolveResult selectResult;
@ -3451,7 +3463,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
StoreCurrentState(queryJoinClause.IntoIdentifierToken); StoreCurrentState(queryJoinClause.IntoIdentifierToken);
groupVariable = MakeVariable(groupParameterType, queryJoinClause.IntoIdentifierToken); groupVariable = MakeVariable(groupParameterType, queryJoinClause.IntoIdentifierToken);
resolver.AddVariable(groupVariable); resolver = resolver.AddVariable(groupVariable);
} }
if (groupVariable != null) { if (groupVariable != null) {

5
ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpAssembly.cs

@ -154,7 +154,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
public ITypeDefinition GetTypeDefinition(string ns, string name, int typeParameterCount) public ITypeDefinition GetTypeDefinition(string ns, string name, int typeParameterCount)
{ {
var key = new FullNameAndTypeParameterCount(ns, name, typeParameterCount); var key = new FullNameAndTypeParameterCount(ns ?? string.Empty, name, typeParameterCount);
DefaultResolvedTypeDefinition def; DefaultResolvedTypeDefinition def;
if (GetTypes().TryGetValue(key, out def)) if (GetTypes().TryGetValue(key, out def))
return def; return def;
@ -187,6 +187,9 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
} }
typeDef = new DefaultResolvedTypeDefinition(new SimpleTypeResolveContext(parentType), parts.ToArray()); typeDef = new DefaultResolvedTypeDefinition(new SimpleTypeResolveContext(parentType), parts.ToArray());
foreach (var part in parts) { foreach (var part in parts) {
// TODO: Fix that hack !
if (nestedTypeDict.ContainsKey (part))
continue;
nestedTypeDict.Add(part, typeDef); nestedTypeDict.Add(part, typeDef);
} }
return typeDef; return typeDef;

25
ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpParsedFile.cs

@ -20,6 +20,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation; using ICSharpCode.NRefactory.TypeSystem.Implementation;
using System.Linq;
namespace ICSharpCode.NRefactory.CSharp.TypeSystem namespace ICSharpCode.NRefactory.CSharp.TypeSystem
{ {
@ -138,5 +139,29 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
} }
return null; return null;
} }
public ITypeResolveContext GetTypeResolveContext (ICompilation compilation, TextLocation loc)
{
var rctx = new CSharpTypeResolveContext (compilation.MainAssembly);
rctx = rctx.WithUsingScope (GetUsingScope (loc).Resolve (compilation));
var curDef = GetInnermostTypeDefinition (loc);
if (curDef != null) {
var resolvedDef = curDef.Resolve (rctx).GetDefinition ();
if (resolvedDef == null)
return rctx;
rctx = rctx.WithCurrentTypeDefinition (resolvedDef);
var curMember = resolvedDef.Members.FirstOrDefault (m => m.Region.FileName == FileName && m.Region.Begin <= loc && loc < m.BodyRegion.End);
if (curMember != null)
rctx = rctx.WithCurrentMember (curMember);
}
return rctx;
}
public ICSharpCode.NRefactory.CSharp.Resolver.CSharpResolver GetResolver (ICompilation compilation, TextLocation loc)
{
return new ICSharpCode.NRefactory.CSharp.Resolver.CSharpResolver (GetTypeResolveContext (compilation, loc) as CSharpTypeResolveContext);
}
} }
} }

10
ICSharpCode.NRefactory.CSharp/TypeSystem/ConstantValues.cs

@ -62,7 +62,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
nestedContext = nestedContext.WithUsingScope(context.CurrentUsingScope.UnresolvedUsingScope.Resolve(nestedCompilation)); nestedContext = nestedContext.WithUsingScope(context.CurrentUsingScope.UnresolvedUsingScope.Resolve(nestedCompilation));
} }
if (context.CurrentTypeDefinition != null) { if (context.CurrentTypeDefinition != null) {
nestedContext = nestedContext.WithCurrentTypeDefinition(context.CurrentTypeDefinition.ToTypeReference().Resolve(nestedContext).GetDefinition()); nestedContext = nestedContext.WithCurrentTypeDefinition(nestedCompilation.Import(context.CurrentTypeDefinition));
} }
return nestedContext; return nestedContext;
} }
@ -432,13 +432,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
public override ResolveResult Resolve(CSharpResolver resolver) public override ResolveResult Resolve(CSharpResolver resolver)
{ {
bool oldCheckForOverflow = resolver.CheckForOverflow; return expression.Resolve(resolver.WithCheckForOverflow(checkForOverflow));
try {
resolver.CheckForOverflow = this.checkForOverflow;
return expression.Resolve(resolver);
} finally {
resolver.CheckForOverflow = oldCheckForOverflow;
}
} }
void ISupportsInterning.PrepareForInterning(IInterningProvider provider) void ISupportsInterning.PrepareForInterning(IInterningProvider provider)

4
ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs

@ -468,7 +468,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
} }
foreach (Constraint c in constraints) { foreach (Constraint c in constraints) {
foreach (var tp in list) { foreach (var tp in list) {
if (tp.Name == c.TypeParameter) { if (tp.Name == c.TypeParameter.Identifier) {
foreach (AstType type in c.BaseTypes) { foreach (AstType type in c.BaseTypes) {
PrimitiveType primType = type as PrimitiveType; PrimitiveType primType = type as PrimitiveType;
if (primType != null) { if (primType != null) {
@ -547,7 +547,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
} else { } else {
ctor.BodyRegion = MakeRegion(constructorDeclaration.Body); ctor.BodyRegion = MakeRegion(constructorDeclaration.Body);
} }
ctor.ReturnType = currentTypeDefinition; ctor.ReturnType = KnownTypeReference.Void;
ConvertAttributes(ctor.Attributes, constructorDeclaration.Attributes); ConvertAttributes(ctor.Attributes, constructorDeclaration.Attributes);
ConvertParameters(ctor.Parameters, constructorDeclaration.Parameters); ConvertParameters(ctor.Parameters, constructorDeclaration.Parameters);

3
ICSharpCode.NRefactory.ConsistencyCheck/.gitignore vendored

@ -0,0 +1,3 @@
bin/
obj/

176
ICSharpCode.NRefactory.ConsistencyCheck/CSharpProject.cs

@ -0,0 +1,176 @@
// 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 System.IO;
using System.Linq;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.TypeSystem;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.NRefactory.ConsistencyCheck
{
public class CSharpProject
{
public readonly Solution Solution;
public readonly string Title;
public readonly string AssemblyName;
public readonly string FileName;
public readonly List<CSharpFile> Files = new List<CSharpFile>();
public readonly bool AllowUnsafeBlocks;
public readonly bool CheckForOverflowUnderflow;
public readonly string[] PreprocessorDefines;
public IProjectContent ProjectContent;
public ICompilation Compilation {
get {
return Solution.SolutionSnapshot.GetCompilation(ProjectContent);
}
}
public CSharpProject(Solution solution, string title, string fileName)
{
this.Solution = solution;
this.Title = title;
this.FileName = fileName;
var p = new Microsoft.Build.Evaluation.Project(fileName);
this.AssemblyName = p.GetPropertyValue("AssemblyName");
this.AllowUnsafeBlocks = GetBoolProperty(p, "AllowUnsafeBlocks") ?? false;
this.CheckForOverflowUnderflow = GetBoolProperty(p, "CheckForOverflowUnderflow") ?? false;
this.PreprocessorDefines = p.GetPropertyValue("DefineConstants").Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var item in p.GetItems("Compile")) {
Files.Add(new CSharpFile(this, Path.Combine(p.DirectoryPath, item.EvaluatedInclude)));
}
List<IAssemblyReference> references = new List<IAssemblyReference>();
string mscorlib = FindAssembly(Program.AssemblySearchPaths, "mscorlib");
if (mscorlib != null) {
references.Add(Program.LoadAssembly(mscorlib));
} else {
Console.WriteLine("Could not find mscorlib");
}
foreach (var item in p.GetItems("Reference")) {
string assemblyFileName = null;
if (item.HasMetadata("HintPath")) {
assemblyFileName = Path.Combine(p.DirectoryPath, item.GetMetadataValue("HintPath"));
if (!File.Exists(assemblyFileName))
assemblyFileName = null;
}
if (assemblyFileName == null) {
assemblyFileName = FindAssembly(Program.AssemblySearchPaths, item.EvaluatedInclude);
}
if (assemblyFileName != null) {
references.Add(Program.LoadAssembly(assemblyFileName));
} else {
Console.WriteLine("Could not find referenced assembly " + item.EvaluatedInclude);
}
}
foreach (var item in p.GetItems("ProjectReference")) {
references.Add(new ProjectReference(solution, item.GetMetadataValue("Name")));
}
this.ProjectContent = new CSharpProjectContent()
.SetAssemblyName(this.AssemblyName)
.AddAssemblyReferences(references)
.UpdateProjectContent(null, Files.Select(f => f.ParsedFile));
}
string FindAssembly(IEnumerable<string> assemblySearchPaths, string evaluatedInclude)
{
if (evaluatedInclude.IndexOf(',') >= 0)
evaluatedInclude = evaluatedInclude.Substring(0, evaluatedInclude.IndexOf(','));
foreach (string searchPath in assemblySearchPaths) {
string assemblyFile = Path.Combine(searchPath, evaluatedInclude + ".dll");
if (File.Exists(assemblyFile))
return assemblyFile;
}
return null;
}
static bool? GetBoolProperty(Microsoft.Build.Evaluation.Project p, string propertyName)
{
string val = p.GetPropertyValue(propertyName);
if (val.Equals("true", StringComparison.OrdinalIgnoreCase))
return true;
if (val.Equals("false", StringComparison.OrdinalIgnoreCase))
return false;
return null;
}
public CSharpParser CreateParser()
{
List<string> args = new List<string>();
if (AllowUnsafeBlocks)
args.Add("-unsafe");
foreach (string define in PreprocessorDefines)
args.Add("-d:" + define);
return new CSharpParser(args.ToArray());
}
}
public class ProjectReference : IAssemblyReference
{
readonly Solution solution;
readonly string projectTitle;
public ProjectReference(Solution solution, string projectTitle)
{
this.solution = solution;
this.projectTitle = projectTitle;
}
public IAssembly Resolve(ITypeResolveContext context)
{
var project = solution.Projects.Single(p => string.Equals(p.Title, projectTitle, StringComparison.OrdinalIgnoreCase));
return project.ProjectContent.Resolve(context);
}
}
public class CSharpFile
{
public readonly CSharpProject Project;
public readonly string FileName;
public readonly ITextSource Content;
public readonly int LinesOfCode;
public CompilationUnit CompilationUnit;
public CSharpParsedFile ParsedFile;
public CSharpFile(CSharpProject project, string fileName)
{
this.Project = project;
this.FileName = fileName;
this.Content = new StringTextSource(File.ReadAllText(FileName));
this.LinesOfCode = 1 + this.Content.Text.Count(c => c == '\n');
CSharpParser p = project.CreateParser();
this.CompilationUnit = p.Parse(Content.CreateReader(), fileName);
if (p.HasErrors) {
Console.WriteLine("Error parsing " + fileName + ":");
foreach (var error in p.ErrorPrinter.Errors) {
Console.WriteLine(" " + error.Region + " " + error.Message);
}
}
this.ParsedFile = this.CompilationUnit.ToTypeSystem();
}
}
}

72
ICSharpCode.NRefactory.ConsistencyCheck/ICSharpCode.NRefactory.ConsistencyCheck.csproj

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<PropertyGroup>
<ProjectGuid>{D81206EF-3DCA-4A30-897B-E262A2AD9EE3}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<OutputType>Exe</OutputType>
<RootNamespace>ICSharpCode.NRefactory.ConsistencyCheck</RootNamespace>
<AssemblyName>ICSharpCode.NRefactory.ConsistencyCheck</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<AppDesignerFolder>Properties</AppDesignerFolder>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'x86' ">
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<OutputPath>bin\Debug\</OutputPath>
<DebugSymbols>True</DebugSymbols>
<DebugType>Full</DebugType>
<Optimize>False</Optimize>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<OutputPath>bin\Release\</OutputPath>
<DebugSymbols>False</DebugSymbols>
<DebugType>None</DebugType>
<Optimize>True</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>TRACE</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Build" />
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="CSharpProject.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ResolverTest.cs" />
<Compile Include="RoundtripTest.cs" />
<Compile Include="Solution.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="Readme.txt" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ICSharpCode.NRefactory.CSharp\ICSharpCode.NRefactory.CSharp.csproj">
<Project>{53DCA265-3C3C-42F9-B647-F72BA678122B}</Project>
<Name>ICSharpCode.NRefactory.CSharp</Name>
</ProjectReference>
<ProjectReference Include="..\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj">
<Project>{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}</Project>
<Name>ICSharpCode.NRefactory</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
</Project>

91
ICSharpCode.NRefactory.ConsistencyCheck/Program.cs

@ -0,0 +1,91 @@
// 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.Concurrent;
using System.Diagnostics;
using System.IO;
using System.Linq;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.NRefactory.ConsistencyCheck
{
class Program
{
public static readonly string[] AssemblySearchPaths = {
@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0",
@"C:\Program Files (x86)\GtkSharp\2.12\lib\gtk-sharp-2.0",
@"C:\Program Files (x86)\GtkSharp\2.12\lib\Mono.Posix",
};
public const string TempPath = @"C:\temp";
static Solution solution;
public static void Main(string[] args)
{
using (new Timer("Loading solution... ")) {
solution = new Solution(Path.GetFullPath("../../../NRefactory.sln"));
}
Console.WriteLine("Loaded {0} lines of code ({1:f1} MB) in {2} files in {3} projects.",
solution.AllFiles.Sum(f => f.LinesOfCode),
solution.AllFiles.Sum(f => f.Content.TextLength) / 1024.0 / 1024.0,
solution.AllFiles.Count(),
solution.Projects.Count);
//RunTestOnAllFiles("Roundtripping test", RoundtripTest.RunTest);
RunTestOnAllFiles("Resolver test", ResolverTest.RunTest);
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
static void RunTestOnAllFiles(string title, Action<CSharpFile> runTest)
{
using (new Timer(title + "... ")) {
foreach (var file in solution.AllFiles) {
runTest(file);
}
}
}
static ConcurrentDictionary<string, IUnresolvedAssembly> assemblyDict = new ConcurrentDictionary<string, IUnresolvedAssembly>(Platform.FileNameComparer);
public static IUnresolvedAssembly LoadAssembly(string assemblyFileName)
{
return assemblyDict.GetOrAdd(assemblyFileName, file => new CecilLoader().LoadAssemblyFile(file));
}
sealed class Timer : IDisposable
{
Stopwatch w = Stopwatch.StartNew();
public Timer(string title)
{
Console.Write(title);
}
public void Dispose()
{
Console.WriteLine(w.Elapsed);
}
}
}
}

31
ICSharpCode.NRefactory.ConsistencyCheck/Properties/AssemblyInfo.cs

@ -0,0 +1,31 @@
#region Using directives
using System;
using System.Reflection;
using System.Runtime.InteropServices;
#endregion
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ICSharpCode.NRefactory.ConsistencyCheck")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ICSharpCode.NRefactory.ConsistencyCheck")]
[assembly: AssemblyCopyright("Copyright 2011")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// This sets the default COM visibility of types in the assembly to invisible.
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
[assembly: ComVisible(false)]
// The assembly version has following format :
//
// Major.Minor.Build.Revision
//
// You can specify all the values or you can use the default the Revision and
// Build Numbers by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")]

8
ICSharpCode.NRefactory.ConsistencyCheck/Readme.txt

@ -0,0 +1,8 @@
This is an automatic consistency check for NRefactory.
It loads a solution file and parses all the source code and referenced libraries,
and then performs a set of consistency checks.
These checks assume that the code is valid C# without any compilation errors,
so make sure to only pass in compilable source code.
Checks currently being performed:
-

83
ICSharpCode.NRefactory.ConsistencyCheck/ResolverTest.cs

@ -0,0 +1,83 @@
/*
* Created by SharpDevelop.
* User: Daniel
* Date: 12/9/2011
* Time: 01:26
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.NRefactory.ConsistencyCheck
{
/// <summary>
/// Description of ResolverTest.
/// </summary>
public class ResolverTest
{
public static void RunTest(CSharpFile file)
{
CSharpAstResolver resolver = new CSharpAstResolver(file.Project.Compilation, file.CompilationUnit, file.ParsedFile);
var navigator = new ValidatingResolveAllNavigator(file.FileName);
resolver.ApplyNavigator(navigator, CancellationToken.None);
navigator.Validate(file.CompilationUnit);
}
sealed class ValidatingResolveAllNavigator : IResolveVisitorNavigator
{
string fileName;
public ValidatingResolveAllNavigator(string fileName)
{
this.fileName = fileName;
}
HashSet<AstNode> resolvedNodes = new HashSet<AstNode>();
HashSet<AstNode> nodesWithConversions = new HashSet<AstNode>();
public ResolveVisitorNavigationMode Scan(AstNode node)
{
return ResolveVisitorNavigationMode.Resolve;
}
public void Resolved(AstNode node, ResolveResult result)
{
if (!resolvedNodes.Add(node))
throw new InvalidOperationException("Duplicate Resolved() call");
if (CSharpAstResolver.IsUnresolvableNode(node))
throw new InvalidOperationException("Resolved unresolvable node");
if (result.IsError) {
Console.WriteLine("Compiler error at " + fileName + ":" + node.StartLocation + ": " + result);
}
}
public void ProcessConversion(Expression expression, ResolveResult result, Conversion conversion, IType targetType)
{
if (!nodesWithConversions.Add(expression))
throw new InvalidOperationException("Duplicate ProcessConversion() call");
if (conversion == Conversion.None) {
Console.WriteLine("Compiler error at " + fileName + ":" + expression.StartLocation + ": Cannot convert from " + result + " to " + targetType);
}
}
public void Validate(CompilationUnit cu)
{
foreach (AstNode node in cu.DescendantsAndSelf.Except(resolvedNodes)) {
if (node.NodeType != NodeType.Token) {
if (!CSharpAstResolver.IsUnresolvableNode(node)) {
Console.WriteLine("Forgot to resolve " + node);
}
}
}
}
}
}
}

108
ICSharpCode.NRefactory.ConsistencyCheck/RoundtripTest.cs

@ -0,0 +1,108 @@
// 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.IO;
using System.Text;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.PatternMatching;
namespace ICSharpCode.NRefactory.ConsistencyCheck
{
/// <summary>
/// Tests parser + output visitor by roundtripping code.
/// Everything but whitespace must be preserved.
/// </summary>
public class RoundtripTest
{
public static void RunTest(CSharpFile file)
{
// TODO: also try Windows-style newlines once the parser bug with integer literals followed by \r is fixed
string code = file.Content.Text.Replace("\r\n", "\n");
if (code.Contains("#pragma"))
return; // skip code with preprocessor directives
if (code.Contains("enum VarianceModifier") || file.FileName.EndsWith("ecore.cs") || file.FileName.EndsWith("method.cs"))
return; // skip enum with ; at end (see TypeDeclarationTests.EnumWithSemicolonAtEnd)
if (file.FileName.EndsWith("KnownTypeReference.cs") || file.FileName.EndsWith("typemanager.cs") || file.FileName.EndsWith("GetAllBaseTypesTest.cs") || file.FileName.EndsWith("Tokens.cs") || file.FileName.EndsWith("OpCode.cs") || file.FileName.EndsWith("MainWindow.cs"))
return; // skip due to optional , at end of array initializer (see ArrayCreateExpressionTests.ArrayInitializerWithCommaAtEnd)
if (file.FileName.EndsWith("cs-parser.cs"))
return; // skip due to completely messed up comment locations
if (file.FileName.EndsWith("PrimitiveExpressionTests.cs"))
return; // skip due to PrimitiveExpressionTests.*WithLeadingDot
if (file.FileName.Contains("FormattingTests") || file.FileName.Contains("ContextAction") || file.FileName.Contains("CodeCompletion"))
return; // skip due to AttributeSectionTests.AttributeWithEmptyParenthesis
if (file.FileName.EndsWith("TypeSystemTests.TestCase.cs"))
return; // skip due to AttributeSectionTests.AssemblyAttributeBeforeNamespace
if (file.FileName.EndsWith("dynamic.cs") || file.FileName.EndsWith("expression.cs"))
return; // skip due to PreprocessorDirectiveTests.NestedInactiveIf
if (file.FileName.EndsWith("property.cs"))
return; // skip due to PreprocessorDirectiveTests.CommentOnEndOfIfDirective
Roundtrip(file.Project.CreateParser(), file.FileName, code);
}
public static void Roundtrip(CSharpParser parser, string fileName, string code)
{
// 1. Parse
CompilationUnit cu = parser.Parse(code, fileName);
if (parser.HasErrors)
throw new InvalidOperationException("There were parse errors.");
// 2. Output
StringWriter w = new StringWriter();
cu.AcceptVisitor(new CSharpOutputVisitor(w, new CSharpFormattingOptions()));
string generatedCode = w.ToString().TrimEnd();
// 3. Compare output with original (modulo whitespaces)
int pos2 = 0;
for (int pos1 = 0; pos1 < code.Length; pos1++) {
if (!char.IsWhiteSpace(code[pos1])) {
while (pos2 < generatedCode.Length && char.IsWhiteSpace(generatedCode[pos2]))
pos2++;
if (pos2 >= generatedCode.Length || code[pos1] != generatedCode[pos2]) {
ReadOnlyDocument doc = new ReadOnlyDocument(code);
File.WriteAllText(Path.Combine(Program.TempPath, "roundtrip-error.cs"), generatedCode);
throw new InvalidOperationException("Mismatch at " + doc.GetLocation(pos1) + " of file " + fileName);
}
pos2++;
}
}
if (pos2 != generatedCode.Length)
throw new InvalidOperationException("Mismatch at end of file " + fileName);
// 4. Parse generated output
CompilationUnit generatedCU;
try {
generatedCU = parser.Parse(generatedCode, fileName);
} catch {
File.WriteAllText(Path.Combine(Program.TempPath, "roundtrip-error.cs"), generatedCode, Encoding.Unicode);
throw;
}
if (parser.HasErrors) {
File.WriteAllText(Path.Combine(Program.TempPath, "roundtrip-error.cs"), generatedCode);
throw new InvalidOperationException("There were parse errors in the roundtripped " + fileName);
}
// 5. Compare AST1 with AST2
if (!cu.IsMatch(generatedCU))
throw new InvalidOperationException("AST match failed for " + fileName + ".");
}
}
}

67
ICSharpCode.NRefactory.ConsistencyCheck/Solution.cs

@ -0,0 +1,67 @@
// 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 System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.ConsistencyCheck
{
public class Solution
{
public readonly string Directory;
public readonly List<CSharpProject> Projects = new List<CSharpProject>();
public readonly ISolutionSnapshot SolutionSnapshot = new DefaultSolutionSnapshot();
public IEnumerable<CSharpFile> AllFiles {
get {
return Projects.SelectMany(p => p.Files);
}
}
public Solution(string fileName)
{
this.Directory = Path.GetDirectoryName(fileName);
var projectLinePattern = new Regex("Project\\(\"(?<TypeGuid>.*)\"\\)\\s+=\\s+\"(?<Title>.*)\",\\s*\"(?<Location>.*)\",\\s*\"(?<Guid>.*)\"");
foreach (string line in File.ReadLines(fileName)) {
Match match = projectLinePattern.Match(line);
if (match.Success) {
string typeGuid = match.Groups["TypeGuid"].Value;
string title = match.Groups["Title"].Value;
string location = match.Groups["Location"].Value;
string guid = match.Groups["Guid"].Value;
switch (typeGuid.ToUpperInvariant()) {
case "{2150E333-8FDC-42A3-9474-1A3956D46DE8}": // Solution Folder
// ignore folders
break;
case "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}": // C# project
Projects.Add(new CSharpProject(this, title, Path.Combine(Directory, location)));
break;
default:
Console.WriteLine("Project {0} has unsupported type {1}", location, typeGuid);
break;
}
}
}
}
}
}

6
ICSharpCode.NRefactory.ConsistencyCheck/app.config

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
</startup>
</configuration>

2
ICSharpCode.NRefactory.Demo/CSDemo.cs

@ -316,7 +316,7 @@ namespace ICSharpCode.NRefactory.Demo
}; };
var searchScopes = fr.GetSearchScopes(entity); var searchScopes = fr.GetSearchScopes(entity);
fr.FindReferencesInFile(searchScopes, parsedFile, compilationUnit, callback, CancellationToken.None); fr.FindReferencesInFile(searchScopes, parsedFile, compilationUnit, compilation, callback, CancellationToken.None);
MessageBox.Show("Found " + referenceCount + " references to " + entity.FullName); MessageBox.Show("Found " + referenceCount + " references to " + entity.FullName);
} }

51
ICSharpCode.NRefactory.GtkDemo/MainWindow.cs

@ -37,6 +37,8 @@ using ICSharpCode.NRefactory.TypeSystem;
using System.Threading.Tasks; using System.Threading.Tasks;
using ICSharpCode.NRefactory.TypeSystem.Implementation; using ICSharpCode.NRefactory.TypeSystem.Implementation;
using Gdk; using Gdk;
using System.Threading;
using System.Diagnostics;
namespace ICSharpCode.NRefactory.GtkDemo namespace ICSharpCode.NRefactory.GtkDemo
{ {
@ -123,7 +125,7 @@ namespace ICSharpCode.NRefactory.GtkDemo
this.editor.Caret.PositionChanged += HandlePositionChanged; this.editor.Caret.PositionChanged += HandlePositionChanged;
} }
public void ShowUnit (CompilationUnit unit, ResolveVisitor visitor) public void ShowUnit (CompilationUnit unit, CSharpAstResolver visitor)
{ {
this.unit = unit; this.unit = unit;
store.Clear (); store.Clear ();
@ -159,7 +161,7 @@ namespace ICSharpCode.NRefactory.GtkDemo
return null; return null;
} }
public void AddChildren (AstNode node, ResolveVisitor visitor, TreeIter iter) public void AddChildren (AstNode node, CSharpAstResolver visitor, TreeIter iter)
{ {
if (node == null) if (node == null)
return; return;
@ -168,7 +170,7 @@ namespace ICSharpCode.NRefactory.GtkDemo
ResolveResult result = null; ResolveResult result = null;
try { try {
if (child is Expression) if (child is Expression)
result = visitor.GetResolveResult (child); result = visitor.Resolve (child, CancellationToken.None);
} catch (Exception){ } catch (Exception){
result = null; result = null;
} }
@ -215,48 +217,41 @@ namespace ICSharpCode.NRefactory.GtkDemo
void HandleClicked (object sender, EventArgs e) void HandleClicked (object sender, EventArgs e)
{ {
var parser = new CSharpParser (); var parser = new CSharpParser ();
var unit = parser.Parse (editor.Text); var unit = parser.Parse (editor.Text, "dummy.cs");
var project = new SimpleProjectContent(); var parsedFile = unit.ToTypeSystem();
var parsedFile = new TypeSystemConvertVisitor(project, "dummy.cs").Convert (unit);
project.UpdateProjectContent(null, parsedFile);
var projects = new List<ITypeResolveContext>(); IProjectContent project = new CSharpProjectContent ();
projects.Add(project); project = project.UpdateProjectContent (null, parsedFile);
projects.AddRange(builtInLibs.Value); project = project.AddAssemblyReferences (builtInLibs.Value);
using (var context = new CompositeTypeResolveContext(projects).Synchronize()) {
var resolver = new CSharpResolver(context); CSharpAstResolver resolver = new CSharpAstResolver(project.CreateCompilation (), unit, parsedFile);
ShowUnit (unit, resolver);
IResolveVisitorNavigator navigator = null;
// if (csharpTreeView.SelectedNode != null) {
// navigator = new NodeListResolveVisitorNavigator(new[] { (AstNode)csharpTreeView.SelectedNode.Tag });
// }
var visitor = new ResolveVisitor (resolver, parsedFile, navigator);
visitor.Scan(unit);
ShowUnit (unit, visitor);
}
} }
Lazy<IList<IProjectContent>> builtInLibs = new Lazy<IList<IProjectContent>>( Lazy<IList<IUnresolvedAssembly>> builtInLibs = new Lazy<IList<IUnresolvedAssembly>>(
delegate { delegate {
Assembly[] assemblies = new Assembly[] { // Compiler error ? Assembly[] assemblies = new Assembly[] {
typeof(object).Assembly, // mscorlib typeof(object).Assembly, // mscorlib
typeof(Uri).Assembly, // System.dll typeof(Uri).Assembly, // System.dll
typeof(System.Linq.Enumerable).Assembly, typeof(System.Linq.Enumerable).Assembly, // System.Core.dll
typeof(ICSharpCode.NRefactory.TypeSystem.IProjectContent).Assembly // typeof(System.Xml.XmlDocument).Assembly, // System.Xml.dll
// typeof(System.Drawing.Bitmap).Assembly, // System.Drawing.dll
// typeof(Form).Assembly, // System.Windows.Forms.dll
typeof(ICSharpCode.NRefactory.TypeSystem.IProjectContent).Assembly,
}; };
IProjectContent[] projectContents = new IProjectContent[assemblies.Length]; IUnresolvedAssembly[] projectContents = new IUnresolvedAssembly[assemblies.Length];
Parallel.For( Parallel.For(
0, assemblies.Length, 0, assemblies.Length,
delegate (int i) { delegate (int i) {
Stopwatch w = Stopwatch.StartNew();
CecilLoader loader = new CecilLoader(); CecilLoader loader = new CecilLoader();
projectContents[i] = loader.LoadAssemblyFile(assemblies[i].Location); projectContents[i] = loader.LoadAssemblyFile(assemblies[i].Location);
}); });
return projectContents; return projectContents;
}); });
} }
} }

146
ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/CodeCompletionBugTests.cs

@ -1496,10 +1496,107 @@ class A
} }
"); ");
Assert.IsNotNull (provider, "provider not found."); Assert.IsNotNull (provider, "provider not found.");
Assert.IsNotNull (provider.Find ("A"), "class 'A' not found.");
Assert.AreEqual ("A", provider.DefaultCompletionString);
Assert.IsNull (provider.Find ("B"), "class 'B' found, but shouldn'tj."); Assert.IsNull (provider.Find ("B"), "class 'B' found, but shouldn'tj.");
} }
/// <summary>
/// Bug 2295 - [New Resolver] 'new' completion doesn't select the correct class name
/// </summary>
[Test()]
public void TestBug2295 ()
{
CombinedProviderTest (
@"
class A
{
public void Test()
{
A a;
$a = new $
}
}
", provider => {
Assert.IsNotNull (provider.Find ("A"), "class 'A' not found.");
Assert.AreEqual ("A", provider.DefaultCompletionString);
});
}
/// <summary>
/// Bug 2061 - Typing 'new' in a method all does not offer valid completion
/// </summary>
[Test()]
public void TestBug2061 ()
{
CombinedProviderTest (
@"
class A
{
void CallTest(A a)
{
}
public void Test()
{
$CallTest(new $
}
}
", provider => {
Assert.IsNotNull (provider.Find ("A"), "class 'A' not found.");
Assert.AreEqual ("A", provider.DefaultCompletionString);
});
}
[Test()]
public void TestBug2061Case2 ()
{
CombinedProviderTest (
@"
class A
{
void CallTest(int i, string s, A a)
{
}
public void Test()
{
$CallTest(5, """", new $
}
}
", provider => {
Assert.IsNotNull (provider.Find ("A"), "class 'A' not found.");
Assert.AreEqual ("A", provider.DefaultCompletionString);
});
}
[Test()]
public void TestNewInConstructor ()
{
CombinedProviderTest (
@"
class CallTest
{
public CallTest(int i, string s, A a)
{
}
}
class A
{
public void Test()
{
$new CallTest(5, """", new $
}
}
", provider => {
Assert.IsNotNull (provider.Find ("A"), "class 'A' not found.");
Assert.AreEqual ("A", provider.DefaultCompletionString);
});
}
/// <summary> /// <summary>
/// Bug 473686 - Constants are not included in code completion /// Bug 473686 - Constants are not included in code completion
/// </summary> /// </summary>
@ -3771,6 +3868,51 @@ public partial class TestMe
Assert.IsNotNull (provider, "provider not found."); Assert.IsNotNull (provider, "provider not found.");
Assert.IsNotNull (provider.Find ("MyMethod"), "method 'MyMethod' not found."); Assert.IsNotNull (provider.Find ("MyMethod"), "method 'MyMethod' not found.");
Assert.IsNull (provider.Find ("Implemented"), "method 'Implemented' found."); Assert.IsNull (provider.Find ("Implemented"), "method 'Implemented' found.");
} }
/// <summary>
/// Bug 224 - Code completion cannot handle lambdas properly.
/// </summary>
[Test()]
public void TestBug224 ()
{
CombinedProviderTest (
@"
using System;
public sealed class CrashEventArgs : EventArgs
{
public int ArgsNum { get; set; }
public CrashEventArgs ()
{
}
}
interface ICrashMonitor
{
event EventHandler<CrashEventArgs> CrashDetected;
void StartMonitoring ();
void StopMonitoring ();
}
namespace ConsoleProject
{
class MainClass
{
public static void Main (string[] args)
{
ICrashMonitor mon;
$mon.CrashDetected += (sender, e) => e.$
}
}
}
", provider => {
Assert.IsNotNull (provider.Find ("ArgsNum"), "property 'ArgsNum' not found.");
});
}
} }
} }

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

@ -161,7 +161,6 @@ class Test
}); });
} }
[Ignore("needs to be fixed in parser.")]
[Test()] [Test()]
public void IsAsKeywordTest () public void IsAsKeywordTest ()
{ {
@ -196,7 +195,6 @@ provider => {
}); });
} }
[Ignore()]
[Test()] [Test()]
public void PublicClassContextTest2 () public void PublicClassContextTest2 ()
{ {
@ -209,7 +207,6 @@ provider => {
}); });
} }
[Ignore()]
[Test()] [Test()]
public void PublicClassContextTestContinuation1 () public void PublicClassContextTestContinuation1 ()
{ {
@ -220,7 +217,6 @@ provider => {
}); });
} }
[Ignore()]
[Test()] [Test()]
public void PublicClassContextTestContinuation2 () public void PublicClassContextTestContinuation2 ()
{ {
@ -231,6 +227,84 @@ provider => {
}); });
} }
[Test()]
public void StatementKeywordTests ()
{
CodeCompletionBugTests.CombinedProviderTest (
@"using System;
class Test
{
public void MyMethod ()
{
$s$
}
", (provider) => {
Assert.IsNotNull (provider.Find ("bool"), "keyword 'bool' not found.");
Assert.IsNotNull (provider.Find ("char"), "keyword 'char' not found.");
Assert.IsNotNull (provider.Find ("byte"), "keyword 'byte' not found.");
Assert.IsNotNull (provider.Find ("sbyte"), "keyword 'sbyte' not found.");
Assert.IsNotNull (provider.Find ("int"), "keyword 'int' not found.");
Assert.IsNotNull (provider.Find ("uint"), "keyword 'uint' not found.");
Assert.IsNotNull (provider.Find ("short"), "keyword 'short' not found.");
Assert.IsNotNull (provider.Find ("ushort"), "keyword 'ushort' not found.");
Assert.IsNotNull (provider.Find ("long"), "keyword 'long' not found.");
Assert.IsNotNull (provider.Find ("ulong"), "keyword 'ulong' not found.");
Assert.IsNotNull (provider.Find ("float"), "keyword 'float' not found.");
Assert.IsNotNull (provider.Find ("double"), "keyword 'double' not found.");
Assert.IsNotNull (provider.Find ("decimal"), "keyword 'decimal' not found.");
Assert.IsNotNull (provider.Find ("const"), "keyword 'const' not found.");
Assert.IsNotNull (provider.Find ("dynamic"), "keyword 'dynamic' not found.");
Assert.IsNotNull (provider.Find ("var"), "keyword 'var' not found.");
Assert.IsNotNull (provider.Find ("do"), "keyword 'do' not found.");
Assert.IsNotNull (provider.Find ("while"), "keyword 'while' not found.");
Assert.IsNotNull (provider.Find ("for"), "keyword 'for' not found.");
Assert.IsNotNull (provider.Find ("foreach"), "keyword 'foreach' not found.");
Assert.IsNotNull (provider.Find ("goto"), "keyword 'goto' not found.");
Assert.IsNotNull (provider.Find ("break"), "keyword 'break' not found.");
Assert.IsNotNull (provider.Find ("continue"), "keyword 'continue' not found.");
Assert.IsNotNull (provider.Find ("return"), "keyword 'return' not found.");
Assert.IsNotNull (provider.Find ("throw"), "keyword 'throw' not found.");
Assert.IsNotNull (provider.Find ("fixed"), "keyword 'fixed' not found.");
Assert.IsNotNull (provider.Find ("using"), "keyword 'using' not found.");
Assert.IsNotNull (provider.Find ("lock"), "keyword 'lock' not found.");
Assert.IsNotNull (provider.Find ("true"), "keyword 'true' not found.");
Assert.IsNotNull (provider.Find ("false"), "keyword 'false' not found.");
Assert.IsNotNull (provider.Find ("null"), "keyword 'null' not found.");
Assert.IsNotNull (provider.Find ("typeof"), "keyword 'typeof' not found.");
Assert.IsNotNull (provider.Find ("sizeof"), "keyword 'sizeof' not found.");
Assert.IsNotNull (provider.Find ("from"), "keyword 'from' not found.");
Assert.IsNotNull (provider.Find ("yield"), "keyword 'yield' not found.");
Assert.IsNotNull (provider.Find ("new"), "keyword 'new' not found.");
});
}
[Test()]
public void ForeachInKeywordTest ()
{
CodeCompletionBugTests.CombinedProviderTest (
@"using System;
class Test
{
public void Method ()
{
$foreach (var o i$
}
}
", (provider) => {
// Either empty list or in - both behaviours are ok.
if (provider.Count > 0)
Assert.IsNotNull (provider.Find ("in"), "keyword 'in' not found.");
});
}
} }
} }

27
ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/ParameterCompletionTests.cs

@ -515,6 +515,33 @@ class A
Assert.IsNotNull (provider, "provider was not created."); Assert.IsNotNull (provider, "provider was not created.");
Assert.AreEqual (1, provider.OverloadCount); Assert.AreEqual (1, provider.OverloadCount);
} }
[Test()]
public void TestConstructorCase2 ()
{
IParameterDataProvider provider = CreateProvider (
@"
namespace Test
{
struct TestMe
{
public TestMe (string a)
{
}
}
class A
{
void Method ()
{
$new TestMe ($
}
}
}");
Assert.IsNotNull (provider, "provider was not created.");
Assert.AreEqual (2, provider.OverloadCount);
}
} }

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

@ -46,6 +46,22 @@ class MyTest
Assert.IsTrue (provider == null || provider.Count == 0, "provider should be empty."); Assert.IsTrue (provider == null || provider.Count == 0, "provider should be empty.");
} }
[Test()]
public void TestDefaultBehaviorInForeach ()
{
var provider = CodeCompletionBugTests.CreateProvider (
@"
class MyTest
{
public void Test ()
{
$foreach (var v$
}
}
");
Assert.IsTrue (provider == null || provider.Count == 0, "provider should be empty.");
}
[Test()] [Test()]
public void TestIntNameProposal () public void TestIntNameProposal ()
{ {
@ -81,6 +97,23 @@ class MyTest
Assert.IsNotNull (provider.Find ("test"), "name proposal 'test' not found."); Assert.IsNotNull (provider.Find ("test"), "name proposal 'test' not found.");
} }
[Test()]
public void TestNameProposalForeach ()
{
var provider = CodeCompletionBugTests.CreateCtrlSpaceProvider (
@"
class MyTest
{
public void Test ()
{
$foreach (MyTest $
}
}
");
Assert.IsNotNull (provider.Find ("myTest"), "name proposal 'myTest' not found.");
Assert.IsNotNull (provider.Find ("test"), "name proposal 'test' not found.");
}
/// <summary> /// <summary>
/// Bug 1799 - [New Resolver] Invalid code completion when typing name of variable /// Bug 1799 - [New Resolver] Invalid code completion when typing name of variable
/// </summary> /// </summary>

4
ICSharpCode.NRefactory.Tests/CSharp/CodeDomConvertVisitorTests.cs

@ -51,8 +51,8 @@ namespace ICSharpCode.NRefactory.CSharp
string Convert(Expression expr) string Convert(Expression expr)
{ {
CSharpResolver resolver = new CSharpResolver(compilation); CSharpResolver resolver = new CSharpResolver(compilation);
resolver.CurrentUsingScope = parsedFile.RootUsingScope.Resolve(compilation); resolver = resolver.WithCurrentUsingScope(parsedFile.RootUsingScope.Resolve(compilation));
resolver.CurrentTypeDefinition = compilation.FindType(KnownTypeCode.Object).GetDefinition(); resolver = resolver.WithCurrentTypeDefinition(compilation.FindType(KnownTypeCode.Object).GetDefinition());
var codeExpr = (CodeExpression)convertVisitor.Convert(expr, new CSharpAstResolver(resolver, expr, parsedFile)); var codeExpr = (CodeExpression)convertVisitor.Convert(expr, new CSharpAstResolver(resolver, expr, parsedFile));
StringWriter writer = new StringWriter(); StringWriter writer = new StringWriter();

2
ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/ArrayCreateExpressionTests.cs

@ -147,7 +147,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
}}); }});
} }
[Test] [Test, Ignore("Parser bug")]
public void ArrayInitializerWithCommaAtEnd() public void ArrayInitializerWithCommaAtEnd()
{ {
var ace = ParseUtilCSharp.ParseExpression<ArrayCreateExpression>("new [] { 1, }"); var ace = ParseUtilCSharp.ParseExpression<ArrayCreateExpression>("new [] { 1, }");

4
ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/CastExpressionTests.cs

@ -166,14 +166,14 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
}); });
} }
[Test, Ignore ("TODO")] [Test]
public void IntMaxValueToBigInt() public void IntMaxValueToBigInt()
{ {
ParseUtilCSharp.AssertExpression( ParseUtilCSharp.AssertExpression(
"(BigInt)int.MaxValue", "(BigInt)int.MaxValue",
new CastExpression { new CastExpression {
Type = new SimpleType("BigInt"), Type = new SimpleType("BigInt"),
Expression = new PrimitiveExpression("int").Member("MaxValue") Expression = new PrimitiveType("int").Member("MaxValue")
}); });
} }
} }

8
ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/InvocationExpressionTests.cs

@ -115,17 +115,17 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
Assert.IsTrue(expr.Arguments.Single() is InvocationExpression); Assert.IsTrue(expr.Arguments.Single() is InvocationExpression);
} }
[Test, Ignore("Positions not yet accurate when parsing expression only (because class/method is added around it)")] [Test]
public void NestedInvocationPositions() public void NestedInvocationPositions()
{ {
InvocationExpression expr = ParseUtilCSharp.ParseExpression<InvocationExpression>("a.B().C(args)"); InvocationExpression expr = ParseUtilCSharp.ParseExpression<InvocationExpression>("a.B().C(args)");
Assert.AreEqual(new TextLocation(1, 8), expr.StartLocation); Assert.AreEqual(new TextLocation(1, 1), expr.StartLocation);
Assert.AreEqual(new TextLocation(1, 14), expr.EndLocation); Assert.AreEqual(new TextLocation(1, 14), expr.EndLocation);
MemberReferenceExpression mre = (MemberReferenceExpression)expr.Target; MemberReferenceExpression mre = (MemberReferenceExpression)expr.Target;
Assert.AreEqual(new TextLocation(1, 6), mre.StartLocation); Assert.AreEqual(new TextLocation(1, 1), mre.StartLocation);
Assert.AreEqual(new TextLocation(1, 8), mre.EndLocation); Assert.AreEqual(new TextLocation(1, 8), mre.EndLocation);
Assert.AreEqual(new TextLocation(1, 4), mre.Target.StartLocation); Assert.AreEqual(new TextLocation(1, 1), mre.Target.StartLocation);
Assert.AreEqual(new TextLocation(1, 6), mre.Target.EndLocation); Assert.AreEqual(new TextLocation(1, 6), mre.Target.EndLocation);
} }

4
ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/MemberReferenceExpressionTests.cs

@ -33,7 +33,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
); );
} }
[Test, Ignore("parser is broken and produces IdentifierExpression instead of PrimitiveType")] [Test]
public void ShortMaxValueTest() public void ShortMaxValueTest()
{ {
ParseUtilCSharp.AssertExpression( ParseUtilCSharp.AssertExpression(
@ -42,7 +42,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
); );
} }
[Test, Ignore("Parsing of @-identifiers is broken")] [Test]
public void IdentShortMaxValueTest() public void IdentShortMaxValueTest()
{ {
ParseUtilCSharp.AssertExpression( ParseUtilCSharp.AssertExpression(

24
ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/PrimitiveExpressionTests.cs

@ -46,24 +46,33 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
PrimitiveExpression pe = ParseUtilCSharp.ParseExpression<PrimitiveExpression>(code); PrimitiveExpression pe = ParseUtilCSharp.ParseExpression<PrimitiveExpression>(code);
Assert.AreEqual(value.GetType(), pe.Value.GetType()); Assert.AreEqual(value.GetType(), pe.Value.GetType());
Assert.AreEqual(value, pe.Value); Assert.AreEqual(value, pe.Value);
Assert.AreEqual(code, pe.LiteralValue);
} }
[Test] [Test]
public void DoubleTest1() public void DoubleWithLeadingDot()
{ {
CheckLiteral(".5e-06", .5e-06); CheckLiteral(".5e-06", .5e-06);
} }
[Test]
public void FloatWithLeadingDot()
{
CheckLiteral(".5e-06f", .5e-06f);
}
[Test] [Test]
public void CharTest1() public void CharTest1()
{ {
CheckLiteral("'\\u0356'", '\u0356'); CheckLiteral("'\\u0356'", '\u0356');
} }
[Test, Ignore("this special case isn't implemented yet")] [Test]
public void IntMinValueTest() public void IntMinValueTest()
{ {
CheckLiteral("-2147483648", -2147483648); ParseUtilCSharp.AssertExpression(
"-2147483648",
new UnaryOperatorExpression(UnaryOperatorType.Minus, new PrimitiveExpression(-2147483648)));
} }
[Test] [Test]
@ -73,10 +82,12 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
CheckLiteral("2147483648", 2147483648); // uint CheckLiteral("2147483648", 2147483648); // uint
} }
[Test, Ignore("this special case isn't implemented yet")] [Test]
public void LongMinValueTest() public void LongMinValueTest()
{ {
CheckLiteral("-9223372036854775808", -9223372036854775808); ParseUtilCSharp.AssertExpression(
"-9223372036854775808",
new UnaryOperatorExpression(UnaryOperatorType.Minus, new PrimitiveExpression(9223372036854775808)));
} }
[Test] [Test]
@ -215,12 +226,13 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
CheckLiteral(@"'\U00000041'", '\U00000041'); CheckLiteral(@"'\U00000041'", '\U00000041');
} }
[Test, Ignore(@"Parser includes \r in integer literal")] [Test]
public void TestPositionOfIntegerAtEndOfLine() public void TestPositionOfIntegerAtEndOfLine()
{ {
var pe = ParseUtilCSharp.ParseExpression<PrimitiveExpression>("0\r\n"); var pe = ParseUtilCSharp.ParseExpression<PrimitiveExpression>("0\r\n");
Assert.AreEqual(new TextLocation(1, 1), pe.StartLocation); Assert.AreEqual(new TextLocation(1, 1), pe.StartLocation);
Assert.AreEqual(new TextLocation(1, 2), pe.EndLocation); Assert.AreEqual(new TextLocation(1, 2), pe.EndLocation);
Assert.AreEqual("0", pe.LiteralValue);
} }
} }
} }

14
ICSharpCode.NRefactory.Tests/CSharp/Parser/Expression/TypeReferenceExpressionTests.cs

@ -38,19 +38,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
})); }));
} }
[Test, Ignore ("Doesn't work")] [Test]
public void GlobalTypeReferenceExpressionWithoutTypeName()
{
TypeReferenceExpression tr = ParseUtilCSharp.ParseExpression<TypeReferenceExpression>("global::", true);
Assert.IsTrue (tr.IsMatch (new TypeReferenceExpression () {
Type = new MemberType () {
Target = new SimpleType ("global"),
IsDoubleColon = true,
}
}));
}
[Test, Ignore("Primitive types as member reference target are not supported yet")]
public void IntReferenceExpression() public void IntReferenceExpression()
{ {
MemberReferenceExpression fre = ParseUtilCSharp.ParseExpression<MemberReferenceExpression>("int.MaxValue"); MemberReferenceExpression fre = ParseUtilCSharp.ParseExpression<MemberReferenceExpression>("int.MaxValue");

34
ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/AttributeSectionTests.cs

@ -17,9 +17,9 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using System.IO;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using ICSharpCode.NRefactory.PatternMatching; using ICSharpCode.NRefactory.PatternMatching;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using NUnit.Framework; using NUnit.Framework;
@ -72,6 +72,26 @@ public class Form1 {
Assert.AreEqual("type", decl.AttributeTarget); Assert.AreEqual("type", decl.AttributeTarget);
} }
[Test]
public void AttributeWithoutParenthesis()
{
string program = @"[Attr] class Test {}";
TypeDeclaration type = ParseUtilCSharp.ParseGlobal<TypeDeclaration>(program);
var attr = type.Attributes.Single().Attributes.Single();
Assert.IsTrue(attr.GetChildByRole(AstNode.Roles.LPar).IsNull);
Assert.IsTrue(attr.GetChildByRole(AstNode.Roles.RPar).IsNull);
}
[Test, Ignore("Parser bug - parenthesis are missing")]
public void AttributeWithEmptyParenthesis()
{
string program = @"[Attr()] class Test {}";
TypeDeclaration type = ParseUtilCSharp.ParseGlobal<TypeDeclaration>(program);
var attr = type.Attributes.Single().Attributes.Single();
Assert.IsFalse(attr.GetChildByRole(AstNode.Roles.LPar).IsNull);
Assert.IsFalse(attr.GetChildByRole(AstNode.Roles.RPar).IsNull);
}
[Test] [Test]
public void TwoAttributesInSameSection() public void TwoAttributesInSameSection()
{ {
@ -170,5 +190,17 @@ public class Form1 {
} }
}}); }});
} }
[Test]
public void AssemblyAttributeBeforeNamespace()
{
var cu = new CSharpParser().Parse(new StringReader("using System; [assembly: Attr] namespace X {}"), "code.cs");
Assert.AreEqual(
new Type[] {
typeof(UsingDeclaration),
typeof(AttributeSection),
typeof(NamespaceDeclaration)
}, cu.Children.Select(c => c.GetType()).ToArray());
}
} }
} }

2
ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/DelegateDeclarationTests.cs

@ -53,7 +53,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
TypeParameters = { new TypeParameterDeclaration { Name = "T" } }, TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
Constraints = { Constraints = {
new Constraint { new Constraint {
TypeParameter = "T", TypeParameter = new SimpleType ("T"),
BaseTypes = { new SimpleType("ICloneable") } BaseTypes = { new SimpleType("ICloneable") }
} }
}}); }});

59
ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/PreprocessorDirectiveTests.cs

@ -62,8 +62,63 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
Assert.AreEqual(PreProcessorDirectiveType.Endif, pp.Last().Type); Assert.AreEqual(PreProcessorDirectiveType.Endif, pp.Last().Type);
Assert.AreEqual(string.Empty, pp.Last().Argument); Assert.AreEqual(string.Empty, pp.Last().Argument);
Assert.AreEqual(new TextLocation(4, 2), pp.First().StartLocation); Assert.AreEqual(new TextLocation(4, 2), pp.Last().StartLocation);
Assert.AreEqual(new TextLocation(4, 8), pp.First().EndLocation); Assert.AreEqual(new TextLocation(4, 8), pp.Last().EndLocation);
}
[Test]
public void NestedInactiveIf()
{
string program = @"namespace NS {
#if SOMETHING
class A {
#if B
void M() {}
#endif
}
#endif
}";
NamespaceDeclaration ns = ParseUtilCSharp.ParseGlobal<NamespaceDeclaration>(program);
Assert.AreEqual(0, ns.Members.Count);
Assert.AreEqual(new Role[] {
AstNode.Roles.Keyword,
AstNode.Roles.Identifier,
AstNode.Roles.LBrace,
AstNode.Roles.PreProcessorDirective,
AstNode.Roles.Comment,
AstNode.Roles.PreProcessorDirective,
AstNode.Roles.Comment,
AstNode.Roles.PreProcessorDirective,
AstNode.Roles.Comment,
AstNode.Roles.PreProcessorDirective,
AstNode.Roles.RBrace
}, ns.Children.Select(c => c.Role).ToArray());
}
[Test]
public void CommentOnEndOfIfDirective()
{
string program = @"namespace NS {
#if SOMETHING // comment
class A { }
#endif
}";
NamespaceDeclaration ns = ParseUtilCSharp.ParseGlobal<NamespaceDeclaration>(program);
Assert.AreEqual(0, ns.Members.Count);
Assert.AreEqual(new Role[] {
AstNode.Roles.Keyword,
AstNode.Roles.Identifier,
AstNode.Roles.LBrace,
AstNode.Roles.PreProcessorDirective,
AstNode.Roles.Comment,
AstNode.Roles.Comment,
AstNode.Roles.PreProcessorDirective,
AstNode.Roles.RBrace
}, ns.Children.Select(c => c.Role).ToArray());
Assert.AreEqual(CommentType.SingleLine, ns.GetChildrenByRole(AstNode.Roles.Comment).First().CommentType);
Assert.AreEqual(CommentType.InactiveCode, ns.GetChildrenByRole(AstNode.Roles.Comment).Last().CommentType);
} }
[Test] [Test]

30
ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/TypeDeclarationTests.cs

@ -109,20 +109,20 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
TypeParameters = { new TypeParameterDeclaration { Name = "T" } }, TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
Constraints = { Constraints = {
new Constraint { new Constraint {
TypeParameter = "T", TypeParameter = new SimpleType ("T"),
BaseTypes = { new SimpleType("IMyInterface") } BaseTypes = { new SimpleType("IMyInterface") }
} }
}}); }});
} }
[Test, Ignore ("Mono parser bug.")] [Test]
public void ComplexGenericClassTypeDeclarationTest() public void ComplexGenericInterfaceTypeDeclarationTest()
{ {
ParseUtilCSharp.AssertGlobal( ParseUtilCSharp.AssertGlobal(
"public class Generic<in T, out S> : System.IComparable where S : G<T[]>, new() where T : MyNamespace.IMyInterface", "public interface Generic<in T, out S> : System.IComparable where S : G<T[]>, new() where T : MyNamespace.IMyInterface {}",
new TypeDeclaration { new TypeDeclaration {
Modifiers = Modifiers.Public, Modifiers = Modifiers.Public,
ClassType = ClassType.Class, ClassType = ClassType.Interface,
Name = "Generic", Name = "Generic",
TypeParameters = { TypeParameters = {
new TypeParameterDeclaration { Variance = VarianceModifier.Contravariant, Name = "T" }, new TypeParameterDeclaration { Variance = VarianceModifier.Contravariant, Name = "T" },
@ -136,7 +136,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
}, },
Constraints = { Constraints = {
new Constraint { new Constraint {
TypeParameter = "S", TypeParameter = new SimpleType ("S"),
BaseTypes = { BaseTypes = {
new SimpleType { new SimpleType {
Identifier = "G", Identifier = "G",
@ -146,7 +146,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
} }
}, },
new Constraint { new Constraint {
TypeParameter = "T", TypeParameter = new SimpleType ("T"),
BaseTypes = { BaseTypes = {
new MemberType { new MemberType {
Target = new SimpleType("MyNamespace"), Target = new SimpleType("MyNamespace"),
@ -240,7 +240,7 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2
}, },
Constraints = { Constraints = {
new Constraint { new Constraint {
TypeParameter = "where", TypeParameter = new SimpleType ("where"),
BaseTypes = { BaseTypes = {
new SimpleType { new SimpleType {
Identifier = "partial", Identifier = "partial",
@ -296,16 +296,6 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2
Assert.AreEqual(10, ((PrimitiveExpression)member.Initializer).Value); Assert.AreEqual(10, ((PrimitiveExpression)member.Initializer).Value);
} }
[Test]
public void EnumWithInitializerAndWindowsNewline()
{
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("enum MyEnum { Val1 = 10\r\n}");
EnumMemberDeclaration member = (EnumMemberDeclaration)td.Members.Single();
Assert.AreEqual("Val1", member.Name);
Assert.AreEqual(10, ((PrimitiveExpression)member.Initializer).Value);
Assert.AreEqual("10", ((PrimitiveExpression)member.Initializer).LiteralValue);
}
[Test] [Test]
public void EnumWithBaseType() public void EnumWithBaseType()
{ {
@ -314,7 +304,7 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2
Assert.AreEqual("short", ((PrimitiveType)td.BaseTypes.Single()).Keyword); Assert.AreEqual("short", ((PrimitiveType)td.BaseTypes.Single()).Keyword);
} }
[Test] [Test, Ignore("Mono parser crash")]
public void EnumWithIncorrectNewlineAfterIntegerLiteral() public void EnumWithIncorrectNewlineAfterIntegerLiteral()
{ {
ParseUtilCSharp.AssertGlobal( ParseUtilCSharp.AssertGlobal(
@ -361,7 +351,7 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2
}, td.Children.Select(c => c.Role).ToArray()); }, td.Children.Select(c => c.Role).ToArray());
} }
[Test] [Test, Ignore("Parser bug (incorrectly creates a comma at the end of the enum)")]
public void EnumWithSemicolonAtEnd() public void EnumWithSemicolonAtEnd()
{ {
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("enum MyEnum { A };"); TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("enum MyEnum { A };");

2
ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseSelfTests.cs

@ -70,7 +70,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser
string currentFileName; string currentFileName;
ReadOnlyDocument currentDocument; ReadOnlyDocument currentDocument;
[Test] [Test, Ignore("Positions still are incorrect in several cases")]
public void ParseAndCheckPositions() public void ParseAndCheckPositions()
{ {
CSharpParser parser = new CSharpParser(); CSharpParser parser = new CSharpParser();

4
ICSharpCode.NRefactory.Tests/CSharp/Parser/Statements/VariableDeclarationStatementTests.cs

@ -191,14 +191,14 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
Assert.AreEqual(20, lvd.EndLocation.Column); Assert.AreEqual(20, lvd.EndLocation.Column);
} }
[Test, Ignore("Nested arrays are broken in the parser")] [Test]
public void NestedArray() public void NestedArray()
{ {
VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement<VariableDeclarationStatement>("DateTime[,][] a;"); VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement<VariableDeclarationStatement>("DateTime[,][] a;");
Assert.IsTrue(new VariableDeclarationStatement(new SimpleType("DateTime").MakeArrayType(1).MakeArrayType(2), "a").IsMatch(lvd)); Assert.IsTrue(new VariableDeclarationStatement(new SimpleType("DateTime").MakeArrayType(1).MakeArrayType(2), "a").IsMatch(lvd));
} }
[Test, Ignore("Nested pointers are broken in the parser")] [Test]
public void NestedPointers() public void NestedPointers()
{ {
VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement<VariableDeclarationStatement>("DateTime*** a;"); VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement<VariableDeclarationStatement>("DateTime*** a;");

6
ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/MethodDeclarationTests.cs

@ -149,7 +149,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") }, Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
Constraints = { Constraints = {
new Constraint { new Constraint {
TypeParameter = "T", TypeParameter = new SimpleType ("T"),
BaseTypes = { new SimpleType("ISomeInterface") } BaseTypes = { new SimpleType("ISomeInterface") }
} }
}, },
@ -176,7 +176,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") }, Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
Constraints = { Constraints = {
new Constraint { new Constraint {
TypeParameter = "T", TypeParameter = new SimpleType ("T"),
BaseTypes = { new SimpleType("ISomeInterface") } BaseTypes = { new SimpleType("ISomeInterface") }
} }
} }
@ -202,7 +202,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") }, Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
Constraints = { Constraints = {
new Constraint { new Constraint {
TypeParameter = "T", TypeParameter = new SimpleType ("T"),
BaseTypes = { new SimpleType("ISomeInterface") } BaseTypes = { new SimpleType("ISomeInterface") }
} }
} }

7
ICSharpCode.NRefactory.Tests/CSharp/Refactoring/TypeSystemAstBuilderTests.cs

@ -78,11 +78,8 @@ namespace OtherNS {
TypeSystemAstBuilder CreateBuilder(ITypeDefinition currentTypeDef = null) TypeSystemAstBuilder CreateBuilder(ITypeDefinition currentTypeDef = null)
{ {
UsingScope usingScope = currentTypeDef != null ? parsedFile.GetUsingScope(currentTypeDef.Region.Begin) : parsedFile.RootUsingScope; UsingScope usingScope = currentTypeDef != null ? parsedFile.GetUsingScope(currentTypeDef.Region.Begin) : parsedFile.RootUsingScope;
return new TypeSystemAstBuilder( return new TypeSystemAstBuilder(new CSharpResolver(
new CSharpResolver(compilation) { new CSharpTypeResolveContext(compilation.MainAssembly, usingScope.Resolve(compilation), currentTypeDef)));
CurrentUsingScope = usingScope.Resolve(compilation),
CurrentTypeDefinition = currentTypeDef
});
} }
string TypeToString(IType type, ITypeDefinition currentTypeDef = null) string TypeToString(IType type, ITypeDefinition currentTypeDef = null)

6
ICSharpCode.NRefactory.Tests/CSharp/Resolver/BinaryOperatorTests.cs

@ -152,12 +152,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test] [Test]
public void AdditionWithOverflow() public void AdditionWithOverflow()
{ {
resolver.CheckForOverflow = false; AssertConstant(int.MinValue, resolver.WithCheckForOverflow(false).ResolveBinaryOperator(
AssertConstant(int.MinValue, resolver.ResolveBinaryOperator(
BinaryOperatorType.Add, MakeConstant(int.MaxValue), MakeConstant(1))); BinaryOperatorType.Add, MakeConstant(int.MaxValue), MakeConstant(1)));
resolver.CheckForOverflow = true; AssertError(typeof(int), resolver.WithCheckForOverflow(true).ResolveBinaryOperator(
AssertError(typeof(int), resolver.ResolveBinaryOperator(
BinaryOperatorType.Add, MakeConstant(int.MaxValue), MakeConstant(1))); BinaryOperatorType.Add, MakeConstant(int.MaxValue), MakeConstant(1)));
} }

9
ICSharpCode.NRefactory.Tests/CSharp/Resolver/CastTests.cs

@ -81,10 +81,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test] [Test]
public void OverflowingCast() public void OverflowingCast()
{ {
resolver.CheckForOverflow = false; AssertConstant(uint.MaxValue, resolver.WithCheckForOverflow(false).ResolveCast(ResolveType(typeof(uint)), MakeConstant(-1.6)));
AssertConstant(uint.MaxValue, resolver.ResolveCast(ResolveType(typeof(uint)), MakeConstant(-1.6))); AssertError(typeof(uint), resolver.WithCheckForOverflow(true).ResolveCast(ResolveType(typeof(uint)), MakeConstant(-1.6)));
resolver.CheckForOverflow = true;
AssertError(typeof(uint), resolver.ResolveCast(ResolveType(typeof(uint)), MakeConstant(-1.6)));
} }
[Test] [Test]
@ -96,8 +94,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test] [Test]
public void OverflowingCastToEnum() public void OverflowingCastToEnum()
{ {
resolver.CheckForOverflow = true; AssertError(typeof(StringComparison), resolver.WithCheckForOverflow(true).ResolveCast(ResolveType(typeof(StringComparison)), MakeConstant(long.MaxValue)));
AssertError(typeof(StringComparison), resolver.ResolveCast(ResolveType(typeof(StringComparison)), MakeConstant(long.MaxValue)));
} }
} }
} }

73
ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs

@ -36,8 +36,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public override void SetUp() public override void SetUp()
{ {
base.SetUp(); base.SetUp();
resolver = new CSharpResolver(compilation); resolver = new CSharpResolver(compilation).WithCurrentUsingScope(MakeUsingScope(string.Empty));
resolver.CurrentUsingScope = MakeUsingScope(string.Empty);
} }
ResolvedUsingScope MakeUsingScope(string namespaceName = "", string[] usings = null, KeyValuePair<string, string>[] usingAliases = null) ResolvedUsingScope MakeUsingScope(string namespaceName = "", string[] usings = null, KeyValuePair<string, string>[] usingAliases = null)
@ -56,15 +55,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
foreach (var pair in usingAliases) foreach (var pair in usingAliases)
usingScope.UsingAliases.Add(new KeyValuePair<string, TypeOrNamespaceReference>(pair.Key, MakeReference(pair.Value))); usingScope.UsingAliases.Add(new KeyValuePair<string, TypeOrNamespaceReference>(pair.Key, MakeReference(pair.Value)));
} }
return usingScope.Resolve(resolver.Compilation); return usingScope.Resolve(compilation);
} }
[Test] [Test]
public void SimpleNameLookupWithoutContext() public void SimpleNameLookupWithoutContext()
{ {
// nothing should be found without specifying any UsingScope - however, the resolver also must not crash // nothing should be found without specifying any UsingScope - however, the resolver also must not crash
resolver.CurrentUsingScope = null; Assert.IsTrue(resolver.WithCurrentUsingScope(null).ResolveSimpleName("System", new IType[0]).IsError);
Assert.IsTrue(resolver.ResolveSimpleName("System", new IType[0]).IsError);
} }
[Test] [Test]
@ -78,23 +76,23 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test] [Test]
public void NamespaceInParentNamespaceLookup() public void NamespaceInParentNamespaceLookup()
{ {
resolver.CurrentUsingScope = MakeUsingScope("System.Collections.Generic"); var resolverWithUsing = resolver.WithCurrentUsingScope(MakeUsingScope("System.Collections.Generic"));
NamespaceResolveResult nrr = (NamespaceResolveResult)resolver.ResolveSimpleName("Text", new IType[0]); NamespaceResolveResult nrr = (NamespaceResolveResult)resolverWithUsing.ResolveSimpleName("Text", new IType[0]);
Assert.AreEqual("System.Text", nrr.NamespaceName); Assert.AreEqual("System.Text", nrr.NamespaceName);
} }
[Test] [Test]
public void NamespacesAreNotImported() public void NamespacesAreNotImported()
{ {
resolver.CurrentUsingScope = MakeUsingScope(usings: new [] { "System" }); var resolverWithUsing = resolver.WithCurrentUsingScope(MakeUsingScope(usings: new [] { "System" }));
Assert.IsTrue(resolver.ResolveSimpleName("Collections", new IType[0]).IsError); Assert.IsTrue(resolverWithUsing.ResolveSimpleName("Collections", new IType[0]).IsError);
} }
[Test] [Test]
public void ImportedType() public void ImportedType()
{ {
resolver.CurrentUsingScope = MakeUsingScope(usings: new [] { "System" }); var resolverWithUsing = resolver.WithCurrentUsingScope(MakeUsingScope(usings: new [] { "System" }));
TypeResolveResult trr = (TypeResolveResult)resolver.ResolveSimpleName("String", new IType[0]); TypeResolveResult trr = (TypeResolveResult)resolverWithUsing.ResolveSimpleName("String", new IType[0]);
Assert.AreEqual("System.String", trr.Type.FullName); Assert.AreEqual("System.String", trr.Type.FullName);
} }
@ -122,8 +120,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test] [Test]
public void AliasToImportedType() public void AliasToImportedType()
{ {
resolver.CurrentUsingScope = MakeUsingScope(usings: new [] { "System" }, usingAliases: new [] { new KeyValuePair<string, string>( "x", "String" )}); var resolverWithUsing = resolver.WithCurrentUsingScope(MakeUsingScope(usings: new [] { "System" }, usingAliases: new [] { new KeyValuePair<string, string>( "x", "String" )}));
UnknownIdentifierResolveResult rr = (UnknownIdentifierResolveResult)resolver.ResolveSimpleName("x", new IType[0]); UnknownIdentifierResolveResult rr = (UnknownIdentifierResolveResult)resolverWithUsing.ResolveSimpleName("x", new IType[0]);
// Unknown identifier (as String isn't looked up in System) // Unknown identifier (as String isn't looked up in System)
Assert.AreEqual("String", rr.Identifier); Assert.AreEqual("String", rr.Identifier);
} }
@ -135,24 +133,24 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
mainUsingScope.Usings.Add(MakeReference("System")); mainUsingScope.Usings.Add(MakeReference("System"));
UsingScope nestedUsingScope = new UsingScope(mainUsingScope, "SomeNamespace"); UsingScope nestedUsingScope = new UsingScope(mainUsingScope, "SomeNamespace");
nestedUsingScope.UsingAliases.Add(new KeyValuePair<string, TypeOrNamespaceReference>("x", MakeReference("String"))); nestedUsingScope.UsingAliases.Add(new KeyValuePair<string, TypeOrNamespaceReference>("x", MakeReference("String")));
resolver.CurrentUsingScope = nestedUsingScope.Resolve(compilation); var resolverWithUsing = resolver.WithCurrentUsingScope(nestedUsingScope.Resolve(compilation));
TypeResolveResult trr = (TypeResolveResult)resolver.ResolveSimpleName("x", new IType[0]); TypeResolveResult trr = (TypeResolveResult)resolverWithUsing.ResolveSimpleName("x", new IType[0]);
Assert.AreEqual("System.String", trr.Type.FullName); Assert.AreEqual("System.String", trr.Type.FullName);
} }
[Test] [Test]
public void AliasOperatorOnTypeAlias() public void AliasOperatorOnTypeAlias()
{ {
resolver.CurrentUsingScope = MakeUsingScope(usingAliases: new [] { new KeyValuePair<string, string>( "x", "System.String" )}); var resolverWithUsing = resolver.WithCurrentUsingScope(MakeUsingScope(usingAliases: new [] { new KeyValuePair<string, string>( "x", "System.String" )}));
Assert.IsTrue(resolver.ResolveAlias("x").IsError); Assert.IsTrue(resolverWithUsing.ResolveAlias("x").IsError);
} }
[Test] [Test]
public void AliasOperatorOnNamespaceAlias() public void AliasOperatorOnNamespaceAlias()
{ {
resolver.CurrentUsingScope = MakeUsingScope(usingAliases: new [] { new KeyValuePair<string, string>( "x", "System.Collections.Generic" )}); var resolverWithUsing = resolver.WithCurrentUsingScope(MakeUsingScope(usingAliases: new [] { new KeyValuePair<string, string>( "x", "System.Collections.Generic" )}));
NamespaceResolveResult nrr = (NamespaceResolveResult)resolver.ResolveAlias("x"); NamespaceResolveResult nrr = (NamespaceResolveResult)resolverWithUsing.ResolveAlias("x");
Assert.AreEqual("System.Collections.Generic", nrr.NamespaceName); Assert.AreEqual("System.Collections.Generic", nrr.NamespaceName);
} }
@ -165,32 +163,34 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test] [Test]
public void FindClassInCurrentNamespace() public void FindClassInCurrentNamespace()
{ {
resolver.CurrentUsingScope = MakeUsingScope("System.Collections"); var resolverWithUsing = resolver.WithCurrentUsingScope(MakeUsingScope("System.Collections"));
TypeResolveResult trr = (TypeResolveResult)resolver.ResolveSimpleName("String", new IType[0]); TypeResolveResult trr = (TypeResolveResult)resolverWithUsing.ResolveSimpleName("String", new IType[0]);
Assert.AreEqual("System.String", trr.Type.FullName); Assert.AreEqual("System.String", trr.Type.FullName);
} }
[Test] [Test]
public void FindNeighborNamespace() public void FindNeighborNamespace()
{ {
resolver.CurrentUsingScope = MakeUsingScope("System.Collections"); var resolverWithUsing = resolver.WithCurrentUsingScope(MakeUsingScope("System.Collections"));
NamespaceResolveResult nrr = (NamespaceResolveResult)resolver.ResolveSimpleName("Text", new IType[0]); NamespaceResolveResult nrr = (NamespaceResolveResult)resolverWithUsing.ResolveSimpleName("Text", new IType[0]);
Assert.AreEqual("System.Text", nrr.NamespaceName); Assert.AreEqual("System.Text", nrr.NamespaceName);
} }
[Test] [Test]
public void FindTypeParameters() public void FindTypeParameters()
{ {
resolver.CurrentUsingScope = MakeUsingScope("System.Collections.Generic"); var listOfT = compilation.FindType(typeof(List<>)).GetDefinition();
resolver.CurrentTypeDefinition = compilation.FindType(typeof(List<>)).GetDefinition(); var resolverWithContext = resolver
resolver.CurrentMember = resolver.CurrentTypeDefinition.Methods.Single(m => m.Name == "ConvertAll"); .WithCurrentUsingScope(MakeUsingScope("System.Collections.Generic"))
.WithCurrentTypeDefinition(listOfT)
.WithCurrentMember(listOfT.Methods.Single(m => m.Name == "ConvertAll"));
TypeResolveResult trr; TypeResolveResult trr;
trr = (TypeResolveResult)resolver.ResolveSimpleName("TOutput", new IType[0]); trr = (TypeResolveResult)resolverWithContext.ResolveSimpleName("TOutput", new IType[0]);
Assert.AreSame(((IMethod)resolver.CurrentMember).TypeParameters[0], trr.Type); Assert.AreSame(((IMethod)resolverWithContext.CurrentMember).TypeParameters[0], trr.Type);
trr = (TypeResolveResult)resolver.ResolveSimpleName("T", new IType[0]); trr = (TypeResolveResult)resolverWithContext.ResolveSimpleName("T", new IType[0]);
Assert.AreSame(resolver.CurrentTypeDefinition.TypeParameters[0], trr.Type); Assert.AreSame(resolverWithContext.CurrentTypeDefinition.TypeParameters[0], trr.Type);
} }
[Test] [Test]
@ -900,6 +900,19 @@ class B
Assert.AreEqual("Test.Base", result.Type.FullName); Assert.AreEqual("Test.Base", result.Type.FullName);
} }
[Test]
public void InnerClassInheritingFromProtectedBaseInnerClassShouldNotCauseStackOverflow()
{
string program = @"class Base {
protected class NestedBase {}
}
class Derived : Base {
class NestedDerived : $NestedBase$ { }
}";
var result = Resolve<TypeResolveResult>(program);
Assert.AreEqual("Base.NestedBase", result.Type.FullName);
}
[Test] [Test]
public void EnumMembersHaveUnderlyingTypeWithinInitializers_MemberFromSameEnum() public void EnumMembersHaveUnderlyingTypeWithinInitializers_MemberFromSameEnum()
{ {

24
ICSharpCode.NRefactory.Tests/CSharp/Resolver/UnaryOperatorTests.cs

@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using NUnit.Framework; using NUnit.Framework;
@ -141,8 +142,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test] [Test]
public void TestUnaryMinusCheckedOverflow() public void TestUnaryMinusCheckedOverflow()
{ {
resolver.CheckForOverflow = true; AssertError(typeof(int), resolver.WithCheckForOverflow(true).ResolveUnaryOperator(UnaryOperatorType.Minus, MakeConstant(-2147483648)));
AssertError(typeof(int), resolver.ResolveUnaryOperator(UnaryOperatorType.Minus, MakeConstant(-2147483648)));
} }
[Test] [Test]
@ -212,5 +212,25 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
AssertType(typeof(StringComparison), resolver.ResolveUnaryOperator(UnaryOperatorType.BitNot, MakeResult(typeof(StringComparison)))); AssertType(typeof(StringComparison), resolver.ResolveUnaryOperator(UnaryOperatorType.BitNot, MakeResult(typeof(StringComparison))));
AssertType(typeof(StringComparison?), resolver.ResolveUnaryOperator(UnaryOperatorType.BitNot, MakeResult(typeof(StringComparison?)))); AssertType(typeof(StringComparison?), resolver.ResolveUnaryOperator(UnaryOperatorType.BitNot, MakeResult(typeof(StringComparison?))));
} }
[Test]
public void IntMinValue()
{
// int:
AssertConstant(-2147483648, Resolve("class A { object x = $-2147483648$; }"));
AssertConstant(-/**/2147483648, Resolve("class A { object x = $-/**/2147483648$; }"));
// long:
AssertConstant(-2147483648L, Resolve("class A { object x = $-2147483648L$; }"));
AssertConstant(-(2147483648), Resolve("class A { object x = $-(2147483648)$; }"));
}
[Test]
public void LongMinValue()
{
// long:
AssertConstant(-9223372036854775808, Resolve("class A { object x = $-9223372036854775808$; }"));
// compiler error:
AssertError(typeof(ulong), Resolve("class A { object x = $-(9223372036854775808)$; }"));
}
} }
} }

2
ICSharpCode.NRefactory.Tests/FormattingTests/TestFormattingBugs.cs

@ -133,7 +133,7 @@ using (IDisposable b = null) {
int start = result.GetOffset (5, 1); int start = result.GetOffset (5, 1);
int end = result.GetOffset (result.LineCount - 1, 1); int end = result.GetOffset (result.LineCount - 1, 1);
string text = result.GetText (start, end - start).Trim (); string text = result.GetText (start, end - start).Trim ();
expectedOutput = expectedOutput.Replace ("\n", "\n\t\t"); expectedOutput = NormalizeNewlines(expectedOutput).Replace ("\n", "\n\t\t");
Assert.AreEqual (expectedOutput, text); Assert.AreEqual (expectedOutput, text);
} }

24
ICSharpCode.NRefactory.Tests/FormattingTests/TestSpacingVisitor.cs

@ -1100,12 +1100,12 @@ return (Test)null;
} }
}"); }");
Assert.AreEqual (@"class Test Assert.AreEqual (NormalizeNewlines(@"class Test
{ {
Test () Test ()
{ {
} }
}", result.Text); }"), result.Text);
} }
[Test()] [Test()]
@ -1290,13 +1290,13 @@ return (Test)null;
} }
}"); }");
Assert.AreEqual (@"class FooBar Assert.AreEqual (NormalizeNewlines(@"class FooBar
{ {
public void Foo () public void Foo ()
{ {
Test (); Test ();
} }
}", result.Text); }"), result.Text);
} }
[Test()] [Test()]
@ -1403,14 +1403,14 @@ return (Test)null;
} }
} }
}"); }");
Assert.AreEqual (@"class FooBar Assert.AreEqual (NormalizeNewlines(@"class FooBar
{ {
public int this [int a, int b] { public int this [int a, int b] {
get { get {
return a + b; return a + b;
} }
} }
}", result.Text); }"), result.Text);
} }
[Test()] [Test()]
@ -1489,13 +1489,13 @@ return (Test)null;
this[0] = 5; this[0] = 5;
} }
}"); }");
Assert.AreEqual (@"class Test Assert.AreEqual (NormalizeNewlines(@"class Test
{ {
void TestMe () void TestMe ()
{ {
this[ 0 ] = 5; this[ 0 ] = 5;
} }
}", result.Text); }"), result.Text);
} }
@ -1513,13 +1513,13 @@ return (Test)null;
this[0] = 5; this[0] = 5;
} }
}"); }");
Assert.AreEqual (@"class Test Assert.AreEqual (NormalizeNewlines(@"class Test
{ {
void TestMe () void TestMe ()
{ {
this [0] = 5; this [0] = 5;
} }
}", result.Text); }"), result.Text);
} }
@ -1574,11 +1574,11 @@ return (Test)null;
int[][] b; int[][] b;
}"); }");
Assert.AreEqual (@"class Test Assert.AreEqual (NormalizeNewlines(@"class Test
{ {
int [] a; int [] a;
int [][] b; int [][] b;
}", result.Text); }"), result.Text);
} }

14
ICSharpCode.NRefactory.Tests/FormattingTests/TextEditorTestAdapter.cs

@ -37,7 +37,7 @@ namespace ICSharpCode.NRefactory.FormattingTests
changes.Sort ((x, y) => y.Offset.CompareTo (x.Offset)); changes.Sort ((x, y) => y.Offset.CompareTo (x.Offset));
StringBuilder b = new StringBuilder(text); StringBuilder b = new StringBuilder(text);
foreach (var change in changes) { foreach (var change in changes) {
// Console.WriteLine ("---- apply:" + change); //Console.WriteLine ("---- apply:" + change);
// Console.WriteLine (adapter.Text); // Console.WriteLine (adapter.Text);
if (change.Offset > b.Length) if (change.Offset > b.Length)
continue; continue;
@ -51,9 +51,10 @@ namespace ICSharpCode.NRefactory.FormattingTests
protected static IDocument GetResult (CSharpFormattingOptions policy, string input) protected static IDocument GetResult (CSharpFormattingOptions policy, string input)
{ {
input = NormalizeNewlines(input);
var adapter = new ReadOnlyDocument (input); var adapter = new ReadOnlyDocument (input);
var visitor = new AstFormattingVisitor (policy, adapter, factory); var visitor = new AstFormattingVisitor (policy, adapter, factory);
visitor.EolMarker = "\n";
var compilationUnit = new CSharpParser ().Parse (new StringReader (input), "test.cs"); var compilationUnit = new CSharpParser ().Parse (new StringReader (input), "test.cs");
compilationUnit.AcceptVisitor (visitor, null); compilationUnit.AcceptVisitor (visitor, null);
@ -62,6 +63,7 @@ namespace ICSharpCode.NRefactory.FormattingTests
protected static IDocument Test (CSharpFormattingOptions policy, string input, string expectedOutput) protected static IDocument Test (CSharpFormattingOptions policy, string input, string expectedOutput)
{ {
expectedOutput = NormalizeNewlines(expectedOutput);
IDocument doc = GetResult(policy, input); IDocument doc = GetResult(policy, input);
if (expectedOutput != doc.Text) { if (expectedOutput != doc.Text) {
Console.WriteLine (doc.Text); Console.WriteLine (doc.Text);
@ -69,11 +71,17 @@ namespace ICSharpCode.NRefactory.FormattingTests
Assert.AreEqual (expectedOutput, doc.Text); Assert.AreEqual (expectedOutput, doc.Text);
return doc; return doc;
} }
protected static string NormalizeNewlines(string input)
{
return input.Replace("\r\n", "\n");
}
protected static void Continue (CSharpFormattingOptions policy, IDocument document, string expectedOutput) protected static void Continue (CSharpFormattingOptions policy, IDocument document, string expectedOutput)
{ {
expectedOutput = NormalizeNewlines(expectedOutput);
var visitior = new AstFormattingVisitor (policy, document, factory); var visitior = new AstFormattingVisitor (policy, document, factory);
visitior.EolMarker = "\n";
var compilationUnit = new CSharpParser ().Parse (new StringReader (document.Text), "test.cs"); var compilationUnit = new CSharpParser ().Parse (new StringReader (document.Text), "test.cs");
compilationUnit.AcceptVisitor (visitior, null); compilationUnit.AcceptVisitor (visitior, null);
string newText = ApplyChanges (document.Text, visitior.Changes); string newText = ApplyChanges (document.Text, visitior.Changes);

1
ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs

@ -314,6 +314,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
var ctors = compilation.FindType(typeof(MyStructWithCtor)).GetConstructors(); var ctors = compilation.FindType(typeof(MyStructWithCtor)).GetConstructors();
Assert.AreEqual(2, ctors.Count()); Assert.AreEqual(2, ctors.Count());
Assert.IsFalse(ctors.Any(c => c.IsStatic)); Assert.IsFalse(ctors.Any(c => c.IsStatic));
Assert.IsTrue(ctors.All(c => c.ReturnType.Kind == TypeKind.Void));
} }
[Test] [Test]

2
ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs

@ -2062,7 +2062,7 @@ namespace ICSharpCode.NRefactory.VB.Visitors
var constraint = typeParameterDeclaration.Parent var constraint = typeParameterDeclaration.Parent
.GetChildrenByRole(CSharp.AstNode.Roles.Constraint) .GetChildrenByRole(CSharp.AstNode.Roles.Constraint)
.SingleOrDefault(c => c.TypeParameter == typeParameterDeclaration.Name); .SingleOrDefault(c => c.TypeParameter.Identifier == typeParameterDeclaration.Name);
if (constraint != null) if (constraint != null)
ConvertNodes(constraint.BaseTypes, param.Constraints); ConvertNodes(constraint.BaseTypes, param.Constraints);

5
ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs

@ -1645,10 +1645,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
} }
} }
if (method.IsConstructor) m.ReturnType = ReadTypeReference(method.ReturnType, typeAttributes: method.MethodReturnType);
m.ReturnType = parentType;
else
m.ReturnType = ReadTypeReference(method.ReturnType, typeAttributes: method.MethodReturnType);
if (HasAnyAttributes(method)) if (HasAnyAttributes(method))
AddAttributes(method, m.Attributes, m.ReturnTypeAttributes); AddAttributes(method, m.Attributes, m.ReturnTypeAttributes);

36
ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs

@ -172,6 +172,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
throw new ArgumentNullException("compilation"); throw new ArgumentNullException("compilation");
if (typeDefinition == null) if (typeDefinition == null)
return null; return null;
if (typeDefinition.Compilation == compilation)
return typeDefinition;
return typeDefinition.ToTypeReference().Resolve(compilation.TypeResolveContext).GetDefinition(); return typeDefinition.ToTypeReference().Resolve(compilation.TypeResolveContext).GetDefinition();
} }
@ -184,8 +186,42 @@ namespace ICSharpCode.NRefactory.TypeSystem
throw new ArgumentNullException("compilation"); throw new ArgumentNullException("compilation");
if (member == null) if (member == null)
return null; return null;
if (member.Compilation == compilation)
return member;
return member.ToMemberReference().Resolve(compilation.TypeResolveContext); return member.ToMemberReference().Resolve(compilation.TypeResolveContext);
} }
/// <summary>
/// Imports a member from another compilation.
/// </summary>
public static IMethod Import(this ICompilation compilation, IMethod method)
{
return (IMethod)compilation.Import((IMember)method);
}
/// <summary>
/// Imports a member from another compilation.
/// </summary>
public static IField Import(this ICompilation compilation, IField field)
{
return (IField)compilation.Import((IMember)field);
}
/// <summary>
/// Imports a member from another compilation.
/// </summary>
public static IEvent Import(this ICompilation compilation, IEvent ev)
{
return (IEvent)compilation.Import((IMember)ev);
}
/// <summary>
/// Imports a member from another compilation.
/// </summary>
public static IProperty Import(this ICompilation compilation, IProperty property)
{
return (IProperty)compilation.Import((IMember)property);
}
#endregion #endregion
#region GetDelegateInvokeMethod #region GetDelegateInvokeMethod

5
ICSharpCode.NRefactory/TypeSystem/IParsedFile.cs

@ -73,5 +73,10 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// Gets the parser errors. /// Gets the parser errors.
/// </summary> /// </summary>
IList<Error> Errors { get; } IList<Error> Errors { get; }
/// <summary>
/// Gets a type resolve context at a given location.
/// </summary>
ITypeResolveContext GetTypeResolveContext (ICompilation compilation, TextLocation loc);
} }
} }

24
ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractResolvedTypeParameter.cs

@ -232,14 +232,30 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return EmptyList<IType>.Instance; return EmptyList<IType>.Instance;
} }
static readonly IUnresolvedMethod dummyConstructor = CreateDummyConstructor();
static IUnresolvedMethod CreateDummyConstructor()
{
var m = new DefaultUnresolvedMethod {
EntityType = EntityType.Constructor,
Name = ".ctor",
Accessibility = Accessibility.Public,
IsSynthetic = true,
ReturnType = KnownTypeReference.Void
};
m.Freeze();
return m;
}
public IEnumerable<IMethod> GetConstructors(Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.IgnoreInheritedMembers) public IEnumerable<IMethod> GetConstructors(Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.IgnoreInheritedMembers)
{ {
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) { if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
if (this.HasDefaultConstructorConstraint || this.HasValueTypeConstraint) { if (this.HasDefaultConstructorConstraint || this.HasValueTypeConstraint) {
throw new NotImplementedException(); if (filter == null || filter(dummyConstructor)) {
//DefaultMethod m = DefaultMethod.CreateDefaultConstructor(GetDummyClassForTypeParameter(constraints)); var resolvedCtor = (IMethod)dummyConstructor.CreateResolved(compilation.TypeResolveContext);
//if (filter(m)) IMethod m = new SpecializedMethod(this, resolvedCtor, EmptyList<IType>.Instance);
// return new [] { m }; return new [] { m };
}
} }
return EmptyList<IMethod>.Instance; return EmptyList<IMethod>.Instance;
} else { } else {

4
ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractUnresolvedMember.cs

@ -28,7 +28,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
[Serializable] [Serializable]
public abstract class AbstractUnresolvedMember : AbstractUnresolvedEntity, IUnresolvedMember public abstract class AbstractUnresolvedMember : AbstractUnresolvedEntity, IUnresolvedMember
{ {
ITypeReference returnType; ITypeReference returnType = SpecialType.UnknownType;
IList<IMemberReference> interfaceImplementations; IList<IMemberReference> interfaceImplementations;
public override void ApplyInterningProvider(IInterningProvider provider) public override void ApplyInterningProvider(IInterningProvider provider)
@ -67,6 +67,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public ITypeReference ReturnType { public ITypeReference ReturnType {
get { return returnType; } get { return returnType; }
set { set {
if (value == null)
throw new ArgumentNullException();
ThrowIfFrozen(); ThrowIfFrozen();
returnType = value; returnType = value;
} }

6
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedField.cs

@ -51,7 +51,11 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
get { get {
ResolveResult rr = this.constantValue; ResolveResult rr = this.constantValue;
if (rr == null) { if (rr == null) {
rr = ((IUnresolvedField)unresolved).ConstantValue.Resolve(context); IConstantValue unresolvedCV = ((IUnresolvedField)unresolved).ConstantValue;
if (unresolvedCV != null)
rr = unresolvedCV.Resolve(context);
else
rr = ErrorResolveResult.UnknownError;
this.constantValue = rr; this.constantValue = rr;
} }
return rr.ConstantValue; return rr.ConstantValue;

76
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs

@ -290,45 +290,51 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
LazyInit.ReadBarrier(); LazyInit.ReadBarrier();
return result; return result;
} else { } else {
result = new List<IType>(); result = CalculateDirectBaseTypes();
bool hasNonInterface = false; return LazyInit.GetOrSet(ref this.directBaseTypes, result);
if (this.Kind != TypeKind.Enum) { }
foreach (var part in parts) { }
var context = part.CreateResolveContext(parentContext).WithCurrentTypeDefinition(this); }
foreach (var baseTypeRef in part.BaseTypes) {
IType baseType = baseTypeRef.Resolve(context); IList<IType> CalculateDirectBaseTypes()
if (!(baseType.Kind == TypeKind.Unknown || result.Contains(baseType))) { {
result.Add(baseType); List<IType> result = new List<IType>();
if (baseType.Kind != TypeKind.Interface) bool hasNonInterface = false;
hasNonInterface = true; if (this.Kind != TypeKind.Enum) {
} foreach (var part in parts) {
} var context = part.CreateResolveContext(parentContext).WithCurrentTypeDefinition(this);
} foreach (var baseTypeRef in part.BaseTypes) {
} IType baseType = baseTypeRef.Resolve(context);
if (!hasNonInterface && !(this.Name == "Object" && this.Namespace == "System" && this.TypeParameterCount == 0)) { if (!(baseType.Kind == TypeKind.Unknown || result.Contains(baseType))) {
KnownTypeCode primitiveBaseType; result.Add(baseType);
switch (this.Kind) { if (baseType.Kind != TypeKind.Interface)
case TypeKind.Enum: hasNonInterface = true;
primitiveBaseType = KnownTypeCode.Enum;
break;
case TypeKind.Struct:
case TypeKind.Void:
primitiveBaseType = KnownTypeCode.ValueType;
break;
case TypeKind.Delegate:
primitiveBaseType = KnownTypeCode.Delegate;
break;
default:
primitiveBaseType = KnownTypeCode.Object;
break;
} }
IType t = parentContext.Compilation.FindType(primitiveBaseType);
if (t.Kind != TypeKind.Unknown)
result.Add(t);
} }
return LazyInit.GetOrSet(ref this.directBaseTypes, result);
} }
} }
if (!hasNonInterface && !(this.Name == "Object" && this.Namespace == "System" && this.TypeParameterCount == 0)) {
KnownTypeCode primitiveBaseType;
switch (this.Kind) {
case TypeKind.Enum:
primitiveBaseType = KnownTypeCode.Enum;
break;
case TypeKind.Struct:
case TypeKind.Void:
primitiveBaseType = KnownTypeCode.ValueType;
break;
case TypeKind.Delegate:
primitiveBaseType = KnownTypeCode.Delegate;
break;
default:
primitiveBaseType = KnownTypeCode.Object;
break;
}
IType t = parentContext.Compilation.FindType(primitiveBaseType);
if (t.Kind != TypeKind.Unknown)
result.Add(t);
}
return result;
} }
#endregion #endregion

2
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedAssembly.cs

@ -105,7 +105,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public IUnresolvedTypeDefinition GetTypeDefinition(string ns, string name, int typeParameterCount) public IUnresolvedTypeDefinition GetTypeDefinition(string ns, string name, int typeParameterCount)
{ {
var key = new FullNameAndTypeParameterCount(ns, name, typeParameterCount); var key = new FullNameAndTypeParameterCount(ns ?? string.Empty, name, typeParameterCount);
IUnresolvedTypeDefinition td; IUnresolvedTypeDefinition td;
if (typeDefinitions.TryGetValue(key, out td)) if (typeDefinitions.TryGetValue(key, out td))
return td; return td;

2
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedMethod.cs

@ -142,7 +142,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
Accessibility = typeDefinition.IsAbstract ? Accessibility.Protected : Accessibility.Public, Accessibility = typeDefinition.IsAbstract ? Accessibility.Protected : Accessibility.Public,
IsSynthetic = true, IsSynthetic = true,
Region = region, Region = region,
ReturnType = typeDefinition ReturnType = KnownTypeReference.Void
}; };
} }
} }

18
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedTypeDefinition.cs

@ -40,6 +40,24 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
this.EntityType = EntityType.TypeDefinition; this.EntityType = EntityType.TypeDefinition;
} }
public DefaultUnresolvedTypeDefinition(string fullName)
{
string namespaceName;
string name;
int idx = fullName.LastIndexOf ('.');
if (idx > 0) {
namespaceName = fullName.Substring (0, idx);
name = fullName.Substring (idx + 1);
} else {
namespaceName = "";
name = fullName;
}
this.EntityType = EntityType.TypeDefinition;
this.namespaceName = namespaceName;
this.Name = name;
}
public DefaultUnresolvedTypeDefinition(string namespaceName, string name) public DefaultUnresolvedTypeDefinition(string namespaceName, string name)
{ {
this.EntityType = EntityType.TypeDefinition; this.EntityType = EntityType.TypeDefinition;

4
ICSharpCode.NRefactory/TypeSystem/Implementation/FullNameAndTypeParameterCount.cs

@ -30,6 +30,10 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public FullNameAndTypeParameterCount(string nameSpace, string name, int typeParameterCount) public FullNameAndTypeParameterCount(string nameSpace, string name, int typeParameterCount)
{ {
if (nameSpace == null)
throw new ArgumentNullException("nameSpace");
if (name == null)
throw new ArgumentNullException("name");
this.Namespace = nameSpace; this.Namespace = nameSpace;
this.Name = name; this.Name = name;
this.TypeParameterCount = typeParameterCount; this.TypeParameterCount = typeParameterCount;

12
NRefactory.sln

@ -1,7 +1,7 @@
 
Microsoft Visual Studio Solution File, Format Version 11.00 Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010 # Visual Studio 2010
# SharpDevelop 4.2.0.8212-alpha # SharpDevelop 4.2.0.8278-alpha
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DC98210E-1646-483B-819A-2BB8272461E4}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DC98210E-1646-483B-819A-2BB8272461E4}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
README = README README = README
@ -22,6 +22,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.NRefactory.CSha
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.NRefactory.GtkDemo", "ICSharpCode.NRefactory.GtkDemo\ICSharpCode.NRefactory.GtkDemo.csproj", "{A7EEF7F8-238F-459D-95A9-96467539641D}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.NRefactory.GtkDemo", "ICSharpCode.NRefactory.GtkDemo\ICSharpCode.NRefactory.GtkDemo.csproj", "{A7EEF7F8-238F-459D-95A9-96467539641D}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.NRefactory.ConsistencyCheck", "ICSharpCode.NRefactory.ConsistencyCheck\ICSharpCode.NRefactory.ConsistencyCheck.csproj", "{D81206EF-3DCA-4A30-897B-E262A2AD9EE3}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -86,6 +88,14 @@ Global
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|Any CPU.Build.0 = net_4_0_Release|Any CPU {D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|Any CPU.Build.0 = net_4_0_Release|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|x86.ActiveCfg = net_4_0_Release|Any CPU {D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|x86.ActiveCfg = net_4_0_Release|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|x86.Build.0 = net_4_0_Release|Any CPU {D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|x86.Build.0 = net_4_0_Release|Any CPU
{D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.Debug|Any CPU.Build.0 = Debug|x86
{D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.Debug|Any CPU.ActiveCfg = Debug|x86
{D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.Debug|x86.Build.0 = Debug|x86
{D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.Debug|x86.ActiveCfg = Debug|x86
{D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.Release|Any CPU.Build.0 = Release|x86
{D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.Release|Any CPU.ActiveCfg = Release|x86
{D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.Release|x86.Build.0 = Release|x86
{D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.Release|x86.ActiveCfg = Release|x86
EndGlobalSection EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = ICSharpCode.NRefactory.Demo\ICSharpCode.NRefactory.Demo.csproj StartupItem = ICSharpCode.NRefactory.Demo\ICSharpCode.NRefactory.Demo.csproj

Loading…
Cancel
Save