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

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

@ -27,16 +27,43 @@ using System; @@ -27,16 +27,43 @@ using System;
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 (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 @@ -38,6 +38,7 @@ namespace ICSharpCode.NRefactory.CSharp
{
public readonly static Role<CSharpTokenNode> ColonRole = TypeDeclaration.ColonRole;
public readonly static Role<AstType> BaseTypeRole = TypeDeclaration.BaseTypeRole;
public readonly static Role<SimpleType> TypeParameterRole = new Role<SimpleType> ("TypeParameter", SimpleType.Null);
public override NodeType NodeType {
get {
@ -45,12 +46,12 @@ namespace ICSharpCode.NRefactory.CSharp @@ -45,12 +46,12 @@ namespace ICSharpCode.NRefactory.CSharp
}
}
public string TypeParameter {
public SimpleType TypeParameter {
get {
return GetChildByRole (Roles.Identifier).Name;
return GetChildByRole (TypeParameterRole);
}
set {
SetChildByRole(Roles.Identifier, Identifier.Create (value, TextLocation.Empty));
SetChildByRole(TypeParameterRole, value);
}
}
@ -66,7 +67,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -66,7 +67,7 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
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 @@ -33,6 +33,29 @@ namespace ICSharpCode.NRefactory.CSharp
{
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()
{
}
@ -42,6 +65,11 @@ namespace ICSharpCode.NRefactory.CSharp @@ -42,6 +65,11 @@ namespace ICSharpCode.NRefactory.CSharp
this.Identifier = identifier;
}
public SimpleType (Identifier identifier)
{
this.IdentifierToken = identifier;
}
public SimpleType(string identifier, TextLocation location)
{
SetChildByRole (Roles.Identifier, CSharp.Identifier.Create (identifier, location));

13
ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs

@ -139,7 +139,18 @@ namespace ICSharpCode.NRefactory.CSharp @@ -139,7 +139,18 @@ namespace ICSharpCode.NRefactory.CSharp
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)

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

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

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

@ -402,60 +402,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -402,60 +402,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
} else {
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 member2 = baseUnit.GetNodeAt<AttributedNode> (memberLocation);
member2.Remove ();
member.ReplaceWith (member2);
var tsvisitor = new TypeSystemConvertVisitor (ProjectContext, Document.FileName);
var tsvisitor = new TypeSystemConvertVisitor (CSharpParsedFile.FileName);
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)

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

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

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

@ -995,7 +995,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -995,7 +995,7 @@ namespace ICSharpCode.NRefactory.CSharp
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);
changes.Add (factory.CreateTextReplaceAction (offset, removedChars, insertedText));

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

@ -604,8 +604,14 @@ namespace ICSharpCode.NRefactory.CSharp @@ -604,8 +604,14 @@ namespace ICSharpCode.NRefactory.CSharp
public object VisitArrayInitializerExpression (ArrayInitializerExpression arrayInitializerExpression, object data)
{
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
&& IsObjectInitializer(arrayInitializerExpression.Parent);
&& IsObjectOrCollectionInitializer(arrayInitializerExpression.Parent)
&& !CanBeConfusedWithObjectInitializer(arrayInitializerExpression.Elements.Single());
if (bracesAreOptional && arrayInitializerExpression.LBraceToken.IsNull) {
arrayInitializerExpression.Elements.Single().AcceptVisitor(this, data);
} else {
@ -614,7 +620,15 @@ namespace ICSharpCode.NRefactory.CSharp @@ -614,7 +620,15 @@ namespace ICSharpCode.NRefactory.CSharp
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))
return false;
@ -2315,18 +2329,8 @@ namespace ICSharpCode.NRefactory.CSharp @@ -2315,18 +2329,8 @@ namespace ICSharpCode.NRefactory.CSharp
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.WriteToken ("#" + preProcessorDirective.Type.ToString ().ToLower ());
if (!string.IsNullOrEmpty(preProcessorDirective.Argument)) {
formatter.Space();
formatter.WriteToken(preProcessorDirective.Argument);
}
formatter.NewLine();
formatter.WritePreProcessorDirective(preProcessorDirective.Type, preProcessorDirective.Argument);
formatter.EndNode (preProcessorDirective);
lastWritten = LastWritten.Whitespace;
return null;
@ -2357,7 +2361,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -2357,7 +2361,7 @@ namespace ICSharpCode.NRefactory.CSharp
StartNode (constraint);
Space ();
WriteKeyword ("where");
WriteIdentifier (constraint.TypeParameter);
WriteIdentifier (constraint.TypeParameter.Identifier);
Space ();
WriteToken (":", Constraint.ColonRole);
Space ();

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

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

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

@ -55,5 +55,6 @@ namespace ICSharpCode.NRefactory.CSharp @@ -55,5 +55,6 @@ namespace ICSharpCode.NRefactory.CSharp
void NewLine();
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 @@ -77,39 +77,39 @@ namespace ICSharpCode.NRefactory.CSharp
{
bool isAtStartOfLine = needsIndent;
switch (style) {
case BraceStyle.DoNotChange:
case BraceStyle.EndOfLine:
WriteIndentation();
if (!isAtStartOfLine)
textWriter.Write(' ');
textWriter.Write('{');
break;
case BraceStyle.EndOfLineWithoutSpace:
WriteIndentation();
textWriter.Write('{');
break;
case BraceStyle.NextLine:
if (!isAtStartOfLine)
case BraceStyle.DoNotChange:
case BraceStyle.EndOfLine:
WriteIndentation();
if (!isAtStartOfLine)
textWriter.Write(' ');
textWriter.Write('{');
break;
case BraceStyle.EndOfLineWithoutSpace:
WriteIndentation();
textWriter.Write('{');
break;
case BraceStyle.NextLine:
if (!isAtStartOfLine)
NewLine();
WriteIndentation();
textWriter.Write('{');
break;
case BraceStyle.NextLineShifted:
NewLine ();
Indent();
WriteIndentation();
textWriter.Write('{');
NewLine();
WriteIndentation();
textWriter.Write('{');
break;
case BraceStyle.NextLineShifted:
NewLine ();
Indent();
WriteIndentation();
textWriter.Write('{');
NewLine();
return;
case BraceStyle.NextLineShifted2:
NewLine ();
Indent();
WriteIndentation();
textWriter.Write('{');
break;
default:
throw new ArgumentOutOfRangeException ();
return;
case BraceStyle.NextLineShifted2:
NewLine ();
Indent();
WriteIndentation();
textWriter.Write('{');
break;
default:
throw new ArgumentOutOfRangeException ();
}
Indent();
NewLine();
@ -118,27 +118,27 @@ namespace ICSharpCode.NRefactory.CSharp @@ -118,27 +118,27 @@ namespace ICSharpCode.NRefactory.CSharp
public void CloseBrace(BraceStyle style)
{
switch (style) {
case BraceStyle.DoNotChange:
case BraceStyle.EndOfLine:
case BraceStyle.EndOfLineWithoutSpace:
case BraceStyle.NextLine:
Unindent();
WriteIndentation();
textWriter.Write('}');
break;
case BraceStyle.NextLineShifted:
WriteIndentation();
textWriter.Write('}');
Unindent();
break;
case BraceStyle.NextLineShifted2:
Unindent();
WriteIndentation();
textWriter.Write('}');
Unindent();
break;
default:
throw new ArgumentOutOfRangeException ();
case BraceStyle.DoNotChange:
case BraceStyle.EndOfLine:
case BraceStyle.EndOfLineWithoutSpace:
case BraceStyle.NextLine:
Unindent();
WriteIndentation();
textWriter.Write('}');
break;
case BraceStyle.NextLineShifted:
WriteIndentation();
textWriter.Write('}');
Unindent();
break;
case BraceStyle.NextLineShifted2:
Unindent();
WriteIndentation();
textWriter.Write('}');
Unindent();
break;
default:
throw new ArgumentOutOfRangeException ();
}
}
@ -193,6 +193,21 @@ namespace ICSharpCode.NRefactory.CSharp @@ -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)
{
}

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

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

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

@ -318,17 +318,16 @@ namespace Mono.CSharp @@ -318,17 +318,16 @@ namespace Mono.CSharp
string assembly_name = a.GetString ();
if (assembly_name.Length == 0)
return;
AssemblyName aname = null;
try {
aname = new AssemblyName (assembly_name);
} catch (Exception) {
#if STATIC
ParsedAssemblyName aname;
ParseAssemblyResult r = Fusion.ParseAssemblyName (assembly_name, out aname);
if (r != ParseAssemblyResult.OK) {
Report.Warning (1700, 3, a.Location, "Assembly reference `{0}' is invalid and cannot be resolved",
assembly_name);
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,
"Friend assembly reference `{0}' is invalid. InternalsVisibleTo declarations cannot have a version, culture or processor architecture specified",
assembly_name);
@ -336,13 +335,13 @@ namespace Mono.CSharp @@ -336,13 +335,13 @@ namespace Mono.CSharp
return;
}
// TODO: GetPublicKey () does not work on .NET when AssemblyName is constructed from a string
if (public_key != null && aname.GetPublicKey () == null) {
if (public_key != null && !aname.HasPublicKey) {
Report.Error (1726, a.Location,
"Friend assembly reference `{0}' is invalid. Strong named assemblies must specify a public key in their InternalsVisibleTo declarations",
assembly_name);
return;
}
#endif
} else if (a.Type == pa.RuntimeCompatibility) {
wrap_non_exception_throws_custom = true;
} else if (a.Type == pa.AssemblyFileVersion) {
@ -486,6 +485,7 @@ namespace Mono.CSharp @@ -486,6 +485,7 @@ namespace Mono.CSharp
}
#else
var args = new PermissionSet[3];
#pragma warning disable 618
declarative_security.TryGetValue (SecurityAction.RequestMinimum, out args[0]);
declarative_security.TryGetValue (SecurityAction.RequestOptional, out args[1]);
declarative_security.TryGetValue (SecurityAction.RequestRefuse, out args[2]);
@ -827,7 +827,7 @@ namespace Mono.CSharp @@ -827,7 +827,7 @@ namespace Mono.CSharp
Compiler.TimeReporter.Stop (TimeReporter.TimerType.OutputSave);
// Save debug symbols file
if (symbol_writer != null) {
if (symbol_writer != null && Compiler.Report.Errors == 0) {
// TODO: it should run in parallel
Compiler.TimeReporter.Start (TimeReporter.TimerType.DebugSave);
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 @@ -151,19 +151,6 @@ namespace Mono.CSharp
List<Location> attributeCommas = new List<Location> ();
List<Location> attributeArgumentCommas = 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
@ -5165,6 +5152,12 @@ if_statement @@ -5165,6 +5152,12 @@ if_statement
if ($7 is EmptyStatement)
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
@ -5276,6 +5269,18 @@ do_statement @@ -5276,6 +5269,18 @@ do_statement
$$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1));
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
@ -5403,6 +5408,27 @@ foreach_statement @@ -5403,6 +5408,27 @@ foreach_statement
lbag.AddStatement (f, GetLocation ($2), GetLocation ($5), GetLocation ($7));
$$ = end_block (GetLocation ($7));
}
| FOREACH open_parens_any type identifier_inside_body error
{
start_block (GetLocation ($2));
current_block.IsCompilerGenerated = true;
var lt = $4 as Tokenizer.LocatedToken;
var li = lt != null ? new LocalVariable (current_block, lt.Value, LocalVariable.Flags.ForeachVariable | LocalVariable.Flags.Used, lt.Location) : null;
Foreach f = new Foreach ((Expression) $3, li, null, null, GetLocation ($1));
current_block.AddStatement (f);
lbag.AddStatement (f, GetLocation ($2));
$$ = end_block (GetLocation ($5));
}
| FOREACH open_parens_any type error
{
Foreach f = new Foreach ((Expression) $3, null, null, null, GetLocation ($1));
current_block.AddStatement (f);
lbag.AddStatement (f, GetLocation ($2));
$$ = f;
}
;
jump_statement
@ -5521,7 +5547,7 @@ try_statement @@ -5521,7 +5547,7 @@ try_statement
| TRY block error
{
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 @@ -836,7 +836,6 @@ namespace Mono.CSharp
}
return res;
return res;
}
static PreprocessorDirective GetPreprocessorDirective (char[] id, int id_len)
@ -1825,11 +1824,11 @@ namespace Mono.CSharp @@ -1825,11 +1824,11 @@ namespace Mono.CSharp
{
// skip over white space
do {
endLine = line;
endCol = col;
c = get_char ();
} while (c == ' ' || c == '\t');
endLine = line;
endCol = col;
int pos = 0;
while (c != -1 && c >= 'a' && c <= 'z') {
id_builder[pos++] = (char) c;
@ -1870,17 +1869,13 @@ namespace Mono.CSharp @@ -1870,17 +1869,13 @@ namespace Mono.CSharp
return cmd;
}
// skip over white space
while (c == ' ' || c == '\t')
while (c == ' ' || c == '\t') {
c = get_char ();
}
int has_identifier_argument = (int)(cmd & PreprocessorDirective.RequiresArgument);
int pos = 0;
endLine = line;
endCol = col;
while (c != -1 && c != '\n' && c != '\r') {
if (c == '\\' && has_identifier_argument >= 0) {
if (has_identifier_argument != 0) {
@ -1914,9 +1909,9 @@ namespace Mono.CSharp @@ -1914,9 +1909,9 @@ namespace Mono.CSharp
break;
}
endLine = line;
endCol = col;
endCol = col + 1;
if (pos == value_builder.Length)
Array.Resize (ref value_builder, pos * 2);
@ -1935,7 +1930,7 @@ namespace Mono.CSharp @@ -1935,7 +1930,7 @@ namespace Mono.CSharp
arg = arg.Trim (simple_whitespaces);
}
if (position_stack.Count == 0)
sbag.AddPreProcessorDirective (startLine, startCol, endLine, endCol + 1, cmd, arg);
sbag.AddPreProcessorDirective (startLine, startCol, endLine, endCol, cmd, arg);
return cmd;
}
@ -3348,7 +3343,7 @@ namespace Mono.CSharp @@ -3348,7 +3343,7 @@ namespace Mono.CSharp
if (ParsePreprocessingDirective (true))
continue;
sbag.StartComment (SpecialsBag.CommentType.Multi, false, line, col);
sbag.StartComment (SpecialsBag.CommentType.InactiveCode, false, line, 1);
bool directive_expected = false;
while ((c = get_char ()) != -1) {
if (col == 1) {
@ -3359,6 +3354,7 @@ namespace Mono.CSharp @@ -3359,6 +3354,7 @@ namespace Mono.CSharp
// Eror_WrongPreprocessorLocation ();
// return Token.ERROR;
// }
sbag.PushCommentChar (c);
continue;
}

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

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

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

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

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

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

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

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

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

@ -667,6 +667,37 @@ namespace Mono.CSharp { @@ -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
//
@ -5181,11 +5212,13 @@ namespace Mono.CSharp { @@ -5181,11 +5212,13 @@ namespace Mono.CSharp {
this.Block = block;
this.Specific = catch_clauses;
this.inside_try_finally = inside_try_finally;
Catch c = catch_clauses [0];
if (c.IsGeneral) {
this.General = c;
catch_clauses.RemoveAt (0);
if (catch_clauses != null) {
Catch c = catch_clauses [0];
if (c.IsGeneral) {
this.General = c;
catch_clauses.RemoveAt (0);
}
}
}
@ -6161,35 +6194,4 @@ namespace Mono.CSharp { @@ -6161,35 +6194,4 @@ namespace Mono.CSharp {
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 @@ -390,6 +390,30 @@ namespace Mono.CSharp
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)
{
if (Kind != MemberKind.Class)

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

@ -7,6 +7,7 @@ @@ -7,6 +7,7 @@
// Dual licensed under the terms of the MIT X11 or GNU GPL
//
// Copyright (c) 2010 Novell, Inc (http://www.novell.com)
// Copyright 2011 Xamarin Inc
//
using System;
@ -178,7 +179,7 @@ namespace Mono.CSharp @@ -178,7 +179,7 @@ namespace Mono.CSharp
{
return null;
}
public virtual object Visit (EmptyExpression emptyExpression)
{
return null;
@ -200,73 +201,66 @@ namespace Mono.CSharp @@ -200,73 +201,66 @@ namespace Mono.CSharp
return null;
}
public virtual object Visit (While whileStatement)
{
return null;
}
public virtual object Visit (For forStatement)
{
return null;
}
public virtual object Visit (StatementExpression statementExpression)
{
return null;
}
public virtual object Visit (StatementErrorExpression errorStatement)
{
return null;
}
public virtual object Visit (Return returnStatement)
{
return null;
}
public virtual object Visit (Goto gotoStatement)
{
return null;
}
public virtual object Visit (LabeledStatement labeledStatement)
{
return null;
}
public virtual object Visit (GotoDefault gotoDefault)
{
return null;
}
public virtual object Visit (GotoCase gotoCase)
{
return null;
}
public virtual object Visit (Throw throwStatement)
{
return null;
}
public virtual object Visit (Break breakStatement)
{
return null;
}
public virtual object Visit (Continue continueStatement)
{
return null;
}
public virtual object Visit (Block blockStatement)
{
return null;
@ -287,19 +281,16 @@ namespace Mono.CSharp @@ -287,19 +281,16 @@ namespace Mono.CSharp
return null;
}
public virtual object Visit (Unchecked uncheckedStatement)
{
return null;
}
public virtual object Visit (Checked checkedStatement)
{
return null;
}
public virtual object Visit (Unsafe unsafeStatement)
{
return null;
@ -317,7 +308,6 @@ namespace Mono.CSharp @@ -317,7 +308,6 @@ namespace Mono.CSharp
return null;
}
public virtual object Visit (TryCatch tryCatchStatement)
{
return null;
@ -445,7 +435,6 @@ namespace Mono.CSharp @@ -445,7 +435,6 @@ namespace Mono.CSharp
return null;
}
public virtual object Visit (Conditional conditionalExpression)
{
return null;
@ -646,10 +635,5 @@ namespace Mono.CSharp @@ -646,10 +635,5 @@ namespace Mono.CSharp
{
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 @@ -128,7 +128,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
/// </returns>
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 @@ -682,7 +682,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
return null;
}
Constraint c = new Constraint();
c.TypeParameter = tp.Name;
c.TypeParameter = new SimpleType (tp.Name);
if (tp.HasReferenceTypeConstraint) {
c.BaseTypes.Add(new PrimitiveType("class"));
} else if (tp.HasValueTypeConstraint) {

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

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

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

@ -289,6 +289,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -289,6 +289,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public override object Invoke(CSharpResolver resolver, object input)
{
if (input == null)
return null;
return func((T)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T)), input));
}
@ -456,6 +458,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -456,6 +458,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
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;
return func((T1)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T1)), lhs),
(T2)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T2)), rhs));
@ -692,6 +696,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -692,6 +696,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
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);
rhs = resolver.CSharpPrimitiveCast(Type, rhs);
bool equal;
@ -734,10 +742,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -734,10 +742,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
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);
}
@ -809,6 +813,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -809,6 +813,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
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),
(T2)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T2)), rhs));
}

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

@ -43,7 +43,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -43,7 +43,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
readonly ICompilation compilation;
internal readonly Conversions conversions;
CSharpTypeResolveContext context;
readonly CSharpTypeResolveContext context;
readonly bool checkForOverflow;
readonly bool isWithinLambdaExpression;
#region Constructor
public CSharpResolver(ICompilation compilation)
@ -65,6 +67,18 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -65,6 +67,18 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (context.CurrentTypeDefinition != null)
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
#region Properties
@ -82,53 +96,101 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -82,53 +96,101 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
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>
/// Gets/Sets whether the current context is <c>checked</c>.
/// Sets whether the resolver is currently within a lambda expression.
/// </summary>
public bool CheckForOverflow { get; set; }
public CSharpResolver WithIsWithinLambdaExpression(bool isWithinLambdaExpression)
{
return new CSharpResolver(compilation, conversions, context, checkForOverflow, isWithinLambdaExpression, currentTypeDefinitionCache, localVariableStack, objectInitializerStack);
}
/// <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.
/// </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 {
get { return context.CurrentMember; }
set {
context = context.WithCurrentMember(value);
}
}
/// <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>
public ResolvedUsingScope 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
#region Per-CurrentTypeDefinition Cache
TypeDefinitionCache currentTypeDefinitionCache;
readonly TypeDefinitionCache currentTypeDefinitionCache;
/// <summary>
/// Gets/Sets the current type definition that is used to look up identifiers as simple members.
/// Gets the current type definition.
/// </summary>
public ITypeDefinition CurrentTypeDefinition {
get { return context.CurrentTypeDefinition; }
set {
context = context.WithCurrentTypeDefinition(value);
if (value == null) {
currentTypeDefinitionCache = null;
} else {
if (currentTypeDefinitionCache == null || currentTypeDefinitionCache.TypeDefinition != value) {
currentTypeDefinitionCache = new TypeDefinitionCache(value);
}
}
}
}
/// <summary>
/// Sets the current type definition.
/// </summary>
public CSharpResolver WithCurrentTypeDefinition(ITypeDefinition typeDefinition)
{
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
@ -151,36 +213,43 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -151,36 +213,43 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// 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.
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>
/// Opens a new scope for local variables.
/// </summary>
public void PushBlock()
public CSharpResolver PushBlock()
{
localVariableStack = localVariableStack.Push(null);
return WithLocalVariableStack(localVariableStack.Push(null));
}
/// <summary>
/// Closes the current scope for local variables; removing all variables in that scope.
/// </summary>
public void PopBlock()
public CSharpResolver PopBlock()
{
var stack = localVariableStack;
IVariable removedVar;
do {
removedVar = localVariableStack.Peek();
localVariableStack = localVariableStack.Pop();
removedVar = stack.Peek();
stack = stack.Pop();
} while (removedVar != null);
return WithLocalVariableStack(stack);
}
/// <summary>
/// Adds a new variable or lambda parameter to the current block.
/// </summary>
public void AddVariable(IVariable variable)
public CSharpResolver AddVariable(IVariable variable)
{
if (variable == null)
throw new ArgumentNullException("variable");
localVariableStack = localVariableStack.Push(variable);
return WithLocalVariableStack(localVariableStack.Push(variable));
}
/// <summary>
@ -191,11 +260,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -191,11 +260,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return localVariableStack.Where(v => v != null);
}
}
/// <summary>
/// Gets whether the resolver is currently within a lambda expression.
/// </summary>
public bool IsWithinLambdaExpression { get; set; }
#endregion
#region Object Initializer Context
@ -211,23 +275,28 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -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>
/// Pushes the type of the object that is currently being initialized.
/// </summary>
public void PushInitializerType(IType type)
public CSharpResolver PushInitializerType(IType type)
{
if (type == null)
throw new ArgumentNullException("type");
objectInitializerStack = new ObjectInitializerContext(type, objectInitializerStack);
return WithObjectInitializerStack(new ObjectInitializerContext(type, objectInitializerStack));
}
public void PopInitializerType()
public CSharpResolver PopInitializerType()
{
if (objectInitializerStack == null)
throw new InvalidOperationException();
objectInitializerStack = objectInitializerStack.prev;
return WithObjectInitializerStack(objectInitializerStack.prev);
}
/// <summary>
@ -244,9 +313,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -244,9 +313,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// <summary>
/// Creates a copy of this CSharp resolver.
/// </summary>
[Obsolete("CSharpResolver is immutable, cloning is no longer necessary")]
public CSharpResolver Clone()
{
return (CSharpResolver)MemberwiseClone();
return this;
}
#endregion
@ -323,7 +393,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -323,7 +393,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
break;
case UnaryOperatorType.BitNot:
if (type.Kind == TypeKind.Enum) {
if (expression.IsCompileTimeConstant && !isNullable) {
if (expression.IsCompileTimeConstant && !isNullable && expression.ConstantValue != null) {
// evaluate as (E)(~(U)x);
var U = compilation.FindType(expression.ConstantValue.GetType());
var unpackedEnum = new ConstantResolveResult(U, expression.ConstantValue);
@ -345,12 +415,17 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -345,12 +415,17 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
CSharpOperators.UnaryOperatorMethod m = (CSharpOperators.UnaryOperatorMethod)builtinOperatorOR.BestCandidate;
IType resultType = m.ReturnType;
if (builtinOperatorOR.BestCandidateErrors != OverloadResolutionErrors.None) {
// If there are any user-defined operators, prefer those over the built-in operators.
// It'll be a more informative error.
if (userDefinedOperatorOR.BestCandidate != null)
if (userDefinedOperatorOR.BestCandidate != null) {
// If there are any user-defined operators, prefer those over the built-in operators.
// It'll be a more informative error.
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);
}
} else if (expression.IsCompileTimeConstant && m.CanEvaluateAtCompileTime) {
object val;
try {
@ -1255,7 +1330,16 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1255,7 +1330,16 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult LookInCurrentType(string identifier, IList<IType> typeArguments, SimpleNameLookupMode lookupMode, bool parameterizeResultType)
{
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
for (ITypeDefinition t = this.CurrentTypeDefinition; t != null; t = t.DeclaringTypeDefinition) {
if (k == 0) {
@ -1306,7 +1390,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1306,7 +1390,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ITypeDefinition def = n.GetTypeDefinition(identifier, k);
if (def != null) {
IType result = def;
if (parameterizeResultType) {
if (parameterizeResultType && k > 0) {
result = new ParameterizedType(def, typeArguments);
}
if (u.HasAlias(identifier))
@ -1410,7 +1494,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1410,7 +1494,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (mgrr != null) {
Debug.Assert(mgrr.extensionMethods == null);
// set the values that are necessary to make MethodGroupResolveResult.GetExtensionMethods() work
mgrr.resolver = this.Clone();
mgrr.resolver = this;
}
}
return result;
@ -1451,9 +1535,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1451,9 +1535,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// </summary>
public MemberLookup CreateMemberLookup()
{
ITypeDefinition currentTypeDefinition = this.CurrentTypeDefinition;
bool isInEnumMemberInitializer = this.CurrentMember != null && this.CurrentMember.EntityType == EntityType.Field
&& this.CurrentTypeDefinition != null && this.CurrentTypeDefinition.Kind == TypeKind.Enum;
return new MemberLookup(this.CurrentTypeDefinition, this.Compilation.MainAssembly, isInEnumMemberInitializer);
&& currentTypeDefinition != null && currentTypeDefinition.Kind == TypeKind.Enum;
return new MemberLookup(currentTypeDefinition, this.Compilation.MainAssembly, isInEnumMemberInitializer);
}
#endregion

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

@ -27,7 +27,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -27,7 +27,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public interface IFindReferenceSearchScope
{
/// <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>
ICompilation Compilation { get; }
@ -51,6 +52,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -51,6 +52,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// Creates a navigator that can find references to this entity and reports
/// them to the specified callback.
/// </summary>
IResolveVisitorNavigator GetNavigator(FoundReferenceCallback callback);
IResolveVisitorNavigator GetNavigator(ICompilation compilation, FoundReferenceCallback callback);
}
}

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

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

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

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

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

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

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

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

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

@ -154,7 +154,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -154,7 +154,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
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;
if (GetTypes().TryGetValue(key, out def))
return def;
@ -187,6 +187,9 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -187,6 +187,9 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
}
typeDef = new DefaultResolvedTypeDefinition(new SimpleTypeResolveContext(parentType), parts.ToArray());
foreach (var part in parts) {
// TODO: Fix that hack !
if (nestedTypeDict.ContainsKey (part))
continue;
nestedTypeDict.Add(part, typeDef);
}
return typeDef;

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

@ -20,6 +20,7 @@ using System; @@ -20,6 +20,7 @@ using System;
using System.Collections.Generic;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using System.Linq;
namespace ICSharpCode.NRefactory.CSharp.TypeSystem
{
@ -138,5 +139,29 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -138,5 +139,29 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
}
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 @@ -62,7 +62,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
nestedContext = nestedContext.WithUsingScope(context.CurrentUsingScope.UnresolvedUsingScope.Resolve(nestedCompilation));
}
if (context.CurrentTypeDefinition != null) {
nestedContext = nestedContext.WithCurrentTypeDefinition(context.CurrentTypeDefinition.ToTypeReference().Resolve(nestedContext).GetDefinition());
nestedContext = nestedContext.WithCurrentTypeDefinition(nestedCompilation.Import(context.CurrentTypeDefinition));
}
return nestedContext;
}
@ -432,13 +432,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues @@ -432,13 +432,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
public override ResolveResult Resolve(CSharpResolver resolver)
{
bool oldCheckForOverflow = resolver.CheckForOverflow;
try {
resolver.CheckForOverflow = this.checkForOverflow;
return expression.Resolve(resolver);
} finally {
resolver.CheckForOverflow = oldCheckForOverflow;
}
return expression.Resolve(resolver.WithCheckForOverflow(checkForOverflow));
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)

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

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

3
ICSharpCode.NRefactory.ConsistencyCheck/.gitignore vendored

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

176
ICSharpCode.NRefactory.ConsistencyCheck/CSharpProject.cs

@ -0,0 +1,176 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ -316,7 +316,7 @@ namespace ICSharpCode.NRefactory.Demo
};
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);
}

51
ICSharpCode.NRefactory.GtkDemo/MainWindow.cs

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

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

@ -1496,10 +1496,107 @@ class A @@ -1496,10 +1496,107 @@ class A
}
");
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.");
}
/// <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>
/// Bug 473686 - Constants are not included in code completion
/// </summary>
@ -3771,6 +3868,51 @@ public partial class TestMe @@ -3771,6 +3868,51 @@ public partial class TestMe
Assert.IsNotNull (provider, "provider not found.");
Assert.IsNotNull (provider.Find ("MyMethod"), "method 'MyMethod' not 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 @@ -161,7 +161,6 @@ class Test
});
}
[Ignore("needs to be fixed in parser.")]
[Test()]
public void IsAsKeywordTest ()
{
@ -196,7 +195,6 @@ provider => { @@ -196,7 +195,6 @@ provider => {
});
}
[Ignore()]
[Test()]
public void PublicClassContextTest2 ()
{
@ -209,7 +207,6 @@ provider => { @@ -209,7 +207,6 @@ provider => {
});
}
[Ignore()]
[Test()]
public void PublicClassContextTestContinuation1 ()
{
@ -220,7 +217,6 @@ provider => { @@ -220,7 +217,6 @@ provider => {
});
}
[Ignore()]
[Test()]
public void PublicClassContextTestContinuation2 ()
{
@ -231,6 +227,84 @@ provider => { @@ -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 @@ -515,6 +515,33 @@ class A
Assert.IsNotNull (provider, "provider was not created.");
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 @@ -46,6 +46,22 @@ class MyTest
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()]
public void TestIntNameProposal ()
{
@ -81,6 +97,23 @@ class MyTest @@ -81,6 +97,23 @@ class MyTest
Assert.IsNotNull (provider.Find ("test"), "name proposal 'test' not found.");
}
[Test()]
public void TestNameProposalForeach ()
{
var provider = CodeCompletionBugTests.CreateCtrlSpaceProvider (
@"
class MyTest
{
public void Test ()
{
$foreach (MyTest $
}
}
");
Assert.IsNotNull (provider.Find ("myTest"), "name proposal 'myTest' not found.");
Assert.IsNotNull (provider.Find ("test"), "name proposal 'test' not found.");
}
/// <summary>
/// Bug 1799 - [New Resolver] Invalid code completion when typing name of variable
/// </summary>

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

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

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

@ -147,7 +147,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression @@ -147,7 +147,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
}});
}
[Test]
[Test, Ignore("Parser bug")]
public void ArrayInitializerWithCommaAtEnd()
{
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 @@ -166,14 +166,14 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
});
}
[Test, Ignore ("TODO")]
[Test]
public void IntMaxValueToBigInt()
{
ParseUtilCSharp.AssertExpression(
"(BigInt)int.MaxValue",
new CastExpression {
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 @@ -115,17 +115,17 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
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()
{
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);
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, 4), mre.Target.StartLocation);
Assert.AreEqual(new TextLocation(1, 1), mre.Target.StartLocation);
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 @@ -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()
{
ParseUtilCSharp.AssertExpression(
@ -42,7 +42,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression @@ -42,7 +42,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Expression
);
}
[Test, Ignore("Parsing of @-identifiers is broken")]
[Test]
public void IdentShortMaxValueTest()
{
ParseUtilCSharp.AssertExpression(

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

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

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

@ -17,9 +17,9 @@ @@ -17,9 +17,9 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using ICSharpCode.NRefactory.PatternMatching;
using ICSharpCode.NRefactory.TypeSystem;
using NUnit.Framework;
@ -72,6 +72,26 @@ public class Form1 { @@ -72,6 +72,26 @@ public class Form1 {
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]
public void TwoAttributesInSameSection()
{
@ -170,5 +190,17 @@ public class Form1 { @@ -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 @@ -53,7 +53,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
Constraints = {
new Constraint {
TypeParameter = "T",
TypeParameter = new SimpleType ("T"),
BaseTypes = { new SimpleType("ICloneable") }
}
}});

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

@ -62,8 +62,63 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope @@ -62,8 +62,63 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
Assert.AreEqual(PreProcessorDirectiveType.Endif, pp.Last().Type);
Assert.AreEqual(string.Empty, pp.Last().Argument);
Assert.AreEqual(new TextLocation(4, 2), pp.First().StartLocation);
Assert.AreEqual(new TextLocation(4, 8), pp.First().EndLocation);
Assert.AreEqual(new TextLocation(4, 2), pp.Last().StartLocation);
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]

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

@ -109,20 +109,20 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope @@ -109,20 +109,20 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
TypeParameters = { new TypeParameterDeclaration { Name = "T" } },
Constraints = {
new Constraint {
TypeParameter = "T",
TypeParameter = new SimpleType ("T"),
BaseTypes = { new SimpleType("IMyInterface") }
}
}});
}
[Test, Ignore ("Mono parser bug.")]
public void ComplexGenericClassTypeDeclarationTest()
[Test]
public void ComplexGenericInterfaceTypeDeclarationTest()
{
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 {
Modifiers = Modifiers.Public,
ClassType = ClassType.Class,
ClassType = ClassType.Interface,
Name = "Generic",
TypeParameters = {
new TypeParameterDeclaration { Variance = VarianceModifier.Contravariant, Name = "T" },
@ -136,7 +136,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope @@ -136,7 +136,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
},
Constraints = {
new Constraint {
TypeParameter = "S",
TypeParameter = new SimpleType ("S"),
BaseTypes = {
new SimpleType {
Identifier = "G",
@ -146,7 +146,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope @@ -146,7 +146,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
}
},
new Constraint {
TypeParameter = "T",
TypeParameter = new SimpleType ("T"),
BaseTypes = {
new MemberType {
Target = new SimpleType("MyNamespace"),
@ -240,7 +240,7 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2 @@ -240,7 +240,7 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2
},
Constraints = {
new Constraint {
TypeParameter = "where",
TypeParameter = new SimpleType ("where"),
BaseTypes = {
new SimpleType {
Identifier = "partial",
@ -296,16 +296,6 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2 @@ -296,16 +296,6 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2
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]
public void EnumWithBaseType()
{
@ -314,7 +304,7 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2 @@ -314,7 +304,7 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2
Assert.AreEqual("short", ((PrimitiveType)td.BaseTypes.Single()).Keyword);
}
[Test]
[Test, Ignore("Mono parser crash")]
public void EnumWithIncorrectNewlineAfterIntegerLiteral()
{
ParseUtilCSharp.AssertGlobal(
@ -361,7 +351,7 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2 @@ -361,7 +351,7 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2
}, 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()
{
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 @@ -70,7 +70,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser
string currentFileName;
ReadOnlyDocument currentDocument;
[Test]
[Test, Ignore("Positions still are incorrect in several cases")]
public void ParseAndCheckPositions()
{
CSharpParser parser = new CSharpParser();

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

@ -191,14 +191,14 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Statements @@ -191,14 +191,14 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.Statements
Assert.AreEqual(20, lvd.EndLocation.Column);
}
[Test, Ignore("Nested arrays are broken in the parser")]
[Test]
public void NestedArray()
{
VariableDeclarationStatement lvd = ParseUtilCSharp.ParseStatement<VariableDeclarationStatement>("DateTime[,][] a;");
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()
{
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 @@ -149,7 +149,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
Constraints = {
new Constraint {
TypeParameter = "T",
TypeParameter = new SimpleType ("T"),
BaseTypes = { new SimpleType("ISomeInterface") }
}
},
@ -176,7 +176,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers @@ -176,7 +176,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
Constraints = {
new Constraint {
TypeParameter = "T",
TypeParameter = new SimpleType ("T"),
BaseTypes = { new SimpleType("ISomeInterface") }
}
}
@ -202,7 +202,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers @@ -202,7 +202,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers
Parameters = { new ParameterDeclaration(new SimpleType("T"), "a") },
Constraints = {
new Constraint {
TypeParameter = "T",
TypeParameter = new SimpleType ("T"),
BaseTypes = { new SimpleType("ISomeInterface") }
}
}

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

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

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

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

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

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

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

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

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

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem;
using NUnit.Framework;
@ -141,8 +142,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -141,8 +142,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void TestUnaryMinusCheckedOverflow()
{
resolver.CheckForOverflow = true;
AssertError(typeof(int), resolver.ResolveUnaryOperator(UnaryOperatorType.Minus, MakeConstant(-2147483648)));
AssertError(typeof(int), resolver.WithCheckForOverflow(true).ResolveUnaryOperator(UnaryOperatorType.Minus, MakeConstant(-2147483648)));
}
[Test]
@ -212,5 +212,25 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -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?))));
}
[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) { @@ -133,7 +133,7 @@ using (IDisposable b = null) {
int start = result.GetOffset (5, 1);
int end = result.GetOffset (result.LineCount - 1, 1);
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);
}

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

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

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

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

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

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

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

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

5
ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs

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

36
ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs

@ -172,6 +172,8 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -172,6 +172,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
throw new ArgumentNullException("compilation");
if (typeDefinition == null)
return null;
if (typeDefinition.Compilation == compilation)
return typeDefinition;
return typeDefinition.ToTypeReference().Resolve(compilation.TypeResolveContext).GetDefinition();
}
@ -184,8 +186,42 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -184,8 +186,42 @@ namespace ICSharpCode.NRefactory.TypeSystem
throw new ArgumentNullException("compilation");
if (member == null)
return null;
if (member.Compilation == compilation)
return member;
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
#region GetDelegateInvokeMethod

5
ICSharpCode.NRefactory/TypeSystem/IParsedFile.cs

@ -73,5 +73,10 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -73,5 +73,10 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// Gets the parser errors.
/// </summary>
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 @@ -232,14 +232,30 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
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)
{
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
if (this.HasDefaultConstructorConstraint || this.HasValueTypeConstraint) {
throw new NotImplementedException();
//DefaultMethod m = DefaultMethod.CreateDefaultConstructor(GetDummyClassForTypeParameter(constraints));
//if (filter(m))
// return new [] { m };
if (filter == null || filter(dummyConstructor)) {
var resolvedCtor = (IMethod)dummyConstructor.CreateResolved(compilation.TypeResolveContext);
IMethod m = new SpecializedMethod(this, resolvedCtor, EmptyList<IType>.Instance);
return new [] { m };
}
}
return EmptyList<IMethod>.Instance;
} else {

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

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

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

@ -51,7 +51,11 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -51,7 +51,11 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
get {
ResolveResult rr = this.constantValue;
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;
}
return rr.ConstantValue;

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

@ -290,45 +290,51 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -290,45 +290,51 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
LazyInit.ReadBarrier();
return result;
} else {
result = new List<IType>();
bool hasNonInterface = false;
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 (!(baseType.Kind == TypeKind.Unknown || result.Contains(baseType))) {
result.Add(baseType);
if (baseType.Kind != TypeKind.Interface)
hasNonInterface = true;
}
}
}
}
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;
result = CalculateDirectBaseTypes();
return LazyInit.GetOrSet(ref this.directBaseTypes, result);
}
}
}
IList<IType> CalculateDirectBaseTypes()
{
List<IType> result = new List<IType>();
bool hasNonInterface = false;
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 (!(baseType.Kind == TypeKind.Unknown || result.Contains(baseType))) {
result.Add(baseType);
if (baseType.Kind != TypeKind.Interface)
hasNonInterface = true;
}
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

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

@ -105,7 +105,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -105,7 +105,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
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;
if (typeDefinitions.TryGetValue(key, out td))
return td;

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

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

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

@ -40,6 +40,24 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -40,6 +40,24 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
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)
{
this.EntityType = EntityType.TypeDefinition;

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

@ -30,6 +30,10 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -30,6 +30,10 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
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.Name = name;
this.TypeParameterCount = typeParameterCount;

12
NRefactory.sln

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# 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}"
ProjectSection(SolutionItems) = preProject
README = README
@ -22,6 +22,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.NRefactory.CSha @@ -22,6 +22,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.NRefactory.CSha
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.NRefactory.GtkDemo", "ICSharpCode.NRefactory.GtkDemo\ICSharpCode.NRefactory.GtkDemo.csproj", "{A7EEF7F8-238F-459D-95A9-96467539641D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.NRefactory.ConsistencyCheck", "ICSharpCode.NRefactory.ConsistencyCheck\ICSharpCode.NRefactory.ConsistencyCheck.csproj", "{D81206EF-3DCA-4A30-897B-E262A2AD9EE3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -86,6 +88,14 @@ Global @@ -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|x86.ActiveCfg = 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
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = ICSharpCode.NRefactory.Demo\ICSharpCode.NRefactory.Demo.csproj

Loading…
Cancel
Save