Browse Source

Merge branch 'master' into soc-master

Conflicts:
	ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj
	ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj
newNRvisualizers
Simon Lindgren 14 years ago
parent
commit
f562e974a9
  1. 88
      ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs
  2. 178
      ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs
  3. 26
      ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs
  4. 198
      ICSharpCode.NRefactory.CSharp/Completion/ICompletionContextProvider.cs
  5. 40
      ICSharpCode.NRefactory.CSharp/Completion/IMemberProvider.cs
  6. 2
      ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs
  7. 8
      ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj
  8. 8
      ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs
  9. 119
      ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs
  10. 21
      ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs
  11. 2
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreatePropertyAction.cs
  12. 93
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ExtractFieldAction.cs
  13. 2
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/UseExplicitTypeAction.cs
  14. 43
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/InconsistentNamingIssue/DefaultRules.cs
  15. 18
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/InconsistentNamingIssue/WordParser.cs
  16. 11
      ICSharpCode.NRefactory.CSharp/Resolver/CSharpConversions.cs
  17. 48
      ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs
  18. 4
      ICSharpCode.NRefactory.CSharp/Resolver/MethodGroupResolveResult.cs
  19. 11
      ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs
  20. 8
      ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs
  21. 1
      ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs
  22. 2
      ICSharpCode.NRefactory.ConsistencyCheck/CSharpProject.cs
  23. 2
      ICSharpCode.NRefactory.Demo/CSDemo.cs
  24. 149
      ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ExtractFieldTests.cs
  25. 6
      ICSharpCode.NRefactory.Tests/CSharp/CodeActions/TestRefactoringContext.cs
  26. 9
      ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/CodeCompletionBugTests.cs
  27. 10
      ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/ParameterCompletionTests.cs
  28. 376
      ICSharpCode.NRefactory.Tests/CSharp/CodeDomConvertVisitorTests.cs
  29. 106
      ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/InconsistentNamingTests.cs
  30. 20
      ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseUtil.cs
  31. 34
      ICSharpCode.NRefactory.Tests/FormattingTests/TestWrapping.cs
  32. 3
      ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj
  33. 1
      ICSharpCode.NRefactory.Tests/TypeSystem/CecilLoaderTests.cs
  34. 2
      ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.TestCase.cs
  35. 11
      ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs
  36. 11
      ICSharpCode.NRefactory/Documentation/XmlDocumentationProvider.cs
  37. 32
      ICSharpCode.NRefactory/Editor/IDocument.cs
  38. 15
      ICSharpCode.NRefactory/Editor/ReadOnlyDocument.cs
  39. 28
      ICSharpCode.NRefactory/Editor/StringBuilderDocument.cs
  40. 7
      ICSharpCode.NRefactory/Editor/StringTextSource.cs
  41. 30
      ICSharpCode.NRefactory/Editor/TextChangeEventArgs.cs
  42. 11
      ICSharpCode.NRefactory/Semantics/ConversionResolveResult.cs
  43. 10
      ICSharpCode.NRefactory/Semantics/ErrorResolveResult.cs
  44. 16
      ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs
  45. 17
      ICSharpCode.NRefactory/TypeSystem/IMethod.cs
  46. 14
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedMethod.cs
  47. 32
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedMethod.cs
  48. 9
      ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMember.cs
  49. 23
      ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMethod.cs
  50. 10
      ICSharpCode.NRefactory/TypeSystem/KnownTypeReference.cs

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

@ -57,7 +57,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -57,7 +57,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
public bool CloseOnSquareBrackets;
#endregion
public CSharpCompletionEngine(IDocument document, ICompletionDataFactory factory, IProjectContent content, CSharpTypeResolveContext ctx, CompilationUnit unit, CSharpParsedFile parsedFile) : base (content, ctx, unit, parsedFile)
public CSharpCompletionEngine(IDocument document, ICompletionContextProvider completionContextProvider, ICompletionDataFactory factory, IProjectContent content, CSharpTypeResolveContext ctx) : base (content, completionContextProvider, ctx)
{
if (document == null) {
throw new ArgumentNullException("document");
@ -239,7 +239,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -239,7 +239,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
parent = (ArrayInitializerExpression)parent.Parent;
if (p != null) {
var contextList = new CompletionDataWrapper(this);
var initializerResult = ResolveExpression(p, unit);
var initializerResult = ResolveExpression(p);
if (initializerResult != null && initializerResult.Item1.Type.Kind != TypeKind.Unknown) {
// check 3 cases:
// 1) New initalizer { xpr
@ -255,7 +255,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -255,7 +255,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
if (prev != null && !(prev is NamedExpression)) {
AddContextCompletion(contextList, GetState(), n, unit);
AddContextCompletion(contextList, GetState(), n);
// case 3)
return contextList.Result;
}
@ -279,7 +279,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -279,7 +279,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return contextList.Result;
}
AddContextCompletion(contextList, GetState(), n, unit);
AddContextCompletion(contextList, GetState(), n);
return contextList.Result;
}
}
@ -480,8 +480,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -480,8 +480,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
AddContextCompletion(
wrapper,
resolveResult.Item2,
expressionOrVariableDeclaration.Node,
expressionOrVariableDeclaration.Unit);
expressionOrVariableDeclaration.Node);
AddEnumMembers(wrapper, resolveResult.Item1.Type, resolveResult.Item2);
AutoCompleteEmptyMatch = false;
return wrapper.Result;
@ -742,8 +741,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -742,8 +741,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
if (n != null && n.Parent is InvocationExpression) {
var invokeParent = (InvocationExpression)n.Parent;
var invokeResult = ResolveExpression(
invokeParent.Target,
identifierStart.Unit
invokeParent.Target
);
var mgr = invokeResult != null ? invokeResult.Item1 as MethodGroupResolveResult : null;
if (mgr != null) {
@ -777,7 +775,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -777,7 +775,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
if (n != null && n.Parent is ObjectCreateExpression) {
var invokeResult = ResolveExpression(n.Parent, identifierStart.Unit);
var invokeResult = ResolveExpression(n.Parent);
var mgr = invokeResult != null ? invokeResult.Item1 as ResolveResult : null;
if (mgr != null) {
foreach (var constructor in mgr.Type.GetConstructors ()) {
@ -797,14 +795,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -797,14 +795,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
// check for compare to enum case
if (evaluationExpr != null) {
resolveResult = ResolveExpression(evaluationExpr, identifierStart.Unit);
resolveResult = ResolveExpression(evaluationExpr);
if (resolveResult != null && resolveResult.Item1.Type.Kind == TypeKind.Enum) {
var wrapper = new CompletionDataWrapper(this);
AddContextCompletion(
wrapper,
resolveResult.Item2,
evaluationExpr,
identifierStart.Unit
evaluationExpr
);
AddEnumMembers(wrapper, resolveResult.Item1.Type, resolveResult.Item2);
AutoCompleteEmptyMatch = false;
@ -827,7 +824,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -827,7 +824,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return DefaultControlSpaceItems();
}
var initalizerResult = ResolveExpression(n.Parent, identifierStart.Unit);
var initalizerResult = ResolveExpression(n.Parent);
var concreteNode = identifierStart.Unit.GetNodeAt<IdentifierExpression>(location);
// check if we're on the right side of an initializer expression
@ -869,8 +866,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -869,8 +866,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
if (n is MemberType) {
resolveResult = ResolveExpression(
((MemberType)n).Target,
identifierStart.Unit
((MemberType)n).Target
);
return CreateTypeAndNamespaceCompletionData(
location,
@ -886,11 +882,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -886,11 +882,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
if (n.Parent is ICSharpCode.NRefactory.CSharp.Attribute) {
nodes.Add(n.Parent);
}
var astResolver = new CSharpAstResolver(
csResolver,
identifierStart.Unit,
CSharpParsedFile
);
var astResolver = CompletionContextProvider.GetResolver (csResolver, identifierStart.Unit);
astResolver.ApplyNavigator(new NodeListResolveVisitorNavigator(nodes));
try {
csResolver = astResolver.GetResolverStateBefore(n);
@ -917,8 +909,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -917,8 +909,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
AddContextCompletion(
contextList,
csResolver,
identifierStart.Node,
identifierStart.Unit
identifierStart.Node
);
return contextList.Result;
// if (stub.Parent is BlockStatement)
@ -1111,7 +1102,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1111,7 +1102,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
Tuple<ResolveResult, CSharpResolver> rr;
if (xp != null) {
node = xp.Node;
rr = ResolveExpression(node, xp.Unit);
rr = ResolveExpression(node);
unit = xp.Unit;
} else {
unit = ParseStub("foo", false);
@ -1120,7 +1111,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1120,7 +1111,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
location.Column + 2,
n => n is Expression || n is AstType
);
rr = ResolveExpression(node, unit);
rr = ResolveExpression(node);
}
if (node is Identifier && node.Parent is ForeachStatement) {
var foreachStmt = (ForeachStatement)node.Parent;
@ -1152,7 +1143,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1152,7 +1143,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return wrapper.Result;
}
}
if (Unit != null && (node == null || node is TypeDeclaration)) {
/* if (Unit != null && (node == null || node is TypeDeclaration)) {
var constructor = Unit.GetNodeAt<ConstructorDeclaration>(
location.Line,
location.Column - 3
@ -1162,7 +1153,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1162,7 +1153,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
wrapper.AddCustom("base");
return wrapper.Result;
}
}
}*/
var initializer = node != null ? node.Parent as ArrayInitializerExpression : null;
if (initializer != null) {
@ -1190,12 +1181,12 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1190,12 +1181,12 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
csResolver = GetState();
}
}
AddContextCompletion(wrapper, csResolver, node, unit);
AddContextCompletion(wrapper, csResolver, node);
return wrapper.Result;
}
void AddContextCompletion(CompletionDataWrapper wrapper, CSharpResolver state, AstNode node, CompilationUnit unit)
void AddContextCompletion(CompletionDataWrapper wrapper, CSharpResolver state, AstNode node)
{
if (state != null && !(node is AstType)) {
foreach (var variable in state.LocalVariables) {
@ -1266,7 +1257,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1266,7 +1257,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
wrapper.Result.AddRange(factory.CreateCodeTemplateCompletionData());
if (node != null && node.Role == Roles.Argument) {
var resolved = ResolveExpression(node.Parent, unit);
var resolved = ResolveExpression(node.Parent);
var invokeResult = resolved != null ? resolved.Item1 as CSharpInvocationResolveResult : null;
if (invokeResult != null) {
int argNum = 0;
@ -1284,7 +1275,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1284,7 +1275,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
if (node is Expression) {
var astResolver = new CSharpAstResolver(state, unit, CSharpParsedFile);
var root = node;
while (root.Parent != null)
root = root.Parent;
var astResolver = CompletionContextProvider.GetResolver (state, root);
foreach (var type in CreateFieldAction.GetValidTypes(astResolver, (Expression)node)) {
if (type.Kind == TypeKind.Enum) {
AddEnumMembers(wrapper, type, state);
@ -1320,10 +1314,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1320,10 +1314,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
void AddTypesAndNamespaces(CompletionDataWrapper wrapper, CSharpResolver state, AstNode node, Func<IType, IType> typePred = null, Predicate<IMember> memberPred = null, Action<ICompletionData, IType> callback = null)
{
var lookup = new MemberLookup(
ctx.CurrentTypeDefinition,
Compilation.MainAssembly
);
var lookup = new MemberLookup(ctx.CurrentTypeDefinition, Compilation.MainAssembly);
if (currentType != null) {
for (var ct = currentType; ct != null; ct = ct.DeclaringTypeDefinition) {
foreach (var nestedType in ct.NestedTypes) {
@ -1384,7 +1375,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1384,7 +1375,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
wrapper.AddTypeParameter(p);
}
}
var scope = CSharpParsedFile.GetUsingScope(location).Resolve(Compilation);
var scope = ctx.CurrentUsingScope;
for (var n = scope; n != null; n = n.Parent) {
foreach (var pair in n.UsingAliases) {
@ -1523,7 +1514,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1523,7 +1514,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
parent = parent.Parent;
}
if (parent is VariableDeclarationStatement) {
var resolved = ResolveExpression(parent, isAsExpression.Unit);
var resolved = ResolveExpression(parent);
if (resolved != null) {
isAsType = resolved.Item1.Type;
}
@ -1662,11 +1653,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1662,11 +1653,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
var expressionOrVariableDeclaration = GetNewExpressionAt(j);
if (expressionOrVariableDeclaration == null)
return null;
var astResolver = new CSharpAstResolver(
GetState(),
expressionOrVariableDeclaration.Unit,
CSharpParsedFile
);
var astResolver = CompletionContextProvider.GetResolver(GetState(), expressionOrVariableDeclaration.Unit);
hintType = CreateFieldAction.GetValidTypes(
astResolver,
expressionOrVariableDeclaration.Node as Expression
@ -1689,8 +1676,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1689,8 +1676,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
AddContextCompletion(
inList,
rr != null ? rr.Item2 : GetState(),
expr.Node,
Unit
expr.Node
);
return inList.Result;
}
@ -2149,11 +2135,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -2149,11 +2135,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
var exprParent = resolvedNode.GetParent<Expression>();
var unit = exprParent != null ? exprParent.GetParent<CompilationUnit>() : null;
var astResolver = unit != null ? new CSharpAstResolver(
state,
unit,
CSharpParsedFile
) : null;
var astResolver = unit != null ? CompletionContextProvider.GetResolver(state, unit) : null;
IType hintType = exprParent != null && astResolver != null ?
CreateFieldAction.GetValidTypes(astResolver, exprParent) .FirstOrDefault() :
null;
@ -2238,7 +2220,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -2238,7 +2220,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
AutoCompleteEmptyMatch = false;
AutoSelect = false;
}
AddContextCompletion(result, state, invocation, unit);
AddContextCompletion(result, state, invocation);
// resolver.AddAccessibleCodeCompletionData (ExpressionContext.MethodBody, cdc);
// if (addedDelegates.Count > 0) {
@ -2372,7 +2354,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -2372,7 +2354,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
}
// ADD Aliases
var scope = CSharpParsedFile.GetUsingScope(location).Resolve(Compilation);
var scope = ctx.CurrentUsingScope;
for (var n = scope; n != null; n = n.Parent) {
foreach (var pair in n.UsingAliases) {
@ -2752,7 +2734,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -2752,7 +2734,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
sb.Append("a;");
AppendMissingClosingBrackets(sb, text, false);
var stream = new System.IO.StringReader(sb.ToString());
var completionUnit = parser.Parse(stream, CSharpParsedFile.FileName, 0);
var completionUnit = parser.Parse(stream, "a.cs", 0);
stream.Close();
var loc = document.GetLocation(offset);
@ -2775,7 +2757,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -2775,7 +2757,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
AppendMissingClosingBrackets(sb, text, false);
var stream = new System.IO.StringReader(sb.ToString());
var completionUnit = parser.Parse(stream, CSharpParsedFile.FileName, 0);
var completionUnit = parser.Parse(stream, "a.cs", 0);
stream.Close();
var loc = document.GetLocation(offset);
@ -2786,7 +2768,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -2786,7 +2768,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
sb.Append("a ()");
AppendMissingClosingBrackets(sb, text, false);
stream = new System.IO.StringReader(sb.ToString());
completionUnit = parser.Parse(stream, CSharpParsedFile.FileName, 0);
completionUnit = parser.Parse(stream, "a.cs", 0);
stream.Close();
loc = document.GetLocation(offset);

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

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
//
//
// CSharpCompletionEngineBase.cs
//
// Author:
@ -51,10 +51,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -51,10 +51,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
#region Input properties
public CSharpTypeResolveContext ctx { get; private set; }
public CompilationUnit Unit { get; private set; }
public CSharpParsedFile CSharpParsedFile { get; private set; }
public IProjectContent ProjectContent { get; private set; }
ICompilation compilation;
@ -68,27 +64,24 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -68,27 +64,24 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
#endregion
protected CSharpCompletionEngineBase (IProjectContent content, CSharpTypeResolveContext ctx, CompilationUnit unit, CSharpParsedFile parsedFile)
protected CSharpCompletionEngineBase(IProjectContent content, ICompletionContextProvider completionContextProvider, CSharpTypeResolveContext ctx)
{
if (content == null)
throw new ArgumentNullException("content");
if (ctx == null)
throw new ArgumentNullException("ctx");
if (unit == null)
throw new ArgumentNullException ("unit");
if (parsedFile == null)
throw new ArgumentNullException ("parsedFile");
if (completionContextProvider == null)
throw new ArgumentNullException("completionContextProvider");
this.ProjectContent = content;
this.CompletionContextProvider = completionContextProvider;
this.ctx = ctx;
this.Unit = unit;
this.CSharpParsedFile = parsedFile;
}
public IMemberProvider MemberProvider {
public ICompletionContextProvider CompletionContextProvider {
get;
set;
private set;
}
public void SetOffset (int offset)
@ -97,8 +90,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -97,8 +90,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
this.offset = offset;
this.location = document.GetLocation (offset);
var provider = MemberProvider ?? new DefaultMemberProvider (this);
provider.GetCurrentMembers (offset, out currentType, out currentMember);
CompletionContextProvider.GetCurrentMembers (offset, out currentType, out currentMember);
}
public bool GetParameterCompletionCommandOffset (out int cpos)
@ -702,34 +694,16 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -702,34 +694,16 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
}
string cachedText = null;
// string cachedText = null;
protected virtual void Reset ()
{
cachedText = null;
// cachedText = null;
}
protected Tuple<string, TextLocation> GetMemberTextToCaret()
{
int startOffset;
if (currentMember != null && currentType != null && currentType.Kind != TypeKind.Enum) {
startOffset = document.GetOffset(currentMember.Region.Begin);
} else if (currentType != null) {
startOffset = document.GetOffset(currentType.Region.Begin);
} else {
startOffset = 0;
}
while (startOffset > 0) {
char ch = document.GetCharAt(startOffset - 1);
if (ch != ' ' && ch != '\t') {
break;
}
--startOffset;
}
if (cachedText == null)
cachedText = document.GetText (startOffset, offset - startOffset);
return Tuple.Create (cachedText, document.GetLocation (startOffset));
return CompletionContextProvider.GetMemberTextToCaret(offset, currentType, currentMember);
}
protected ExpressionResult GetInvocationBeforeCursor(bool afterBracket)
@ -806,10 +780,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -806,10 +780,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
protected Tuple<ResolveResult, CSharpResolver> ResolveExpression (ExpressionResult tuple)
{
return ResolveExpression (tuple.Node, tuple.Unit);
return ResolveExpression (tuple.Node);
}
protected Tuple<ResolveResult, CSharpResolver> ResolveExpression(AstNode expr, CompilationUnit unit)
protected Tuple<ResolveResult, CSharpResolver> ResolveExpression(AstNode expr)
{
if (expr == null) {
return null;
@ -823,12 +797,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -823,12 +797,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
resolveNode = expr;
}
try {
var ctx = CSharpParsedFile.GetResolver(Compilation, location);
var root = expr.AncestorsAndSelf.FirstOrDefault(n => n is EntityDeclaration || n is CompilationUnit);
if (root == null) {
return null;
}
var csResolver = new CSharpAstResolver (ctx, root, CSharpParsedFile);
var csResolver = CompletionContextProvider.GetResolver (GetState(), root);
var result = csResolver.Resolve(resolveNode);
var state = csResolver.GetResolverStateBefore(resolveNode);
return Tuple.Create(result, state);
@ -839,128 +812,5 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -839,128 +812,5 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
#endregion
class DefaultMemberProvider : IMemberProvider
{
CSharpCompletionEngineBase engine;
public DefaultMemberProvider (CSharpCompletionEngineBase engine)
{
this.engine = engine;
}
public void GetCurrentMembers (int offset, out IUnresolvedTypeDefinition currentType, out IUnresolvedMember currentMember)
{
//var document = engine.document;
var location = engine.location;
currentType = null;
foreach (var type in engine.CSharpParsedFile.TopLevelTypeDefinitions) {
if (type.Region.Begin < location)
currentType = type;
}
currentType = FindInnerType (currentType, location);
// location is beyond last reported end region, now we need to check, if the end region changed
if (currentType != null && currentType.Region.End < location) {
if (!IsInsideType (currentType, location))
currentType = null;
}
currentMember = null;
if (currentType != null) {
foreach (var member in currentType.Members) {
if (member.Region.Begin < location && (currentMember == null || currentMember.Region.Begin < member.Region.Begin))
currentMember = member;
}
}
// location is beyond last reported end region, now we need to check, if the end region changed
// NOTE: Enums are a special case, there the "last" field needs to be treated as current member
if (currentMember != null && currentMember.Region.End < location && currentType.Kind != TypeKind.Enum) {
if (!IsInsideType (currentMember, location))
currentMember = null;
}
var stack = GetBracketStack (engine.GetMemberTextToCaret ().Item1);
if (stack.Count == 0)
currentMember = null;
}
IUnresolvedTypeDefinition FindInnerType (IUnresolvedTypeDefinition parent, TextLocation location)
{
if (parent == null)
return null;
var currentType = parent;
foreach (var type in parent.NestedTypes) {
if (type.Region.Begin < location && location < type.Region.End)
currentType = FindInnerType (type, location);
}
return currentType;
}
bool IsInsideType (IUnresolvedEntity currentType, TextLocation location)
{
var document = engine.document;
int startOffset = document.GetOffset (currentType.Region.Begin);
int endOffset = document.GetOffset (location);
//bool foundEndBracket = false;
var bracketStack = new Stack<char> ();
bool isInString = false, isInChar = false;
bool isInLineComment = false, isInBlockComment = false;
for (int i = startOffset; i < endOffset; i++) {
char ch = document.GetCharAt (i);
switch (ch) {
case '(':
case '[':
case '{':
if (!isInString && !isInChar && !isInLineComment && !isInBlockComment)
bracketStack.Push (ch);
break;
case ')':
case ']':
case '}':
if (!isInString && !isInChar && !isInLineComment && !isInBlockComment)
if (bracketStack.Count > 0)
bracketStack.Pop ();
break;
case '\r':
case '\n':
isInLineComment = false;
break;
case '/':
if (isInBlockComment) {
if (i > 0 && document.GetCharAt (i - 1) == '*')
isInBlockComment = false;
} else if (!isInString && !isInChar && i + 1 < document.TextLength) {
char nextChar = document.GetCharAt (i + 1);
if (nextChar == '/')
isInLineComment = true;
if (!isInLineComment && nextChar == '*')
isInBlockComment = true;
}
break;
case '"':
if (!(isInChar || isInLineComment || isInBlockComment))
isInString = !isInString;
break;
case '\'':
if (!(isInString || isInLineComment || isInBlockComment))
isInChar = !isInChar;
break;
default :
break;
}
}
return bracketStack.Any (t => t == '{');
}
}
}
}

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

@ -39,7 +39,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -39,7 +39,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
{
internal IParameterCompletionDataFactory factory;
public CSharpParameterCompletionEngine(IDocument document, IParameterCompletionDataFactory factory, IProjectContent content, CSharpTypeResolveContext ctx, CompilationUnit unit, CSharpParsedFile parsedFile) : base (content, ctx, unit, parsedFile)
public CSharpParameterCompletionEngine(IDocument document, ICompletionContextProvider completionContextProvider, IParameterCompletionDataFactory factory, IProjectContent content, CSharpTypeResolveContext ctx) : base (content, completionContextProvider, ctx)
{
if (document == null) {
throw new ArgumentNullException("document");
@ -57,9 +57,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -57,9 +57,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
if (currentMember == null && currentType == null) {
return null;
}
if (Unit == null) {
return null;
}
baseUnit = ParseStub("x] = a[1");
//var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin;
@ -80,9 +77,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -80,9 +77,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
if (currentMember == null && currentType == null) {
return null;
}
if (Unit == null) {
return null;
}
baseUnit = ParseStub("a) {}", false);
var expr = baseUnit.GetNodeAt <ConstructorInitializer>(location);
@ -98,9 +92,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -98,9 +92,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
if (currentMember == null && currentType == null) {
return null;
}
if (Unit == null) {
return null;
}
baseUnit = ParseStub("x> a");
//var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin;
@ -171,7 +162,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -171,7 +162,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
}
if (invoke.Node is ObjectCreateExpression) {
var createType = ResolveExpression(((ObjectCreateExpression)invoke.Node).Type, invoke.Unit);
var createType = ResolveExpression(((ObjectCreateExpression)invoke.Node).Type);
if (createType.Item1.Type.Kind == TypeKind.Unknown)
return null;
return factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), createType.Item1.Type);
@ -234,7 +225,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -234,7 +225,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
if (GetCurrentParameterIndex(document.GetOffset(invoke.Node.StartLocation), offset) < 0)
return null;
if (invoke.Node is ObjectCreateExpression) {
var createType = ResolveExpression(((ObjectCreateExpression)invoke.Node).Type, invoke.Unit);
var createType = ResolveExpression(((ObjectCreateExpression)invoke.Node).Type);
return factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), createType.Item1.Type);
}
@ -316,17 +307,12 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -316,17 +307,12 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
List<string> GetUsedNamespaces()
{
var scope = CSharpParsedFile.GetUsingScope(location);
var scope = ctx.CurrentUsingScope;
var result = new List<string>();
var resolver = new CSharpResolver(ctx);
while (scope != null) {
result.Add(scope.NamespaceName);
result.Add(scope.Namespace.FullName);
foreach (var u in scope.Usings) {
var ns = u.ResolveNamespace(resolver);
if (ns == null) {
continue;
}
foreach (var ns in scope.Usings) {
result.Add(ns.FullName);
}
scope = scope.Parent;

198
ICSharpCode.NRefactory.CSharp/Completion/ICompletionContextProvider.cs

@ -0,0 +1,198 @@ @@ -0,0 +1,198 @@
//
// IMemberProvider.cs
//
// Author:
// Mike Krüger <mkrueger@xamarin.com>
//
// Copyright (c) 2012 Xamarin Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.CSharp.TypeSystem;
using System.Linq;
using ICSharpCode.NRefactory.CSharp.Resolver;
namespace ICSharpCode.NRefactory.CSharp.Completion
{
public interface ICompletionContextProvider
{
void GetCurrentMembers (int offset, out IUnresolvedTypeDefinition currentType, out IUnresolvedMember currentMember);
Tuple<string, TextLocation> GetMemberTextToCaret(int caretOffset, IUnresolvedTypeDefinition currentType, IUnresolvedMember currentMember);
CSharpAstResolver GetResolver (CSharpResolver resolver, AstNode rootNode);
}
public class DefaultCompletionContextProvider : ICompletionContextProvider
{
readonly IDocument document;
readonly CSharpParsedFile parsedFile;
public DefaultCompletionContextProvider (IDocument document, CSharpParsedFile parsedFile)
{
if (document == null)
throw new ArgumentNullException("document");
if (parsedFile == null)
throw new ArgumentNullException("parsedFile");
this.document = document;
this.parsedFile = parsedFile;
}
public void GetCurrentMembers(int offset, out IUnresolvedTypeDefinition currentType, out IUnresolvedMember currentMember)
{
//var document = engine.document;
var location = document.GetLocation(offset);
currentType = null;
foreach (var type in parsedFile.TopLevelTypeDefinitions) {
if (type.Region.Begin < location)
currentType = type;
}
currentType = FindInnerType (currentType, location);
// location is beyond last reported end region, now we need to check, if the end region changed
if (currentType != null && currentType.Region.End < location) {
if (!IsInsideType (currentType, location))
currentType = null;
}
currentMember = null;
if (currentType != null) {
foreach (var member in currentType.Members) {
if (member.Region.Begin < location && (currentMember == null || currentMember.Region.Begin < member.Region.Begin))
currentMember = member;
}
}
// location is beyond last reported end region, now we need to check, if the end region changed
// NOTE: Enums are a special case, there the "last" field needs to be treated as current member
if (currentMember != null && currentMember.Region.End < location && currentType.Kind != TypeKind.Enum) {
if (!IsInsideType (currentMember, location))
currentMember = null;
}/*
var stack = GetBracketStack (engine.GetMemberTextToCaret ().Item1);
if (stack.Count == 0)
currentMember = null;*/
}
IUnresolvedTypeDefinition FindInnerType (IUnresolvedTypeDefinition parent, TextLocation location)
{
if (parent == null)
return null;
var currentType = parent;
foreach (var type in parent.NestedTypes) {
if (type.Region.Begin < location && location < type.Region.End)
currentType = FindInnerType (type, location);
}
return currentType;
}
bool IsInsideType (IUnresolvedEntity currentType, TextLocation location)
{
int startOffset = document.GetOffset (currentType.Region.Begin);
int endOffset = document.GetOffset (location);
//bool foundEndBracket = false;
var bracketStack = new Stack<char> ();
bool isInString = false, isInChar = false;
bool isInLineComment = false, isInBlockComment = false;
for (int i = startOffset; i < endOffset; i++) {
char ch = document.GetCharAt (i);
switch (ch) {
case '(':
case '[':
case '{':
if (!isInString && !isInChar && !isInLineComment && !isInBlockComment)
bracketStack.Push (ch);
break;
case ')':
case ']':
case '}':
if (!isInString && !isInChar && !isInLineComment && !isInBlockComment)
if (bracketStack.Count > 0)
bracketStack.Pop ();
break;
case '\r':
case '\n':
isInLineComment = false;
break;
case '/':
if (isInBlockComment) {
if (i > 0 && document.GetCharAt (i - 1) == '*')
isInBlockComment = false;
} else if (!isInString && !isInChar && i + 1 < document.TextLength) {
char nextChar = document.GetCharAt (i + 1);
if (nextChar == '/')
isInLineComment = true;
if (!isInLineComment && nextChar == '*')
isInBlockComment = true;
}
break;
case '"':
if (!(isInChar || isInLineComment || isInBlockComment))
isInString = !isInString;
break;
case '\'':
if (!(isInString || isInLineComment || isInBlockComment))
isInChar = !isInChar;
break;
default :
break;
}
}
return bracketStack.Any (t => t == '{');
}
public Tuple<string, TextLocation> GetMemberTextToCaret(int caretOffset, IUnresolvedTypeDefinition currentType, IUnresolvedMember currentMember)
{
int startOffset;
if (currentMember != null && currentType != null && currentType.Kind != TypeKind.Enum) {
startOffset = document.GetOffset(currentMember.Region.Begin);
} else if (currentType != null) {
startOffset = document.GetOffset(currentType.Region.Begin);
} else {
startOffset = 0;
}
while (startOffset > 0) {
char ch = document.GetCharAt(startOffset - 1);
if (ch != ' ' && ch != '\t') {
break;
}
--startOffset;
}
return Tuple.Create (document.GetText (startOffset, caretOffset - startOffset), document.GetLocation (startOffset));
}
public CSharpAstResolver GetResolver (CSharpResolver resolver, AstNode rootNode)
{
return new CSharpAstResolver (resolver, rootNode, parsedFile);
}
}
}

40
ICSharpCode.NRefactory.CSharp/Completion/IMemberProvider.cs

@ -1,40 +0,0 @@ @@ -1,40 +0,0 @@
//
// IMemberProvider.cs
//
// Author:
// Mike Krüger <mkrueger@xamarin.com>
//
// Copyright (c) 2012 Xamarin Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.CSharp.TypeSystem;
using System.Linq;
namespace ICSharpCode.NRefactory.CSharp.Completion
{
public interface IMemberProvider
{
void GetCurrentMembers (int offset, out IUnresolvedTypeDefinition currentType, out IUnresolvedMember currentMember);
}
}

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

@ -1822,7 +1822,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1822,7 +1822,7 @@ namespace ICSharpCode.NRefactory.CSharp
if (methodCallArgumentWrapping == Wrapping.DoNotWrap) {
ForceSpacesBeforeRemoveNewLines(rParToken, spaceWithinMethodCallParentheses);
} else {
bool sameLine = rParToken.GetPrevNode().StartLocation.Line == rParToken.StartLocation.Line;
bool sameLine = rParToken.GetPrevNode().EndLocation.Line == rParToken.StartLocation.Line;
if (sameLine) {
ForceSpacesBeforeRemoveNewLines(rParToken, spaceWithinMethodCallParentheses);
} else {

8
ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<PropertyGroup>
<ProjectGuid>{53DCA265-3C3C-42F9-B647-F72BA678122B}</ProjectGuid>
@ -41,8 +41,7 @@ @@ -41,8 +41,7 @@
<DefineConstants>TRACE;FULL_AST</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>PdbOnly</DebugType>
<DebugSymbols>false</DebugSymbols>
<DebugType>none</DebugType>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugType>full</DebugType>
@ -294,7 +293,6 @@ @@ -294,7 +293,6 @@
<Compile Include="Completion\CSharpCompletionEngine.cs" />
<Compile Include="Completion\CSharpCompletionEngineBase.cs" />
<Compile Include="Completion\CSharpParameterCompletionEngine.cs" />
<Compile Include="Completion\IMemberProvider.cs" />
<Compile Include="Parser\mcs\module.cs" />
<Compile Include="Parser\mcs\settings.cs" />
<Compile Include="Parser\mcs\SourceMethodBuilder.cs" />
@ -381,6 +379,8 @@ @@ -381,6 +379,8 @@
<Compile Include="Refactoring\CodeActions\StaticMethodInvocationToExtensionMethodInvocationAction.cs" />
<Compile Include="Refactoring\CodeActions\ExtensionMethodInvocationToStaticMethodInvocationAction.cs" />
<Compile Include="Refactoring\CodeActions\IterateViaForeachAction.cs" />
<Compile Include="Refactoring\CodeActions\ExtractFieldAction.cs" />
<Compile Include="Completion\ICompletionContextProvider.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj">

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

@ -1007,6 +1007,14 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1007,6 +1007,14 @@ namespace ICSharpCode.NRefactory.CSharp
EndNode(primitiveExpression);
}
public static string PrintPrimitiveValue(object val)
{
StringWriter writer = new StringWriter();
CSharpOutputVisitor visitor = new CSharpOutputVisitor(writer, new CSharpFormattingOptions());
visitor.WritePrimitiveValue(val);
return writer.ToString();
}
void WritePrimitiveValue(object val)
{
if (val == null) {

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

@ -21,12 +21,12 @@ using System.CodeDom; @@ -21,12 +21,12 @@ using System.CodeDom;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using ICSharpCode.NRefactory.CSharp.Refactoring;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.CSharp.TypeSystem;
using ICSharpCode.NRefactory.PatternMatching;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.CSharp
{
@ -40,14 +40,23 @@ namespace ICSharpCode.NRefactory.CSharp @@ -40,14 +40,23 @@ namespace ICSharpCode.NRefactory.CSharp
{
//ICompilation compilation = MinimalResolveContext.Instance;
CSharpAstResolver resolver;
bool useFullyQualifiedTypeNames;
/// <summary>
/// Gets/Sets whether the visitor should use fully-qualified type references.
/// </summary>
public bool UseFullyQualifiedTypeNames {
get { return useFullyQualifiedTypeNames; }
set { useFullyQualifiedTypeNames = value; }
public bool UseFullyQualifiedTypeNames { get; set; }
/// <summary>
/// Gets whether the visitor is allowed to produce snippet nodes for
/// code that cannot be converted.
/// The default is true. If this property is set to false,
/// unconvertible code will throw a NotSupportedException.
/// </summary>
public bool AllowSnippetNodes { get; set; }
public CodeDomConvertVisitor()
{
this.AllowSnippetNodes = true;
}
/// <summary>
@ -136,8 +145,16 @@ namespace ICSharpCode.NRefactory.CSharp @@ -136,8 +145,16 @@ namespace ICSharpCode.NRefactory.CSharp
CodeTypeReference Convert(IType type)
{
if (type.Kind == TypeKind.Array) {
ArrayType a = (ArrayType)type;
return new CodeTypeReference(Convert(a.ElementType), a.Dimensions);
} else if (type is ParameterizedType) {
var pt = (ParameterizedType)type;
return new CodeTypeReference(pt.GetDefinition().ReflectionName, pt.TypeArguments.Select(Convert).ToArray());
} else {
return new CodeTypeReference(type.ReflectionName);
}
}
CodeStatement Convert(Statement stmt)
{
@ -148,6 +165,8 @@ namespace ICSharpCode.NRefactory.CSharp @@ -148,6 +165,8 @@ namespace ICSharpCode.NRefactory.CSharp
{
List<CodeStatement> result = new List<CodeStatement>();
foreach (Statement stmt in block.Statements) {
if (stmt is EmptyStatement)
continue;
CodeStatement s = Convert(stmt);
if (s != null)
result.Add(s);
@ -160,6 +179,8 @@ namespace ICSharpCode.NRefactory.CSharp @@ -160,6 +179,8 @@ namespace ICSharpCode.NRefactory.CSharp
BlockStatement block = embeddedStatement as BlockStatement;
if (block != null) {
return ConvertBlock(block);
} else if (embeddedStatement is EmptyStatement) {
return new CodeStatement[0];
}
CodeStatement s = Convert(embeddedStatement);
if (s != null)
@ -170,6 +191,8 @@ namespace ICSharpCode.NRefactory.CSharp @@ -170,6 +191,8 @@ namespace ICSharpCode.NRefactory.CSharp
string MakeSnippet(AstNode node)
{
if (!AllowSnippetNodes)
throw new NotSupportedException();
StringWriter w = new StringWriter();
CSharpOutputVisitor v = new CSharpOutputVisitor(w, FormattingOptionsFactory.CreateMono ());
node.AcceptVisitor(v);
@ -371,7 +394,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -371,7 +394,7 @@ namespace ICSharpCode.NRefactory.CSharp
TypeResolveResult trr = rr as TypeResolveResult;
if (trr != null) {
CodeTypeReference typeRef;
if (useFullyQualifiedTypeNames) {
if (UseFullyQualifiedTypeNames) {
typeRef = Convert(trr.Type);
} else {
typeRef = new CodeTypeReference(identifierExpression.Identifier);
@ -380,7 +403,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -380,7 +403,7 @@ namespace ICSharpCode.NRefactory.CSharp
return new CodeTypeReferenceExpression(typeRef);
}
MethodGroupResolveResult mgrr = rr as MethodGroupResolveResult;
if (mgrr != null) {
if (mgrr != null || identifierExpression.TypeArguments.Any()) {
return new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), identifierExpression.Identifier, Convert(identifierExpression.TypeArguments));
}
return new CodeVariableReferenceExpression(identifierExpression.Identifier);
@ -658,7 +681,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -658,7 +681,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration)
{
CodeTypeDelegate d = new CodeTypeDelegate(delegateDeclaration.Name);
d.Attributes = ConvertMemberAttributes(delegateDeclaration.Modifiers);
d.Attributes = ConvertMemberAttributes(delegateDeclaration.Modifiers, EntityType.TypeDefinition);
d.CustomAttributes.AddRange(Convert(delegateDeclaration.Attributes));
d.ReturnType = Convert(delegateDeclaration.ReturnType);
d.Parameters.AddRange(Convert(delegateDeclaration.Parameters));
@ -666,13 +689,15 @@ namespace ICSharpCode.NRefactory.CSharp @@ -666,13 +689,15 @@ namespace ICSharpCode.NRefactory.CSharp
return d;
}
static MemberAttributes ConvertMemberAttributes(Modifiers modifiers)
MemberAttributes ConvertMemberAttributes(Modifiers modifiers, EntityType entityType)
{
MemberAttributes a = 0;
if ((modifiers & Modifiers.Abstract) != 0)
a |= MemberAttributes.Abstract;
if ((modifiers & Modifiers.Sealed) != 0)
a |= MemberAttributes.Final;
if (entityType != EntityType.TypeDefinition && (modifiers & (Modifiers.Abstract | Modifiers.Override | Modifiers.Virtual)) == 0)
a |= MemberAttributes.Final;
if ((modifiers & Modifiers.Static) != 0)
a |= MemberAttributes.Static;
if ((modifiers & Modifiers.Override) != 0)
@ -719,7 +744,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -719,7 +744,7 @@ namespace ICSharpCode.NRefactory.CSharp
{
//bool isNestedType = typeStack.Count > 0;
CodeTypeDeclaration typeDecl = new CodeTypeDeclaration(typeDeclaration.Name);
typeDecl.Attributes = ConvertMemberAttributes(typeDeclaration.Modifiers);
typeDecl.Attributes = ConvertMemberAttributes(typeDeclaration.Modifiers, EntityType.TypeDefinition);
typeDecl.CustomAttributes.AddRange(Convert(typeDeclaration.Attributes));
switch (typeDeclaration.ClassType) {
@ -809,7 +834,12 @@ namespace ICSharpCode.NRefactory.CSharp @@ -809,7 +834,12 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitEmptyStatement(EmptyStatement emptyStatement)
{
return null;
return EmptyStatement();
}
CodeStatement EmptyStatement()
{
return new CodeExpressionStatement(new CodeObjectCreateExpression(new CodeTypeReference(typeof(object))));
}
CodeObject IAstVisitor<CodeObject>.VisitExpressionStatement(ExpressionStatement expressionStatement)
@ -817,10 +847,55 @@ namespace ICSharpCode.NRefactory.CSharp @@ -817,10 +847,55 @@ namespace ICSharpCode.NRefactory.CSharp
AssignmentExpression assignment = expressionStatement.Expression as AssignmentExpression;
if (assignment != null && assignment.Operator == AssignmentOperatorType.Assign) {
return new CodeAssignStatement(Convert(assignment.Left), Convert(assignment.Right));
} else if (assignment != null && CanBeDuplicatedForCompoundAssignment(assignment.Left)) {
CodeBinaryOperatorType op;
switch (assignment.Operator) {
case AssignmentOperatorType.Add:
op = CodeBinaryOperatorType.Add;
break;
case AssignmentOperatorType.Subtract:
op = CodeBinaryOperatorType.Subtract;
break;
case AssignmentOperatorType.Multiply:
op = CodeBinaryOperatorType.Multiply;
break;
case AssignmentOperatorType.Divide:
op = CodeBinaryOperatorType.Divide;
break;
case AssignmentOperatorType.Modulus:
op = CodeBinaryOperatorType.Modulus;
break;
case AssignmentOperatorType.BitwiseAnd:
op = CodeBinaryOperatorType.BitwiseAnd;
break;
case AssignmentOperatorType.BitwiseOr:
op = CodeBinaryOperatorType.BitwiseOr;
break;
default:
return MakeSnippetStatement(expressionStatement);
}
var cboe = new CodeBinaryOperatorExpression(Convert(assignment.Left), op, Convert(assignment.Right));
return new CodeAssignStatement(Convert(assignment.Left), cboe);
}
UnaryOperatorExpression unary = expressionStatement.Expression as UnaryOperatorExpression;
if (unary != null && CanBeDuplicatedForCompoundAssignment(unary.Expression)) {
var op = unary.Operator;
if (op == UnaryOperatorType.Increment || op == UnaryOperatorType.PostIncrement) {
var cboe = new CodeBinaryOperatorExpression(Convert(unary.Expression), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1));
return new CodeAssignStatement(Convert(unary.Expression), cboe);
} else if (op == UnaryOperatorType.Decrement || op == UnaryOperatorType.PostDecrement) {
var cboe = new CodeBinaryOperatorExpression(Convert(unary.Expression), CodeBinaryOperatorType.Subtract, new CodePrimitiveExpression(1));
return new CodeAssignStatement(Convert(unary.Expression), cboe);
}
}
return new CodeExpressionStatement(Convert(expressionStatement.Expression));
}
bool CanBeDuplicatedForCompoundAssignment(Expression expr)
{
return expr is IdentifierExpression;
}
CodeObject IAstVisitor<CodeObject>.VisitFixedStatement(FixedStatement fixedStatement)
{
return MakeSnippetStatement(fixedStatement);
@ -956,7 +1031,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -956,7 +1031,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitWhileStatement(WhileStatement whileStatement)
{
return new CodeIterationStatement(null, Convert(whileStatement.Condition), null, ConvertEmbeddedStatement(whileStatement.EmbeddedStatement));
return new CodeIterationStatement(EmptyStatement(), Convert(whileStatement.Condition), EmptyStatement(), ConvertEmbeddedStatement(whileStatement.EmbeddedStatement));
}
CodeObject IAstVisitor<CodeObject>.VisitYieldBreakStatement(YieldBreakStatement yieldBreakStatement)
@ -977,7 +1052,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -977,7 +1052,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration)
{
CodeConstructor ctor = new CodeConstructor();
ctor.Attributes = ConvertMemberAttributes(constructorDeclaration.Modifiers);
ctor.Attributes = ConvertMemberAttributes(constructorDeclaration.Modifiers, EntityType.Constructor);
ctor.CustomAttributes.AddRange(Convert(constructorDeclaration.Attributes));
if (constructorDeclaration.Initializer.ConstructorInitializerType == ConstructorInitializerType.This) {
ctor.ChainedConstructorArgs.AddRange(Convert(constructorDeclaration.Initializer.Arguments));
@ -1019,7 +1094,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1019,7 +1094,7 @@ namespace ICSharpCode.NRefactory.CSharp
}
CodeMemberEvent e = new CodeMemberEvent();
e.Attributes = ConvertMemberAttributes(eventDeclaration.Modifiers);
e.Attributes = ConvertMemberAttributes(eventDeclaration.Modifiers, EntityType.Event);
e.CustomAttributes.AddRange(Convert(eventDeclaration.Attributes));
e.Name = vi.Name;
e.Type = Convert(eventDeclaration.ReturnType);
@ -1037,7 +1112,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1037,7 +1112,7 @@ namespace ICSharpCode.NRefactory.CSharp
{
foreach (VariableInitializer vi in fieldDeclaration.Variables) {
CodeMemberField f = new CodeMemberField(Convert(fieldDeclaration.ReturnType), vi.Name);
f.Attributes = ConvertMemberAttributes(fieldDeclaration.Modifiers);
f.Attributes = ConvertMemberAttributes(fieldDeclaration.Modifiers, EntityType.Field);
f.CustomAttributes.AddRange(Convert(fieldDeclaration.Attributes));
f.InitExpression = ConvertVariableInitializer(vi.Initializer, fieldDeclaration.ReturnType);
AddTypeMember(f);
@ -1048,7 +1123,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1048,7 +1123,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration)
{
CodeMemberProperty p = new CodeMemberProperty();
p.Attributes = ConvertMemberAttributes(indexerDeclaration.Modifiers);
p.Attributes = ConvertMemberAttributes(indexerDeclaration.Modifiers, EntityType.Indexer);
p.CustomAttributes.AddRange(Convert(indexerDeclaration.Attributes));
p.Name = "Items";
p.PrivateImplementationType = Convert(indexerDeclaration.PrivateImplementationType);
@ -1069,7 +1144,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1069,7 +1144,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitMethodDeclaration(MethodDeclaration methodDeclaration)
{
CodeMemberMethod m = new CodeMemberMethod();
m.Attributes = ConvertMemberAttributes(methodDeclaration.Modifiers);
m.Attributes = ConvertMemberAttributes(methodDeclaration.Modifiers, EntityType.Method);
m.CustomAttributes.AddRange(Convert(methodDeclaration.Attributes.Where(a => a.AttributeTarget != "return")));
m.ReturnTypeCustomAttributes.AddRange(Convert(methodDeclaration.Attributes.Where(a => a.AttributeTarget == "return")));
@ -1087,7 +1162,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1087,7 +1162,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration)
{
CodeMemberMethod m = new CodeMemberMethod();
m.Attributes = ConvertMemberAttributes(operatorDeclaration.Modifiers);
m.Attributes = ConvertMemberAttributes(operatorDeclaration.Modifiers, EntityType.Method);
m.CustomAttributes.AddRange(Convert(operatorDeclaration.Attributes.Where(a => a.AttributeTarget != "return")));
m.ReturnTypeCustomAttributes.AddRange(Convert(operatorDeclaration.Attributes.Where(a => a.AttributeTarget == "return")));
@ -1129,7 +1204,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1129,7 +1204,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)
{
CodeMemberProperty p = new CodeMemberProperty();
p.Attributes = ConvertMemberAttributes(propertyDeclaration.Modifiers);
p.Attributes = ConvertMemberAttributes(propertyDeclaration.Modifiers, EntityType.Property);
p.CustomAttributes.AddRange(Convert(propertyDeclaration.Attributes));
p.Name = propertyDeclaration.Name;
p.PrivateImplementationType = Convert(propertyDeclaration.PrivateImplementationType);
@ -1181,7 +1256,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1181,7 +1256,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitSimpleType(SimpleType simpleType)
{
if (useFullyQualifiedTypeNames) {
if (UseFullyQualifiedTypeNames) {
IType type = Resolve(simpleType).Type;
if (type.Kind != TypeKind.Unknown)
return Convert(type);
@ -1198,7 +1273,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1198,7 +1273,7 @@ namespace ICSharpCode.NRefactory.CSharp
tr.TypeArguments.AddRange(Convert(memberType.TypeArguments));
return tr;
}
if (useFullyQualifiedTypeNames || memberType.IsDoubleColon) {
if (UseFullyQualifiedTypeNames || memberType.IsDoubleColon) {
IType type = Resolve(memberType).Type;
if (type.Kind != TypeKind.Unknown)
return Convert(type);
@ -1309,7 +1384,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -1309,7 +1384,7 @@ namespace ICSharpCode.NRefactory.CSharp
return null;
}
CodeObject IAstVisitor<CodeObject>.VisitPatternPlaceholder(AstNode placeholder, ICSharpCode.NRefactory.PatternMatching.Pattern pattern)
CodeObject IAstVisitor<CodeObject>.VisitPatternPlaceholder(AstNode placeholder, Pattern pattern)
{
return null;
}

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

@ -3598,6 +3598,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -3598,6 +3598,7 @@ namespace ICSharpCode.NRefactory.CSharp
}
ErrorReportPrinter errorReportPrinter = new ErrorReportPrinter (null);
[Obsolete("Use the Errors/Warnings/ErrorsAndWarnings properties instead")]
public ErrorReportPrinter ErrorPrinter {
get {
return errorReportPrinter;
@ -3616,6 +3617,22 @@ namespace ICSharpCode.NRefactory.CSharp @@ -3616,6 +3617,22 @@ namespace ICSharpCode.NRefactory.CSharp
}
}
public IEnumerable<Error> Errors {
get {
return errorReportPrinter.Errors.Where(e => e.ErrorType == ErrorType.Error);
}
}
public IEnumerable<Error> Warnings {
get {
return errorReportPrinter.Errors.Where(e => e.ErrorType == ErrorType.Warning);
}
}
public IEnumerable<Error> ErrorsAndWarnings {
get { return errorReportPrinter.Errors; }
}
public CompilationUnit Parse (ITextSource textSource, string fileName, int lineModifier = 0)
{
return Parse (textSource.CreateReader (), fileName, lineModifier);
@ -3733,7 +3750,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -3733,7 +3750,7 @@ namespace ICSharpCode.NRefactory.CSharp
return AstType.Null;
}
public AstNode ParseExpression (TextReader reader)
public Expression ParseExpression (TextReader reader)
{
var es = ParseStatements (new StringReader ("tmp = " + Environment.NewLine + reader.ReadToEnd () + ";"), -1).FirstOrDefault () as ExpressionStatement;
if (es != null) {
@ -3741,7 +3758,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -3741,7 +3758,7 @@ namespace ICSharpCode.NRefactory.CSharp
if (ae != null)
return ae.Right;
}
return null;
return Expression.Null;
}
/// <summary>

2
ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreatePropertyAction.cs

@ -63,6 +63,8 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -63,6 +63,8 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
ResolveResult targetResolveResult = null;
if (identifier is MemberReferenceExpression) {
targetResolveResult = context.Resolve(((MemberReferenceExpression)identifier).Target);
if (targetResolveResult.Type.GetDefinition() == null || targetResolveResult.Type.GetDefinition().Region.IsEmpty)
yield break;
createInOtherType = !state.CurrentTypeDefinition.Equals(targetResolveResult.Type.GetDefinition());
}

93
ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ExtractFieldAction.cs

@ -0,0 +1,93 @@ @@ -0,0 +1,93 @@
//
// ExtractFieldAction.cs
//
// Author:
// Nieve <>
//
// Copyright (c) 2012 Nieve
//
// 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.Linq;
using ICSharpCode.NRefactory.PatternMatching;
using Mono.CSharp;
namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
[ContextAction("Extract field", Description = "Extracts a field from a local variable declaration.")]
public class ExtractFieldAction : ICodeActionProvider
{
public IEnumerable<CodeAction> GetActions(RefactoringContext context)
{
//TODO: implement variable assignment & ctor param
var varInit = context.GetNode<VariableInitializer>();
if (varInit != null) {
AstType type = varInit.GetPrevNode() as AstType;
if (type == null) yield break;
if (varInit.Parent is FieldDeclaration) yield break;
if (CannotExtractField(varInit)) yield break;
yield return new CodeAction("Extract field", s=>{
var name = varInit.Name;
FieldDeclaration field = new FieldDeclaration(){
ReturnType = type.Clone(),
Variables = { new VariableInitializer(name) }
};
AstNode nodeToRemove = RemoveDeclaration(varInit) ? varInit.Parent : type;
s.Remove(nodeToRemove, true);
s.InsertWithCursor(context.TranslateString("Extract field"),Script.InsertPosition.Before,field);
s.FormatText(varInit.Parent);
});
}
var idntf = context.GetNode<Identifier>();
if (idntf == null) yield break;
var paramDec = idntf.Parent as ParameterDeclaration;
if (paramDec != null) {
var ctor = paramDec.Parent as ConstructorDeclaration;
if (ctor == null) yield break;
MemberReferenceExpression thisField = new MemberReferenceExpression(new ThisReferenceExpression(), idntf.Name, new AstType[]{});
var assign = new AssignmentExpression(thisField, AssignmentOperatorType.Assign, new IdentifierExpression(idntf.Name));
var statement = new ExpressionStatement(assign);
var type = (idntf.GetPrevNode() as AstType).Clone();
FieldDeclaration field = new FieldDeclaration(){
ReturnType = type.Clone(),
Variables = { new VariableInitializer(idntf.Name) }
};
yield return new CodeAction("Extract field", s=>{
s.InsertWithCursor(context.TranslateString("Extract field"),Script.InsertPosition.Before,field);
s.AddTo(ctor.Body, statement);
});
}
}
static bool RemoveDeclaration (VariableInitializer varInit){
var result = varInit.Parent as VariableDeclarationStatement;
return result.Variables.First ().Initializer.IsNull;
}
static bool CannotExtractField (VariableInitializer varInit)
{
var result = varInit.Parent as VariableDeclarationStatement;
return result == null || result.Variables.Count != 1;
}
}
}

2
ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/UseExplicitTypeAction.cs

@ -52,7 +52,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -52,7 +52,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
if (!(!type.Equals(SpecialType.NullType) && !type.Equals(SpecialType.UnknownType))) {
yield break;
}
yield return new CodeAction (context.TranslateString("Use expcicit type"), script => {
yield return new CodeAction (context.TranslateString("Use explicit type"), script => {
if (varDecl != null) {
script.Replace (varDecl.Type, context.CreateShortType (type));
} else {

43
ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/InconsistentNamingIssue/DefaultRules.cs

@ -39,24 +39,28 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -39,24 +39,28 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
yield return new NamingRule(AffectedEntity.Class | AffectedEntity.Struct | AffectedEntity.Enum | AffectedEntity.Delegate) {
Name = "Types",
VisibilityMask = Modifiers.Public,
NamingStyle = NamingStyle.PascalCase
};
yield return new NamingRule(AffectedEntity.Interface) {
Name = "Interfaces",
NamingStyle = NamingStyle.PascalCase,
VisibilityMask = Modifiers.Public,
RequiredPrefixes = new [] { "I" }
};
yield return new NamingRule(AffectedEntity.CustomAttributes) {
Name = "Attributes",
NamingStyle = NamingStyle.PascalCase,
VisibilityMask = Modifiers.Public,
RequiredSuffixes = new [] { "Attribute" }
};
yield return new NamingRule(AffectedEntity.CustomEventArgs) {
Name = "Event Arguments",
NamingStyle = NamingStyle.PascalCase,
VisibilityMask = Modifiers.Public,
RequiredSuffixes = new [] { "EventArgs" }
};
@ -68,66 +72,45 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -68,66 +72,45 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
yield return new NamingRule(AffectedEntity.Methods) {
Name = "Methods",
VisibilityMask = Modifiers.Public | Modifiers.Protected,
NamingStyle = NamingStyle.PascalCase
};
yield return new NamingRule(AffectedEntity.ReadonlyField) {
Name = "Static Readonly Fields",
VisibilityMask = Modifiers.Public | Modifiers.Protected | Modifiers.Internal,
VisibilityMask = Modifiers.Public | Modifiers.Protected,
NamingStyle = NamingStyle.PascalCase,
IncludeInstanceMembers = false
};
yield return new NamingRule(AffectedEntity.Field) {
Name = "Fields (Non Private)",
Name = "Fields",
NamingStyle = NamingStyle.PascalCase,
VisibilityMask = Modifiers.Public | Modifiers.Protected | Modifiers.Internal
VisibilityMask = Modifiers.Public | Modifiers.Protected
};
yield return new NamingRule(AffectedEntity.ReadonlyField) {
Name = "ReadOnly Fields (Non Private)",
Name = "ReadOnly Fields",
NamingStyle = NamingStyle.PascalCase,
VisibilityMask = Modifiers.Public | Modifiers.Protected | Modifiers.Internal,
IncludeStaticEntities = false
};
yield return new NamingRule(AffectedEntity.Field | AffectedEntity.ReadonlyField) {
Name = "Fields (Private)",
NamingStyle = NamingStyle.CamelCase,
AllowedPrefixes = new [] { "_", "m_" },
VisibilityMask = Modifiers.Private,
IncludeStaticEntities = false
};
yield return new NamingRule(AffectedEntity.Field) {
Name = "Static Fields (Private)",
NamingStyle = NamingStyle.CamelCase,
VisibilityMask = Modifiers.Private,
IncludeStaticEntities = true,
IncludeInstanceMembers = false
};
yield return new NamingRule(AffectedEntity.ReadonlyField) {
Name = "ReadOnly Fields (Private)",
NamingStyle = NamingStyle.CamelCase,
VisibilityMask = Modifiers.Private,
AllowedPrefixes = new [] { "_", "m_" },
VisibilityMask = Modifiers.Public | Modifiers.Protected,
IncludeStaticEntities = false
};
yield return new NamingRule(AffectedEntity.ConstantField) {
Name = "Constant Fields",
NamingStyle = NamingStyle.PascalCase,
VisibilityMask = Modifiers.Public | Modifiers.Protected | Modifiers.Internal | Modifiers.Private
VisibilityMask = Modifiers.Public | Modifiers.Protected
};
yield return new NamingRule(AffectedEntity.Property) {
Name = "Properties",
VisibilityMask = Modifiers.Public | Modifiers.Protected,
NamingStyle = NamingStyle.PascalCase
};
yield return new NamingRule(AffectedEntity.Event) {
Name = "Events",
VisibilityMask = Modifiers.Public | Modifiers.Protected,
NamingStyle = NamingStyle.PascalCase
};

18
ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/InconsistentNamingIssue/WordParser.cs

@ -37,26 +37,28 @@ namespace ICSharpCode.NRefactory.CSharp @@ -37,26 +37,28 @@ namespace ICSharpCode.NRefactory.CSharp
bool lastWasLower = false, lastWasUpper = false;
for (int i = 0; i < identifier.Length; i++) {
char c = identifier[i];
if (c == '_') {
if ((i - wordStart) > 0) {
words.Add (identifier.Substring (wordStart, i - wordStart));
}
wordStart = i + 1;
lastWasLower = lastWasUpper = false;
} else if (Char.IsLower (c)) {
var category = char.GetUnicodeCategory (c);
if (category == System.Globalization.UnicodeCategory.LowercaseLetter) {
if (lastWasUpper && (i - wordStart) > 2) {
words.Add (identifier.Substring (wordStart, i - wordStart - 1));
wordStart = i - 1;
}
lastWasLower = true;
lastWasUpper = false;
} else if (Char.IsUpper (c)) {
} else if (category == System.Globalization.UnicodeCategory.UppercaseLetter) {
if (lastWasLower) {
words.Add (identifier.Substring (wordStart, i - wordStart));
wordStart = i;
}
lastWasLower = false;
lastWasUpper = true;
} else {
if (c == '_') {
if ((i - wordStart) > 0)
words.Add(identifier.Substring(wordStart, i - wordStart));
wordStart = i + 1;
lastWasLower = lastWasUpper = false;
}
}
}
if (wordStart < identifier.Length)

11
ICSharpCode.NRefactory.CSharp/Resolver/CSharpConversions.cs

@ -155,7 +155,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -155,7 +155,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return Conversion.NullLiteralConversion;
if (ImplicitReferenceConversion(fromType, toType, 0))
return Conversion.ImplicitReferenceConversion;
if (BoxingConversion(fromType, toType))
if (IsBoxingConversion(fromType, toType))
return Conversion.BoxingConversion;
if (fromType.Kind == TypeKind.Dynamic)
return Conversion.ImplicitDynamicConversion;
@ -184,7 +184,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -184,7 +184,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return true;
if (ImplicitReferenceConversion(fromType, toType, 0))
return true;
if (BoxingConversion(fromType, toType) && !NullableType.IsNullable(fromType))
if (IsBoxingConversion(fromType, toType) && !NullableType.IsNullable(fromType))
return true;
if (ImplicitTypeParameterConversion(fromType, toType))
return true;
@ -398,6 +398,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -398,6 +398,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#endregion
#region Implicit Reference Conversion
public bool IsImplicitReferenceConversion(IType fromType, IType toType)
{
return ImplicitReferenceConversion(fromType, toType, 0);
}
bool ImplicitReferenceConversion(IType fromType, IType toType, int subtypeCheckNestingDepth)
{
// C# 4.0 spec: §6.1.6
@ -510,7 +515,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -510,7 +515,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#endregion
#region Boxing Conversions
bool BoxingConversion(IType fromType, IType toType)
public bool IsBoxingConversion(IType fromType, IType toType)
{
// C# 4.0 spec: §6.1.7
fromType = NullableType.GetUnderlyingType(fromType);

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

@ -390,7 +390,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -390,7 +390,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
bool isNullable = NullableType.IsNullable(expression.Type);
// the operator is overloadable:
OverloadResolution userDefinedOperatorOR = new OverloadResolution(compilation, new[] { expression }, conversions: conversions);
OverloadResolution userDefinedOperatorOR = CreateOverloadResolution(new[] { expression });
foreach (var candidate in GetUserDefinedOperatorCandidates(type, overloadableOperatorName)) {
userDefinedOperatorOR.AddCandidate(candidate);
}
@ -439,7 +439,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -439,7 +439,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
default:
throw new InvalidOperationException();
}
OverloadResolution builtinOperatorOR = new OverloadResolution(compilation, new[] { expression }, conversions: conversions);
OverloadResolution builtinOperatorOR = CreateOverloadResolution(new[] { expression });
foreach (var candidate in methodGroup) {
builtinOperatorOR.AddCandidate(candidate);
}
@ -569,7 +569,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -569,7 +569,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
IType rhsType = NullableType.GetUnderlyingType(rhs.Type);
// the operator is overloadable:
OverloadResolution userDefinedOperatorOR = new OverloadResolution(compilation, new[] { lhs, rhs }, conversions: conversions);
OverloadResolution userDefinedOperatorOR = CreateOverloadResolution(new[] { lhs, rhs });
HashSet<IParameterizedMember> userOperatorCandidates = new HashSet<IParameterizedMember>();
userOperatorCandidates.UnionWith(GetUserDefinedOperatorCandidates(lhsType, overloadableOperatorName));
userOperatorCandidates.UnionWith(GetUserDefinedOperatorCandidates(rhsType, overloadableOperatorName));
@ -800,7 +800,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -800,7 +800,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
default:
throw new InvalidOperationException();
}
OverloadResolution builtinOperatorOR = new OverloadResolution(compilation, new[] { lhs, rhs }, conversions: conversions);
OverloadResolution builtinOperatorOR = CreateOverloadResolution(new[] { lhs, rhs });
foreach (var candidate in methodGroup) {
builtinOperatorOR.AddCandidate(candidate);
}
@ -1260,7 +1260,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1260,7 +1260,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
else if (rr.IsCompileTimeConstant && c != Conversion.None)
return ResolveCast(targetType, rr);
else
return new ConversionResolveResult(targetType, rr, c);
return new ConversionResolveResult(targetType, rr, c, checkForOverflow);
}
public ResolveResult ResolveCast(IType targetType, ResolveResult expression)
@ -1291,7 +1291,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1291,7 +1291,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
}
Conversion c = conversions.ExplicitConversion(expression, targetType);
return new ConversionResolveResult(targetType, expression, c);
return new ConversionResolveResult(targetType, expression, c, checkForOverflow);
}
internal object CSharpPrimitiveCast(TypeCode targetType, object input)
@ -1891,7 +1891,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1891,7 +1891,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
MethodGroupResolveResult mgrr = target as MethodGroupResolveResult;
if (mgrr != null) {
OverloadResolution or = mgrr.PerformOverloadResolution(compilation, arguments, argumentNames, conversions: conversions);
OverloadResolution or = mgrr.PerformOverloadResolution(compilation, arguments, argumentNames, checkForOverflow: checkForOverflow, conversions: conversions);
if (or.BestCandidate != null) {
if (or.BestCandidate.IsStatic && !or.IsExtensionMethodInvocation && !(mgrr.TargetResult is TypeResolveResult))
return or.CreateResolveResult(new TypeResolveResult(mgrr.TargetResult.Type));
@ -1914,7 +1914,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1914,7 +1914,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
IMethod invokeMethod = target.Type.GetDelegateInvokeMethod();
if (invokeMethod != null) {
OverloadResolution or = new OverloadResolution(compilation, arguments, argumentNames, conversions: conversions);
OverloadResolution or = CreateOverloadResolution(arguments, argumentNames);
or.AddCandidate(invokeMethod);
return new CSharpInvocationResolveResult(
target, invokeMethod, //invokeMethod.ReturnType.Resolve(context),
@ -2003,6 +2003,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2003,6 +2003,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
variableName = variableName.Substring(1);
return char.ToLower(variableName[0]) + variableName.Substring(1);
}
OverloadResolution CreateOverloadResolution(ResolveResult[] arguments, string[] argumentNames = null, IType[] typeArguments = null)
{
var or = new OverloadResolution(compilation, arguments, argumentNames, typeArguments, conversions);
or.CheckForOverflow = checkForOverflow;
return or;
}
#endregion
#region ResolveIndexer
@ -2035,7 +2042,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2035,7 +2042,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
// §7.6.6.2 Indexer access
OverloadResolution or = new OverloadResolution(compilation, arguments, argumentNames, conversions: conversions);
OverloadResolution or = CreateOverloadResolution(arguments, argumentNames);
MemberLookup lookup = CreateMemberLookup();
var indexers = lookup.LookupIndexers(target.Type);
or.AddMethodLists(indexers);
@ -2090,7 +2097,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2090,7 +2097,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (type.Kind == TypeKind.Delegate && arguments.Length == 1) {
return Convert(arguments[0], type);
}
OverloadResolution or = new OverloadResolution(compilation, arguments, argumentNames, conversions: conversions);
OverloadResolution or = CreateOverloadResolution(arguments, argumentNames);
MemberLookup lookup = CreateMemberLookup();
foreach (IMethod ctor in type.GetConstructors()) {
if (lookup.IsAccessible(ctor, allowProtectedAccess))
@ -2197,6 +2204,27 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2197,6 +2204,27 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return Convert(input, boolean, c);
}
/// <summary>
/// Converts the negated input to <c>bool</c> using the rules for boolean expressions.
/// Computes <c>!(bool)input</c> if the implicit cast to bool is valid; otherwise
/// computes <c>input.operator false()</c>.
/// </summary>
public ResolveResult ResolveConditionFalse(ResolveResult input)
{
if (input == null)
throw new ArgumentNullException("input");
IType boolean = compilation.FindType(KnownTypeCode.Boolean);
Conversion c = conversions.ImplicitConversion(input, boolean);
if (!c.IsValid) {
var opFalse = input.Type.GetMethods(m => m.IsOperator && m.Name == "op_False").FirstOrDefault();
if (opFalse != null) {
c = Conversion.UserDefinedImplicitConversion(opFalse, false);
return Convert(input, boolean, c);
}
}
return ResolveUnaryOperator(UnaryOperatorType.Not, Convert(input, boolean, c));
}
public ResolveResult ResolveConditional(ResolveResult condition, ResolveResult trueExpression, ResolveResult falseExpression)
{
// C# 4.0 spec §7.14: Conditional operator

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

@ -178,7 +178,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -178,7 +178,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return string.Format("[{0} with {1} method(s)]", GetType().Name, this.Methods.Count());
}
public OverloadResolution PerformOverloadResolution(ICompilation compilation, ResolveResult[] arguments, string[] argumentNames = null, bool allowExtensionMethods = true, bool allowExpandingParams = true, CSharpConversions conversions = null)
public OverloadResolution PerformOverloadResolution(ICompilation compilation, ResolveResult[] arguments, string[] argumentNames = null, bool allowExtensionMethods = true, bool allowExpandingParams = true, bool checkForOverflow = false, CSharpConversions conversions = null)
{
Log.WriteLine("Performing overload resolution for " + this);
Log.WriteCollection(" Arguments: ", arguments);
@ -186,6 +186,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -186,6 +186,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
var typeArgumentArray = this.TypeArguments.ToArray();
OverloadResolution or = new OverloadResolution(compilation, arguments, argumentNames, typeArgumentArray, conversions);
or.AllowExpandingParams = allowExpandingParams;
or.CheckForOverflow = checkForOverflow;
or.AddMethodLists(methodLists);
@ -207,6 +208,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -207,6 +208,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
var extOr = new OverloadResolution(compilation, extArguments, extArgumentNames, typeArgumentArray, conversions);
extOr.AllowExpandingParams = allowExpandingParams;
extOr.IsExtensionMethodInvocation = true;
extOr.CheckForOverflow = checkForOverflow;
foreach (var g in extensionMethods) {
foreach (var method in g) {

11
ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs

@ -170,6 +170,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -170,6 +170,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// </summary>
public bool AllowExpandingParams { get; set; }
/// <summary>
/// Gets/Sets whether ConversionResolveResults created by this OverloadResolution
/// instance apply overflow checking.
/// The default value is false.
/// </summary>
public bool CheckForOverflow { get; set; }
/// <summary>
/// Gets the arguments for which this OverloadResolution instance was created.
/// </summary>
@ -801,9 +808,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -801,9 +808,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
parameterType = SpecialType.UnknownType;
}
if (arguments[i].IsCompileTimeConstant && conversions[i] != Conversion.None) {
args[i] = new CSharpResolver(compilation).ResolveCast(parameterType, argument);
args[i] = new CSharpResolver(compilation).WithCheckForOverflow(CheckForOverflow).ResolveCast(parameterType, argument);
} else {
args[i] = new ConversionResolveResult(parameterType, argument, conversions[i]);
args[i] = new ConversionResolveResult(parameterType, argument, conversions[i], CheckForOverflow);
}
}
}

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

@ -1243,7 +1243,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1243,7 +1243,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (resolverEnabled) {
ResolveResult input = Resolve(asExpression.Expression);
var targetType = ResolveType(asExpression.Type);
return new ConversionResolveResult(targetType, input, Conversion.TryCast);
return new ConversionResolveResult(targetType, input, Conversion.TryCast, resolver.CheckForOverflow);
} else {
ScanChildren(asExpression);
return null;
@ -1505,7 +1505,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1505,7 +1505,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
var addRR = memberLookup.Lookup(initializedObject, "Add", EmptyList<IType>.Instance, true);
var mgrr = addRR as MethodGroupResolveResult;
if (mgrr != null) {
OverloadResolution or = mgrr.PerformOverloadResolution(resolver.Compilation, addArguments, null, false, false, resolver.conversions);
OverloadResolution or = mgrr.PerformOverloadResolution(resolver.Compilation, addArguments, null, false, false, resolver.CheckForOverflow, resolver.conversions);
var invocationRR = or.CreateResolveResult(initializedObject);
StoreResult(aie, invocationRR);
ProcessConversionsInInvocation(null, aie.Elements, invocationRR);
@ -3422,7 +3422,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3422,7 +3422,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// </summary>
ResolveResult WrapResult(ResolveResult result)
{
return new ConversionResolveResult(result.Type, result, Conversion.IdentityConversion);
return new ConversionResolveResult(result.Type, result, Conversion.IdentityConversion, resolver.CheckForOverflow);
}
ResolveResult IAstVisitor<ResolveResult>.VisitQueryContinuationClause(QueryContinuationClause queryContinuationClause)
@ -3610,7 +3610,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3610,7 +3610,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ProcessConversion(queryWhereClause.Condition, condition, conversionToBool, boolType);
if (currentQueryResult != null) {
if (conversionToBool != Conversion.IdentityConversion && conversionToBool != Conversion.None) {
condition = new ConversionResolveResult(boolType, condition, conversionToBool);
condition = new ConversionResolveResult(boolType, condition, conversionToBool, resolver.CheckForOverflow);
}
var methodGroup = resolver.ResolveMemberAccess(currentQueryResult, "Where", EmptyList<IType>.Instance);

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

@ -677,6 +677,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -677,6 +677,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
if (accessor.IsNull)
return null;
var a = new DefaultUnresolvedMethod(currentTypeDefinition, prefix + p.Name);
a.AccessorOwner = p;
a.Accessibility = GetAccessibility(accessor.Modifiers) ?? p.Accessibility;
a.IsAbstract = p.IsAbstract;
a.IsOverride = p.IsOverridable;

2
ICSharpCode.NRefactory.ConsistencyCheck/CSharpProject.cs

@ -180,7 +180,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck @@ -180,7 +180,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck
this.CompilationUnit = p.Parse(Content.CreateReader(), fileName);
if (p.HasErrors) {
Console.WriteLine("Error parsing " + fileName + ":");
foreach (var error in p.ErrorPrinter.Errors) {
foreach (var error in p.ErrorsAndWarnings) {
Console.WriteLine(" " + error.Region + " " + error.Message);
}
}

2
ICSharpCode.NRefactory.Demo/CSDemo.cs

@ -94,7 +94,7 @@ namespace ICSharpCode.NRefactory.Demo @@ -94,7 +94,7 @@ namespace ICSharpCode.NRefactory.Demo
b.Append(node.GetType().Name);
bool hasProperties = false;
foreach (PropertyInfo p in node.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
if (p.Name == "NodeType" || p.Name == "IsNull")
if (p.Name == "NodeType" || p.Name == "IsNull" || p.Name == "IsFrozen" || p.Name == "HasChildren")
continue;
if (p.PropertyType == typeof(string) || p.PropertyType.IsEnum || p.PropertyType == typeof(bool)) {
if (!hasProperties) {

149
ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ExtractFieldTests.cs

@ -0,0 +1,149 @@ @@ -0,0 +1,149 @@
//
// CreateFieldTests.cs
//
// Author:
// Nieve Goor
//
// 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 NUnit.Framework;
using ICSharpCode.NRefactory.CSharp.Refactoring;
namespace ICSharpCode.NRefactory.CSharp.CodeActions
{
[TestFixture]
public class ExtractFieldTests : ContextActionTestBase
{
[Test]
public void TestWrongContext1 ()
{
TestWrongContext<ExtractFieldAction> (
"using System;" + Environment.NewLine +
"class TestClass" + Environment.NewLine +
"{" + Environment.NewLine +
" void Test ()" + Environment.NewLine +
" {" + Environment.NewLine +
" $foo = 2;" + Environment.NewLine +
" }" + Environment.NewLine +
"}"
);
}
[Test]
public void TestWrongContext2 ()
{
TestWrongContext<ExtractFieldAction> (
"using System;" + Environment.NewLine +
"class TestClass" + Environment.NewLine +
"{" + Environment.NewLine +
" int foo;" + Environment.NewLine +
" void Test ()" + Environment.NewLine +
" {" + Environment.NewLine +
" $foo = 2;" + Environment.NewLine +
" }" + Environment.NewLine +
"}"
);
}
[Test]
public void TestLocalInitializer()
{
string result = RunContextAction (
new ExtractFieldAction (),
"using System;" + Environment.NewLine +
"class TestClass" + Environment.NewLine +
"{" + Environment.NewLine +
" void Test ()" + Environment.NewLine +
" {" + Environment.NewLine +
" int $foo = 5;" + Environment.NewLine +
" }" + Environment.NewLine +
"}"
);
Console.WriteLine (result);
Assert.AreEqual (
"using System;" + Environment.NewLine +
"class TestClass" + Environment.NewLine +
"{" + Environment.NewLine +
" int foo;" + Environment.NewLine +
"" + Environment.NewLine +
" void Test ()" + Environment.NewLine +
" {" + Environment.NewLine +
" foo = 5;" + Environment.NewLine +
" }" + Environment.NewLine +
"}", result);
}
[Test]
public void TestLocalDeclaration()
{
string result = RunContextAction (
new ExtractFieldAction (),
"using System;" + Environment.NewLine +
"class TestClass" + Environment.NewLine +
"{" + Environment.NewLine +
" void Test ()" + Environment.NewLine +
" {" + Environment.NewLine +
" int $foo;" + Environment.NewLine +
" }" + Environment.NewLine +
"}"
);
Console.WriteLine (result);
Assert.AreEqual (
"using System;" + Environment.NewLine +
"class TestClass" + Environment.NewLine +
"{" + Environment.NewLine +
" int foo;" + Environment.NewLine +
"" + Environment.NewLine +
" void Test ()" + Environment.NewLine +
" {" + Environment.NewLine +
" }" + Environment.NewLine +
"}", result);
}
[Test]
public void TestCtorParam ()
{
string result = RunContextAction (
new ExtractFieldAction (),
"using System;" + Environment.NewLine +
"class TestClass" + Environment.NewLine +
"{" + Environment.NewLine +
" TestClass (int $foo)" + Environment.NewLine +
" {" + Environment.NewLine +
" " + Environment.NewLine +
" }" + Environment.NewLine +
"}"
);
Assert.AreEqual (
"using System;" + Environment.NewLine +
"class TestClass" + Environment.NewLine +
"{" + Environment.NewLine +
" int foo;" + Environment.NewLine +
"" + Environment.NewLine +
" TestClass (int foo)" + Environment.NewLine +
" {" + Environment.NewLine +
" this.foo = foo;" + Environment.NewLine +
" " + Environment.NewLine +
" }" + Environment.NewLine +
"}", result);
}
}
}

6
ICSharpCode.NRefactory.Tests/CSharp/CodeActions/TestRefactoringContext.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
//
//
// TestRefactoringContext.cs
//
// Author:
@ -246,8 +246,8 @@ namespace ICSharpCode.NRefactory.CSharp.CodeActions @@ -246,8 +246,8 @@ namespace ICSharpCode.NRefactory.CSharp.CodeActions
var doc = new StringBuilderDocument (content);
var parser = new CSharpParser ();
var unit = parser.Parse (content, "program.cs");
if (parser.HasErrors)
parser.ErrorPrinter.Errors.ForEach (e => Console.WriteLine (e.Message));
foreach (var error in parser.Errors)
Console.WriteLine (error.Message);
Assert.IsFalse (parser.HasErrors, "File contains parsing errors.");
unit.Freeze ();
var parsedFile = unit.ToTypeSystem ();

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

@ -235,10 +235,12 @@ namespace ICSharpCode.NRefactory.CSharp.CodeCompletion @@ -235,10 +235,12 @@ namespace ICSharpCode.NRefactory.CSharp.CodeCompletion
var resolvedDef = curDef.Resolve(rctx).GetDefinition();
rctx = rctx.WithCurrentTypeDefinition(resolvedDef);
var curMember = resolvedDef.Members.FirstOrDefault(m => m.Region.Begin <= loc && loc < m.BodyRegion.End);
if (curMember != null)
if (curMember != null) {
rctx = rctx.WithCurrentMember(curMember);
}
var engine = new CSharpCompletionEngine (doc, new TestFactory (), pctx, rctx, compilationUnit, parsedFile);
}
var mb = new DefaultCompletionContextProvider(doc, parsedFile);
var engine = new CSharpCompletionEngine (doc, mb, new TestFactory (), pctx, rctx);
engine.EolMarker = Environment.NewLine;
engine.FormattingPolicy = FormattingOptionsFactory.CreateMono ();
@ -263,7 +265,8 @@ namespace ICSharpCode.NRefactory.CSharp.CodeCompletion @@ -263,7 +265,8 @@ namespace ICSharpCode.NRefactory.CSharp.CodeCompletion
pctx = pctx.UpdateProjectContent(null, parsedFile);
var cmp = pctx.CreateCompilation();
var engine = new CSharpCompletionEngine (doc, new TestFactory (), pctx, new CSharpTypeResolveContext (cmp.MainAssembly), compilationUnit, parsedFile);
var mb = new DefaultCompletionContextProvider(doc, parsedFile);
var engine = new CSharpCompletionEngine (doc, mb, new TestFactory (), pctx, new CSharpTypeResolveContext (cmp.MainAssembly));
engine.EolMarker = Environment.NewLine;
engine.FormattingPolicy = FormattingOptionsFactory.CreateMono ();
return Tuple.Create (doc, engine);

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

@ -260,9 +260,9 @@ namespace ICSharpCode.NRefactory.CSharp.CodeCompletion @@ -260,9 +260,9 @@ namespace ICSharpCode.NRefactory.CSharp.CodeCompletion
string editorText;
int cursorPosition = text.IndexOf('$');
int endPos = text.IndexOf('$', cursorPosition + 1);
if (endPos == -1)
if (endPos == -1) {
parsedText = editorText = text.Substring(0, cursorPosition) + text.Substring(cursorPosition + 1);
else {
} else {
parsedText = text.Substring(0, cursorPosition) + new string(' ', endPos - cursorPosition) + text.Substring(endPos + 1);
editorText = text.Substring(0, cursorPosition) + text.Substring(cursorPosition + 1, endPos - cursorPosition - 1) + text.Substring(endPos + 1);
cursorPosition = endPos - 1;
@ -287,10 +287,12 @@ namespace ICSharpCode.NRefactory.CSharp.CodeCompletion @@ -287,10 +287,12 @@ namespace ICSharpCode.NRefactory.CSharp.CodeCompletion
if (curDef != null) {
rctx = rctx.WithCurrentTypeDefinition(curDef.Resolve(rctx).GetDefinition());
var curMember = parsedFile.GetMember(loc);
if (curMember != null)
if (curMember != null) {
rctx = rctx.WithCurrentMember(curMember.CreateResolved(rctx));
}
var engine = new CSharpParameterCompletionEngine (doc, new TestFactory (pctx), pctx, rctx, compilationUnit, parsedFile);
}
var mb = new DefaultCompletionContextProvider(doc, parsedFile);
var engine = new CSharpParameterCompletionEngine (doc, mb, new TestFactory (pctx), pctx, rctx);
return engine.GetParameterDataProvider (cursorPosition, doc.GetCharAt (cursorPosition - 1));
}

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

@ -20,11 +20,11 @@ using System; @@ -20,11 +20,11 @@ using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.CSharp.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using Microsoft.CSharp;
using NUnit.Framework;
@ -45,138 +45,388 @@ namespace ICSharpCode.NRefactory.CSharp @@ -45,138 +45,388 @@ namespace ICSharpCode.NRefactory.CSharp
parsedFile.RootUsingScope.Usings.Add(MakeReference("System.Linq"));
convertVisitor = new CodeDomConvertVisitor();
convertVisitor.AllowSnippetNodes = false;
convertVisitor.UseFullyQualifiedTypeNames = true;
}
string Convert(Expression expr)
#region Helper methods
string ConvertHelper(AstNode node, Action<CSharpCodeProvider, CodeObject, TextWriter, CodeGeneratorOptions> action)
{
CSharpResolver resolver = new CSharpResolver(compilation);
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));
var codeObj = convertVisitor.Convert(node, new CSharpAstResolver(resolver, node));
StringWriter writer = new StringWriter();
writer.NewLine = " ";
new CSharpCodeProvider().GenerateCodeFromExpression(codeExpr, writer, new CodeGeneratorOptions { IndentString = " " });
return Regex.Replace(writer.ToString(), @"\s+", " ");
action(new CSharpCodeProvider(), codeObj, writer, new CodeGeneratorOptions { IndentString = " " });
return Regex.Replace(writer.ToString(), @"\s+", " ").Trim();
}
string ConvertExpression(Expression expr)
{
return ConvertHelper(expr, (p,obj,w,opt) => p.GenerateCodeFromExpression((CodeExpression)obj, w, opt));
}
string ConvertExpression(string code)
{
CSharpParser parser = new CSharpParser();
var expr = parser.ParseExpression(new StringReader(code));
Assert.IsFalse(parser.HasErrors);
return ConvertExpression(expr);
}
string ConvertStatement(Statement statement)
{
return ConvertHelper(statement, (p,obj,w,opt) => p.GenerateCodeFromStatement((CodeStatement)obj, w, opt));
}
string ConvertStatement(string code)
{
CSharpParser parser = new CSharpParser();
var expr = parser.ParseStatements(new StringReader(code)).Single();
Assert.IsFalse(parser.HasErrors);
return ConvertStatement(expr);
}
string ConvertMember(EntityDeclaration entity)
{
return ConvertHelper(entity, (p,obj,w,opt) => p.GenerateCodeFromMember((CodeTypeMember)obj, w, opt));
}
string ConvertMember(string code)
{
CSharpParser parser = new CSharpParser();
var expr = parser.ParseTypeMembers(new StringReader(code)).Single();
Assert.IsFalse(parser.HasErrors);
return ConvertMember(expr);
}
string ConvertTypeDeclaration(EntityDeclaration decl)
{
return ConvertHelper(decl, (p,obj,w,opt) => p.GenerateCodeFromType((CodeTypeDeclaration)obj, w, opt));
}
string ConvertTypeDeclaration(string code)
{
CSharpParser parser = new CSharpParser();
var cu = parser.Parse(new StringReader(code), "program.cs");
Assert.IsFalse(parser.HasErrors);
return ConvertTypeDeclaration((EntityDeclaration)cu.Children.Single());
}
#endregion
#region Type References
[Test]
public void CreateArray()
public void MultidimensionalArrayTypeReference()
{
Assert.AreEqual("new int[10]", Convert(
new ArrayCreateExpression {
Type = new PrimitiveType("int"),
Arguments = { new PrimitiveExpression(10) }
}));
Assert.AreEqual("default(int[,][])", ConvertExpression("default(int[,][])"));
}
[Test]
public void CreateJaggedArray()
public void NestedTypeInGenericType()
{
Assert.AreEqual("new int[10][]", Convert(
new ArrayCreateExpression {
Type = new PrimitiveType("int"),
Arguments = { new PrimitiveExpression(10) },
AdditionalArraySpecifiers = { new ArraySpecifier() }
}));
Assert.AreEqual("default(System.Collections.Generic.List<string>.Enumerator)",
ConvertExpression("default(List<string>.Enumerator)"));
convertVisitor.UseFullyQualifiedTypeNames = false;
Assert.AreEqual("default(List<string>.Enumerator)",
ConvertExpression("default(List<string>.Enumerator)"));
}
#endregion
#region Arrays
[Test]
public void CreateArray()
{
Assert.AreEqual("new int[10]", ConvertExpression("new int[10]"));
}
[Test, ExpectedException(typeof(NotSupportedException))]
public void CreateJaggedArray()
{
ConvertExpression("new int[10][]");
}
[Test, ExpectedException(typeof(NotSupportedException))]
public void Create2DArray()
{
Assert.AreEqual("new int[10, 20]", Convert(
new ArrayCreateExpression {
Type = new PrimitiveType("int"),
Arguments = { new PrimitiveExpression(10), new PrimitiveExpression(20) }
}));
ConvertExpression("new int[10, 20]");
}
[Test]
public void CreateImplicitlyTypedArray()
{
// implicitly-typed array not supported in CodeDom, so the conversion should infer the type
Assert.AreEqual("new int[] { 1, 2, 3}", Convert(
new ArrayCreateExpression {
AdditionalArraySpecifiers = { new ArraySpecifier() },
Initializer = new ArrayInitializerExpression {
Elements = {
new PrimitiveExpression(1),
new PrimitiveExpression(2),
new PrimitiveExpression(3)
}
}
}));
Assert.AreEqual("new int[] { 1, 2, 3}", ConvertExpression("new [] { 1, 2, 3 }"));
Assert.AreEqual("new System.Collections.Generic.List<string>[] { new System.Collections.Generic.List<string>()}",
ConvertExpression("new [] { new List<string>() }"));
}
[Test]
[Test, ExpectedException(typeof(NotSupportedException))]
public void Create2DImplicitlyTypedArray()
{
Assert.AreEqual("new int[,] { { 1, 2 }, { 3, 4 }}", Convert(
new ArrayCreateExpression {
AdditionalArraySpecifiers = { new ArraySpecifier(2) },
Initializer = new ArrayInitializerExpression {
Elements = {
new ArrayInitializerExpression(new PrimitiveExpression(1), new PrimitiveExpression(2)),
new ArrayInitializerExpression(new PrimitiveExpression(3), new PrimitiveExpression(4))
}
}
}));
ConvertExpression("new [,] { { 1, 2 }, { 3, 4 }}");
}
#endregion
#region Operators
[Test]
public void AdditionOperator()
public void ArithmeticOperators()
{
Assert.AreEqual("(0 + 1)", Convert(
new BinaryOperatorExpression(new PrimitiveExpression(0), BinaryOperatorType.Add, new PrimitiveExpression(1))));
Assert.AreEqual("(0 + 1)", ConvertExpression("0 + 1"));
Assert.AreEqual("(0 - 1)", ConvertExpression("0 - 1"));
Assert.AreEqual("(0 * 1)", ConvertExpression("0 * 1"));
Assert.AreEqual("(0 / 1)", ConvertExpression("0 / 1"));
Assert.AreEqual("(0 % 1)", ConvertExpression("0 % 1"));
Assert.AreEqual("(0 & 1)", ConvertExpression("0 & 1"));
Assert.AreEqual("(0 | 1)", ConvertExpression("0 | 1"));
Assert.AreEqual("(0 < 1)", ConvertExpression("0 < 1"));
Assert.AreEqual("(0 > 1)", ConvertExpression("0 > 1"));
Assert.AreEqual("(0 <= 1)", ConvertExpression("0 <= 1"));
Assert.AreEqual("(0 >= 1)", ConvertExpression("0 >= 1"));
Assert.AreEqual("(true && false)", ConvertExpression("true && false"));
Assert.AreEqual("(true || false)", ConvertExpression("true || false"));
}
[Test]
public void EqualityOperator()
{
Assert.AreEqual("(0 == 1)", Convert(
new BinaryOperatorExpression(new PrimitiveExpression(0), BinaryOperatorType.Equality, new PrimitiveExpression(1))));
Assert.AreEqual("(0 == 1)", ConvertExpression("0 == 1"));
Assert.AreEqual("(default(object) == null)", ConvertExpression("default(object) == null"));
}
[Test]
public void InEqualityOperator()
{
Assert.AreEqual("((0 == 1) == false)", Convert(
new BinaryOperatorExpression(new PrimitiveExpression(0), BinaryOperatorType.InEquality, new PrimitiveExpression(1))));
Assert.AreEqual("((0 == 1) == false)", ConvertExpression("0 != 1"));
Assert.AreEqual("(default(object) != null)", ConvertExpression("default(object) != null"));
}
[Test]
public void ReferenceInEqualityOperator()
public void UnaryOperators()
{
Assert.AreEqual("(default(object) != null)", Convert(
new BinaryOperatorExpression(new DefaultValueExpression(new PrimitiveType("object")), BinaryOperatorType.InEquality, new NullReferenceExpression())));
Assert.AreEqual("(a == false)", ConvertExpression("!a"));
Assert.AreEqual("(0 - a)", ConvertExpression("-a"));
Assert.AreEqual("a", ConvertExpression("+a"));
}
[Test]
public void Cast()
{
Assert.AreEqual("((double)(0))", ConvertExpression("(double)0"));
}
#endregion
#region Member Access
[Test]
public void StaticProperty()
{
Assert.AreEqual("System.Environment.TickCount", Convert(
new IdentifierExpression("Environment").Member("TickCount")));
Assert.AreEqual("System.Environment.TickCount", ConvertExpression("Environment.TickCount"));
}
[Test]
public void InstanceMethodInvocation()
{
Assert.AreEqual("this.Equals(null)",
Convert(new IdentifierExpression("Equals").Invoke(new NullReferenceExpression())));
Assert.AreEqual("this.Equals(null)", ConvertExpression("Equals(null)"));
}
[Test]
public void StaticMethodInvocation()
{
Assert.AreEqual("object.Equals(null, null)",
Convert(new IdentifierExpression("Equals").Invoke(new NullReferenceExpression(), new NullReferenceExpression())));
Assert.AreEqual("object.Equals(null, null)", ConvertExpression("Equals(null, null)"));
}
[Test]
public void BaseMemberAccess()
{
Assert.AreEqual("base.X", ConvertExpression("base.X"));
Assert.AreEqual("base[i]", ConvertExpression("base[i]"));
}
[Test]
public void GenericMethodReference()
{
Assert.AreEqual("this.Stuff<string>", ConvertExpression("this.Stuff<string>"));
Assert.AreEqual("this.Stuff<string>", ConvertExpression("Stuff<string>"));
}
[Test]
public void ByReferenceCall()
{
Assert.AreEqual("a.Call(ref x, out y, z)", ConvertExpression("a.Call(ref x, out y, z)"));
}
[Test]
public void MemberAccessOnType()
{
Assert.AreEqual("string.Empty", ConvertExpression("string.Empty"));
}
#endregion
#region Statements
[Test]
public void MethodInvocationStatement()
{
Assert.AreEqual("a.SomeMethod();", ConvertStatement("a.SomeMethod();"));
}
[Test]
public void Assignment()
{
Assert.AreEqual("a = 1;", ConvertStatement("a = 1;"));
}
[Test, ExpectedException(typeof(NotSupportedException))]
public void AssignmentNotSupportedInExpression()
{
ConvertStatement("a = b = 1;");
}
[Test]
public void BlockStatement()
{
Assert.AreEqual("if (true) { a = 1; b = 2; }",
ConvertStatement("{ a = 1; b = 2; }"));
}
[Test]
public void CompoundAssign()
{
Assert.AreEqual("a = (a + 1);", ConvertStatement("a += 1;"));
Assert.AreEqual("a = (a - 1);", ConvertStatement("a -= 1;"));
Assert.AreEqual("a = (a * 1);", ConvertStatement("a *= 1;"));
Assert.AreEqual("a = (a / 1);", ConvertStatement("a /= 1;"));
Assert.AreEqual("a = (a % 1);", ConvertStatement("a %= 1;"));
Assert.AreEqual("a = (a & 1);", ConvertStatement("a &= 1;"));
Assert.AreEqual("a = (a | 1);", ConvertStatement("a |= 1;"));
}
[Test]
public void Increment()
{
Assert.AreEqual("a = (a + 1);", ConvertStatement("a++;"));
Assert.AreEqual("a = (a + 1);", ConvertStatement("++a;"));
Assert.AreEqual("a = (a - 1);", ConvertStatement("a--;"));
Assert.AreEqual("a = (a - 1);", ConvertStatement("--a;"));
}
[Test]
public void ForLoop()
{
Assert.AreEqual("for (int i = 0; (i < 10); i = (i + 1)) { }",
ConvertStatement("for (int i = 0; i < 10; i++) {}"));
}
[Test]
public void WhileLoop()
{
Assert.AreEqual("for (new object(); (i < 10); new object()) { }",
ConvertStatement("while (i < 10);"));
}
[Test]
public void VariableDeclarationWithArrayInitializer()
{
Assert.AreEqual("int[] nums = new int[] { 1, 2};",
ConvertStatement("int[] nums = { 1, 2 };"));
}
[Test]
public void TryCatch()
{
Assert.AreEqual("try { a = 1; } catch (System.Exception ex) { ex.ToString(); }",
ConvertStatement("try { a = 1; } catch (Exception ex) { ex.ToString(); }"));
}
[Test]
public void TryEmptyCatch()
{
Assert.AreEqual("try { a = 1; } catch (System.Exception ) { }",
ConvertStatement("try { a = 1; } catch (Exception) { }"));
}
[Test]
public void TryFinally()
{
Assert.AreEqual("try { a = 1; } finally { a = 0; }",
ConvertStatement("try { a = 1; } finally { a = 0; }"));
}
#endregion
#region Type Members
[Test]
public void MethodParameterNamedValue()
{
Assert.AreEqual("void M(string value) { System.Console.WriteLine(value); }",
ConvertMember("void M(string value) { Console.WriteLine(value); }"));
}
[Test]
public void ValueInProperty()
{
Assert.AreEqual("string P { set { System.Console.WriteLine(value); } }",
ConvertMember("string P { set { Console.WriteLine(value); } }"));
}
[Test]
public void MethodWithAttribute()
{
Assert.AreEqual("[Test()] void MethodWithAttribute() { }",
ConvertMember("[Test] void MethodWithAttribute() { }"));
}
[Test]
public void PublicNonVirtualMethod()
{
Assert.AreEqual("public void Method() { }",
ConvertMember("public void Method() { }"));
}
[Test]
public void PublicVirtualMethod()
{
Assert.AreEqual("public virtual void Method() { }",
ConvertMember("public virtual void Method() { }"));
}
[Test]
public void NestedClass()
{
Assert.AreEqual("public class Outer { public class Inner { } }",
ConvertTypeDeclaration("class Outer { class Inner { } }"));
}
[Test]
public void Constructor()
{
string code = "public class Test : Base { public Test(string x) : base(x) { } }";
Assert.AreEqual(code, ConvertTypeDeclaration(code));
}
[Test]
public void Enum()
{
string code = "public enum E { [Description(\"Text\")] None, B = 2, }";
Assert.AreEqual(code, ConvertTypeDeclaration(code));
}
[Test]
public void Field()
{
Assert.AreEqual("public class X {" +
" int A;" +
" int B; }",
ConvertMember("public class X { int A, B; }"));
}
[Test]
public void NotOperator()
public void Event()
{
Assert.AreEqual("(a == false)", Convert(new UnaryOperatorExpression(UnaryOperatorType.Not, new IdentifierExpression("a"))));
Assert.AreEqual("public class X {" +
" protected event System.EventHandler A;" +
" protected event System.EventHandler B; }",
ConvertMember("public class X { protected event EventHandler A, B; }"));
}
#endregion
}
}

106
ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/InconsistentNamingTests.cs

@ -57,24 +57,24 @@ namespace ICSharpCode.NRefactory.CSharp.CodeIssues @@ -57,24 +57,24 @@ namespace ICSharpCode.NRefactory.CSharp.CodeIssues
[Test]
public void TestClassName ()
{
var input = @"class anIssue {}";
var output = @"class AnIssue {}";
var input = @"public class anIssue {}";
var output = @"public class AnIssue {}";
CheckNaming (input, output);
}
[Test]
public void TestAttributeName ()
{
var input = @"class test : System.Attribute {}";
var output = @"class TestAttribute : System.Attribute {}";
var input = @"public class test : System.Attribute {}";
var output = @"public class TestAttribute : System.Attribute {}";
CheckNaming (input, output);
}
[Test]
public void TestEventArgsName ()
{
var input = @"class test : System.EventArgs {}";
var output = @"class TestEventArgs : System.EventArgs {}";
var input = @"public class test : System.EventArgs {}";
var output = @"public class TestEventArgs : System.EventArgs {}";
CheckNaming (input, output);
}
@ -89,50 +89,50 @@ namespace ICSharpCode.NRefactory.CSharp.CodeIssues @@ -89,50 +89,50 @@ namespace ICSharpCode.NRefactory.CSharp.CodeIssues
[Test]
public void TestStructName ()
{
var input = @"struct anIssue {}";
var output = @"struct AnIssue {}";
var input = @"public struct anIssue {}";
var output = @"public struct AnIssue {}";
CheckNaming (input, output);
}
[Test]
public void TestInterfaceName ()
{
var input = @"interface anIssue {}";
var output = @"interface IAnIssue {}";
var input = @"public interface anIssue {}";
var output = @"public interface IAnIssue {}";
CheckNaming (input, output);
}
[Test]
public void TestEnumName ()
{
var input = @"enum anIssue {}";
var output = @"enum AnIssue {}";
var input = @"public enum anIssue {}";
var output = @"public enum AnIssue {}";
CheckNaming (input, output);
}
[Test]
public void TestDelegateName ()
{
var input = @"delegate void anIssue ();";
var output = @"delegate void AnIssue ();";
var input = @"public delegate void anIssue ();";
var output = @"public delegate void AnIssue ();";
CheckNaming (input, output);
}
[Test]
public void TestPrivateFieldName ()
{
var input = @"class AClass { int Field; }";
var output = @"class AClass { int field; }";
CheckNaming (input, output);
}
// [Test]
// public void TestPrivateFieldName ()
// {
// var input = @"class AClass { int Field; }";
// var output = @"class AClass { int field; }";
// CheckNaming (input, output);
// }
[Test]
public void TestUnderscoreFieldName ()
{
var input = @"class AClass { int _Field; }";
var output = @"class AClass { int _field; }";
CheckNaming (input, output);
}
// [Test]
// public void TestUnderscoreFieldName ()
// {
// var input = @"class AClass { int _Field; }";
// var output = @"class AClass { int _field; }";
// CheckNaming (input, output);
// }
[Test]
public void TestPublicFieldName ()
@ -142,13 +142,13 @@ namespace ICSharpCode.NRefactory.CSharp.CodeIssues @@ -142,13 +142,13 @@ namespace ICSharpCode.NRefactory.CSharp.CodeIssues
CheckNaming (input, output);
}
[Test]
public void TestPrivateConstantFieldName ()
{
var input = @"class AClass { const int field = 5; }";
var output = @"class AClass { const int Field = 5; }";
CheckNaming (input, output);
}
// [Test]
// public void TestPrivateConstantFieldName ()
// {
// var input = @"class AClass { const int field = 5; }";
// var output = @"class AClass { const int Field = 5; }";
// CheckNaming (input, output);
// }
[Test]
public void TestPublicReadOnlyFieldName ()
@ -174,13 +174,13 @@ namespace ICSharpCode.NRefactory.CSharp.CodeIssues @@ -174,13 +174,13 @@ namespace ICSharpCode.NRefactory.CSharp.CodeIssues
CheckNaming (input, output, true);
}
[Test]
public void TestPrivateStaticFieldName ()
{
var input = @"class AClass { static int Field; }";
var output = @"class AClass { static int field; }";
CheckNaming (input, output);
}
// [Test]
// public void TestPrivateStaticFieldName ()
// {
// var input = @"class AClass { static int Field; }";
// var output = @"class AClass { static int field; }";
// CheckNaming (input, output);
// }
[Test]
public void TestPublicStaticReadOnlyFieldName ()
@ -190,13 +190,13 @@ namespace ICSharpCode.NRefactory.CSharp.CodeIssues @@ -190,13 +190,13 @@ namespace ICSharpCode.NRefactory.CSharp.CodeIssues
CheckNaming (input, output);
}
[Test]
public void TestPrivateReadOnlyFieldName ()
{
var input = @"class AClass { readonly int Field; }";
var output = @"class AClass { readonly int field; }";
CheckNaming (input, output);
}
// [Test]
// public void TestPrivateReadOnlyFieldName ()
// {
// var input = @"class AClass { readonly int Field; }";
// var output = @"class AClass { readonly int field; }";
// CheckNaming (input, output);
// }
[Test]
public void TestPublicConstantFieldName ()
@ -209,16 +209,16 @@ namespace ICSharpCode.NRefactory.CSharp.CodeIssues @@ -209,16 +209,16 @@ namespace ICSharpCode.NRefactory.CSharp.CodeIssues
[Test]
public void TestMethodName ()
{
var input = @"class AClass { int method () {} }";
var output = @"class AClass { int Method () {} }";
var input = @"class AClass { public int method () {} }";
var output = @"class AClass { public int Method () {} }";
CheckNaming (input, output);
}
[Test]
public void TestPropertyName ()
{
var input = @"class AClass { int property { get; set; } }";
var output = @"class AClass { int Property { get; set; } }";
var input = @"class AClass { public int property { get; set; } }";
var output = @"class AClass { public int Property { get; set; } }";
CheckNaming (input, output);
}

20
ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseUtil.cs

@ -35,8 +35,8 @@ namespace ICSharpCode.NRefactory.CSharp.Parser @@ -35,8 +35,8 @@ namespace ICSharpCode.NRefactory.CSharp.Parser
CSharpParser parser = new CSharpParser();
CompilationUnit cu = parser.Parse(new StringReader(code), "parsed.cs");
if (parser.HasErrors)
parser.ErrorPrinter.Errors.ForEach (err => Console.WriteLine (err.Message));
foreach (var error in parser.Errors)
Console.WriteLine (error.Message);
Assert.AreEqual(expectErrors, parser.HasErrors, "HasErrors");
AstNode node = cu.Children.Single();
@ -58,8 +58,8 @@ namespace ICSharpCode.NRefactory.CSharp.Parser @@ -58,8 +58,8 @@ namespace ICSharpCode.NRefactory.CSharp.Parser
CSharpParser parser = new CSharpParser();
var statements = parser.ParseStatements(new StringReader(stmt));
if (parser.HasErrors)
parser.ErrorPrinter.Errors.ForEach (err => Console.WriteLine (err.Message));
foreach (var error in parser.Errors)
Console.WriteLine (error.Message);
Assert.AreEqual(expectErrors, parser.HasErrors, "HasErrors");
AstNode statement = statements.Single();
@ -81,8 +81,8 @@ namespace ICSharpCode.NRefactory.CSharp.Parser @@ -81,8 +81,8 @@ namespace ICSharpCode.NRefactory.CSharp.Parser
CSharpParser parser = new CSharpParser();
AstNode parsedExpression = parser.ParseExpression(new StringReader(expr));
if (parser.HasErrors)
parser.ErrorPrinter.Errors.ForEach (err => Console.WriteLine (err.Message));
foreach (var error in parser.Errors)
Console.WriteLine (error.Message);
Assert.AreEqual(expectErrors, parser.HasErrors, "HasErrors");
if (expectErrors && parsedExpression == null)
return default (T);
@ -103,8 +103,8 @@ namespace ICSharpCode.NRefactory.CSharp.Parser @@ -103,8 +103,8 @@ namespace ICSharpCode.NRefactory.CSharp.Parser
{
CSharpParser parser = new CSharpParser();
var members = parser.ParseTypeMembers(new StringReader(expr));
if (parser.HasErrors)
parser.ErrorPrinter.Errors.ForEach (err => Console.WriteLine (err.Message));
foreach (var error in parser.Errors)
Console.WriteLine (error.Message);
Assert.AreEqual(expectErrors, parser.HasErrors, "HasErrors");
EntityDeclaration m = members.Single();
Type type = typeof(T);
@ -125,8 +125,8 @@ namespace ICSharpCode.NRefactory.CSharp.Parser @@ -125,8 +125,8 @@ namespace ICSharpCode.NRefactory.CSharp.Parser
CSharpParser parser = new CSharpParser();
var parsedExpression = parser.ParseDocumentationReference(cref);
if (parser.HasErrors)
parser.ErrorPrinter.Errors.ForEach (err => Console.WriteLine (err.Message));
foreach (var error in parser.Errors)
Console.WriteLine (error.Message);
Assert.AreEqual(expectErrors, parser.HasErrors, "HasErrors");
if (expectErrors && parsedExpression == null)
return null;

34
ICSharpCode.NRefactory.Tests/FormattingTests/TestWrapping.cs

@ -580,5 +580,39 @@ namespace ICSharpCode.NRefactory.CSharp.FormattingTests @@ -580,5 +580,39 @@ namespace ICSharpCode.NRefactory.CSharp.FormattingTests
}");
}
[Test()]
public void TestNoBlankLinesBetweenEndBraceAndEndParenthesis ()
{
CSharpFormattingOptions policy = FormattingOptionsFactory.CreateMono ();
policy.BlankLinesBetweenMembers = 1;
var adapter = Test (policy, @"class Test
{
int Foo (int i, double d, Action a)
{
a ();
}
void Bar ()
{
Foo (1, 2, () => {
});
}
}",
@"class Test
{
int Foo (int i, double d, Action a)
{
a ();
}
void Bar ()
{
Foo (1, 2, () => {
});
}
}", FormattingMode.Intrusive);
}
}
}

3
ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<PropertyGroup>
<ProjectGuid>{63D3B27A-D966-4902-90B3-30290E1692F1}</ProjectGuid>
@ -277,6 +277,7 @@ @@ -277,6 +277,7 @@
<Compile Include="CSharp\CodeActions\StaticMethodInvocationToExtensionMethodInvocationTests.cs" />
<Compile Include="CSharp\CodeActions\ExtensionMethodInvocationToStaticMethodInvocationTests.cs" />
<Compile Include="CSharp\CodeActions\IterateViaForeachTests.cs" />
<Compile Include="CSharp\CodeActions\ExtractFieldTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Mono.Cecil\Mono.Cecil.csproj">

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

@ -145,7 +145,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -145,7 +145,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
Assert.AreEqual(0, c.GetProperties().Count());
Assert.AreEqual(0, c.GetEvents().Count());
Assert.AreEqual(0, c.GetFields().Count());
Assert.AreEqual(3, c.Attributes.Count);
}
[Test]

2
ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.TestCase.cs

@ -72,6 +72,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.TestCase @@ -72,6 +72,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.TestCase
public NestedEnum EnumField;
public A Property { get; set; }
public enum NestedEnum {
EnumMember
}

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

@ -351,6 +351,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -351,6 +351,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
Assert.AreEqual(Accessibility.Public, p.Getter.Accessibility);
Assert.AreEqual(new[] { "index" }, p.Getter.Parameters.Select(x => x.Name).ToArray());
Assert.AreEqual("System.String", p.Getter.ReturnType.ReflectionName);
Assert.AreEqual(p, p.Getter.AccessorOwner);
}
[Test]
@ -365,6 +366,16 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -365,6 +366,16 @@ namespace ICSharpCode.NRefactory.TypeSystem
Assert.AreEqual(TypeKind.Void, p.Setter.ReturnType.Kind);
}
[Test]
public void GenericPropertyGetter()
{
var type = compilation.FindType(typeof(GenericClass<string, object>));
var prop = type.GetProperties(p => p.Name == "Property").Single();
Assert.AreEqual("System.String", prop.Getter.ReturnType.ReflectionName);
Assert.IsTrue(prop.Getter.IsAccessor);
Assert.AreEqual(prop, prop.Getter.AccessorOwner);
}
[Test]
public void EnumTest()
{

11
ICSharpCode.NRefactory/Documentation/XmlDocumentationProvider.cs

@ -121,7 +121,7 @@ namespace ICSharpCode.NRefactory.Documentation @@ -121,7 +121,7 @@ namespace ICSharpCode.NRefactory.Documentation
this.fileName = fileName;
ReadXmlDoc(xmlReader);
} else {
string redirectionTarget = GetRedirectionTarget(xmlReader.GetAttribute("redirect"));
string redirectionTarget = GetRedirectionTarget(fileName, xmlReader.GetAttribute("redirect"));
if (redirectionTarget != null) {
Debug.WriteLine("XmlDoc " + fileName + " is redirecting to " + redirectionTarget);
using (FileStream redirectedFs = new FileStream(redirectionTarget, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete)) {
@ -138,7 +138,7 @@ namespace ICSharpCode.NRefactory.Documentation @@ -138,7 +138,7 @@ namespace ICSharpCode.NRefactory.Documentation
}
}
static string GetRedirectionTarget(string target)
static string GetRedirectionTarget(string xmlFileName, string target)
{
string programFilesDir = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86);
programFilesDir = AppendDirectorySeparator(programFilesDir);
@ -146,8 +146,11 @@ namespace ICSharpCode.NRefactory.Documentation @@ -146,8 +146,11 @@ namespace ICSharpCode.NRefactory.Documentation
string corSysDir = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory();
corSysDir = AppendDirectorySeparator(corSysDir);
return LookupLocalizedXmlDoc(target.Replace("%PROGRAMFILESDIR%", programFilesDir)
.Replace("%CORSYSDIR%", corSysDir));
var fileName = target.Replace ("%PROGRAMFILESDIR%", programFilesDir)
.Replace ("%CORSYSDIR%", corSysDir);
if (!Path.IsPathRooted (fileName))
fileName = Path.Combine (Path.GetDirectoryName (xmlFileName), fileName);
return LookupLocalizedXmlDoc(fileName);
}
static string AppendDirectorySeparator(string dir)

32
ICSharpCode.NRefactory/Editor/IDocument.cs

@ -109,6 +109,18 @@ namespace ICSharpCode.NRefactory.Editor @@ -109,6 +109,18 @@ namespace ICSharpCode.NRefactory.Editor
/// </remarks>
void Insert(int offset, string text);
/// <summary>
/// Inserts text.
/// </summary>
/// <param name="offset">The offset at which the text is inserted.</param>
/// <param name="text">The new text.</param>
/// <remarks>
/// Anchors positioned exactly at the insertion offset will move according to their movement type.
/// For AnchorMovementType.Default, they will move behind the inserted text.
/// The caret will also move behind the inserted text.
/// </remarks>
void Insert(int offset, ITextSource text);
/// <summary>
/// Inserts text.
/// </summary>
@ -121,6 +133,18 @@ namespace ICSharpCode.NRefactory.Editor @@ -121,6 +133,18 @@ namespace ICSharpCode.NRefactory.Editor
/// </param>
void Insert(int offset, string text, AnchorMovementType defaultAnchorMovementType);
/// <summary>
/// Inserts text.
/// </summary>
/// <param name="offset">The offset at which the text is inserted.</param>
/// <param name="text">The new text.</param>
/// <param name="defaultAnchorMovementType">
/// Anchors positioned exactly at the insertion offset will move according to the anchor's movement type.
/// For AnchorMovementType.Default, they will move according to the movement type specified by this parameter.
/// The caret will also move according to the <paramref name="defaultAnchorMovementType"/> parameter.
/// </param>
void Insert(int offset, ITextSource text, AnchorMovementType defaultAnchorMovementType);
/// <summary>
/// Removes text.
/// </summary>
@ -136,6 +160,14 @@ namespace ICSharpCode.NRefactory.Editor @@ -136,6 +160,14 @@ namespace ICSharpCode.NRefactory.Editor
/// <param name="newText">The new text.</param>
void Replace(int offset, int length, string newText);
/// <summary>
/// Replaces text.
/// </summary>
/// <param name="offset">The starting offset of the text to be replaced.</param>
/// <param name="length">The length of the text to be replaced.</param>
/// <param name="newText">The new text.</param>
void Replace(int offset, int length, ITextSource newText);
/// <summary>
/// Make the document combine the following actions into a single
/// action for undo purposes.

15
ICSharpCode.NRefactory/Editor/ReadOnlyDocument.cs

@ -257,6 +257,21 @@ namespace ICSharpCode.NRefactory.Editor @@ -257,6 +257,21 @@ namespace ICSharpCode.NRefactory.Editor
throw new NotSupportedException();
}
void IDocument.Insert(int offset, ITextSource text)
{
throw new NotImplementedException();
}
void IDocument.Insert(int offset, ITextSource text, AnchorMovementType defaultAnchorMovementType)
{
throw new NotImplementedException();
}
void IDocument.Replace(int offset, int length, ITextSource newText)
{
throw new NotImplementedException();
}
void IDocument.StartUndoableAction()
{
}

28
ICSharpCode.NRefactory/Editor/StringBuilderDocument.cs

@ -104,17 +104,35 @@ namespace ICSharpCode.NRefactory.Editor @@ -104,17 +104,35 @@ namespace ICSharpCode.NRefactory.Editor
Replace(offset, 0, text);
}
/// <inheritdoc/>
public void Insert(int offset, ITextSource text)
{
if (text == null)
throw new ArgumentNullException("text");
Replace(offset, 0, text.Text);
}
/// <inheritdoc/>
public void Insert(int offset, string text, AnchorMovementType defaultAnchorMovementType)
{
if (offset < 0 || offset > this.TextLength)
throw new ArgumentOutOfRangeException("offset");
if (text == null)
throw new ArgumentNullException("text");
if (defaultAnchorMovementType == AnchorMovementType.BeforeInsertion)
PerformChange(new InsertionWithMovementBefore(offset, text));
else
Replace(offset, 0, text);
}
/// <inheritdoc/>
public void Insert(int offset, ITextSource text, AnchorMovementType defaultAnchorMovementType)
{
if (text == null)
throw new ArgumentNullException("text");
Insert(offset, text.Text, defaultAnchorMovementType);
}
[Serializable]
sealed class InsertionWithMovementBefore : TextChangeEventArgs
{
@ -149,6 +167,14 @@ namespace ICSharpCode.NRefactory.Editor @@ -149,6 +167,14 @@ namespace ICSharpCode.NRefactory.Editor
PerformChange(new TextChangeEventArgs(offset, b.ToString(offset, length), newText));
}
/// <inheritdoc/>
public void Replace(int offset, int length, ITextSource newText)
{
if (newText == null)
throw new ArgumentNullException("newText");
Replace(offset, length, newText.Text);
}
bool isInChange;
void PerformChange(TextChangeEventArgs change)
@ -166,7 +192,7 @@ namespace ICSharpCode.NRefactory.Editor @@ -166,7 +192,7 @@ namespace ICSharpCode.NRefactory.Editor
documentSnapshot = null;
cachedText = null;
b.Remove(change.Offset, change.RemovalLength);
b.Insert(change.Offset, change.InsertedText);
b.Insert(change.Offset, change.InsertedText.Text);
versionProvider.AppendChange(change);
// Update anchors and fire Deleted events

7
ICSharpCode.NRefactory/Editor/StringTextSource.cs

@ -27,6 +27,11 @@ namespace ICSharpCode.NRefactory.Editor @@ -27,6 +27,11 @@ namespace ICSharpCode.NRefactory.Editor
[Serializable]
public class StringTextSource : ITextSource
{
/// <summary>
/// Gets a text source containing the empty string.
/// </summary>
public static readonly StringTextSource Empty = new StringTextSource(string.Empty);
readonly string text;
readonly ITextSourceVersion version;
@ -69,7 +74,7 @@ namespace ICSharpCode.NRefactory.Editor @@ -69,7 +74,7 @@ namespace ICSharpCode.NRefactory.Editor
/// <inheritdoc/>
public ITextSource CreateSnapshot()
{
return this; // StringTextBuffer is immutable
return this; // StringTextSource is immutable
}
/// <inheritdoc/>

30
ICSharpCode.NRefactory/Editor/TextChangeEventArgs.cs

@ -28,8 +28,8 @@ namespace ICSharpCode.NRefactory.Editor @@ -28,8 +28,8 @@ namespace ICSharpCode.NRefactory.Editor
public class TextChangeEventArgs : EventArgs
{
readonly int offset;
readonly string removedText;
readonly string insertedText;
readonly ITextSource removedText;
readonly ITextSource insertedText;
/// <summary>
/// The offset at which the change occurs.
@ -41,7 +41,7 @@ namespace ICSharpCode.NRefactory.Editor @@ -41,7 +41,7 @@ namespace ICSharpCode.NRefactory.Editor
/// <summary>
/// The text that was removed.
/// </summary>
public string RemovedText {
public ITextSource RemovedText {
get { return removedText; }
}
@ -49,13 +49,13 @@ namespace ICSharpCode.NRefactory.Editor @@ -49,13 +49,13 @@ namespace ICSharpCode.NRefactory.Editor
/// The number of characters removed.
/// </summary>
public int RemovalLength {
get { return removedText.Length; }
get { return removedText.TextLength; }
}
/// <summary>
/// The text that was inserted.
/// </summary>
public string InsertedText {
public ITextSource InsertedText {
get { return insertedText; }
}
@ -63,7 +63,7 @@ namespace ICSharpCode.NRefactory.Editor @@ -63,7 +63,7 @@ namespace ICSharpCode.NRefactory.Editor
/// The number of characters inserted.
/// </summary>
public int InsertionLength {
get { return insertedText.Length; }
get { return insertedText.TextLength; }
}
/// <summary>
@ -71,9 +71,23 @@ namespace ICSharpCode.NRefactory.Editor @@ -71,9 +71,23 @@ namespace ICSharpCode.NRefactory.Editor
/// </summary>
public TextChangeEventArgs(int offset, string removedText, string insertedText)
{
if (offset < 0)
throw new ArgumentOutOfRangeException("offset", offset, "offset must not be negative");
this.offset = offset;
this.removedText = removedText ?? string.Empty;
this.insertedText = insertedText ?? string.Empty;
this.removedText = removedText != null ? new StringTextSource(removedText) : StringTextSource.Empty;
this.insertedText = insertedText != null ? new StringTextSource(insertedText) : StringTextSource.Empty;
}
/// <summary>
/// Creates a new TextChangeEventArgs object.
/// </summary>
public TextChangeEventArgs(int offset, ITextSource removedText, ITextSource insertedText)
{
if (offset < 0)
throw new ArgumentOutOfRangeException("offset", offset, "offset must not be negative");
this.offset = offset;
this.removedText = removedText ?? StringTextSource.Empty;
this.insertedText = insertedText ?? StringTextSource.Empty;
}
/// <summary>

11
ICSharpCode.NRefactory/Semantics/ConversionResolveResult.cs

@ -27,6 +27,11 @@ namespace ICSharpCode.NRefactory.Semantics @@ -27,6 +27,11 @@ namespace ICSharpCode.NRefactory.Semantics
public readonly ResolveResult Input;
public readonly Conversion Conversion;
/// <summary>
/// For numeric conversions, specifies whether overflow checking is enabled.
/// </summary>
public readonly bool CheckForOverflow;
public ConversionResolveResult(IType targetType, ResolveResult input, Conversion conversion)
: base(targetType)
{
@ -38,6 +43,12 @@ namespace ICSharpCode.NRefactory.Semantics @@ -38,6 +43,12 @@ namespace ICSharpCode.NRefactory.Semantics
this.Conversion = conversion;
}
public ConversionResolveResult(IType targetType, ResolveResult input, Conversion conversion, bool checkForOverflow)
: this(targetType, input, conversion)
{
this.CheckForOverflow = checkForOverflow;
}
public override bool IsError {
get { return !Conversion.IsValid; }
}

10
ICSharpCode.NRefactory/Semantics/ErrorResolveResult.cs

@ -35,8 +35,18 @@ namespace ICSharpCode.NRefactory.Semantics @@ -35,8 +35,18 @@ namespace ICSharpCode.NRefactory.Semantics
{
}
public ErrorResolveResult(IType type, string message, TextLocation location) : base(type)
{
this.Message = message;
this.Location = location;
}
public override bool IsError {
get { return true; }
}
public string Message { get; private set; }
public TextLocation Location { get; private set; }
}
}

16
ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs

@ -1646,11 +1646,17 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1646,11 +1646,17 @@ namespace ICSharpCode.NRefactory.TypeSystem
#region Read Method
[CLSCompliant(false)]
public IUnresolvedMethod ReadMethod(MethodDefinition method, IUnresolvedTypeDefinition parentType, EntityType methodType = EntityType.Method)
{
return ReadMethod(method, parentType, null, methodType);
}
IUnresolvedMethod ReadMethod(MethodDefinition method, IUnresolvedTypeDefinition parentType, IUnresolvedMember accessorOwner, EntityType methodType = EntityType.Method)
{
if (method == null)
return null;
DefaultUnresolvedMethod m = new DefaultUnresolvedMethod(parentType, method.Name);
m.EntityType = methodType;
m.AccessorOwner = accessorOwner;
if (method.HasGenericParameters) {
for (int i = 0; i < method.GenericParameters.Count; i++) {
if (method.GenericParameters[i].Position != i)
@ -1876,8 +1882,8 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1876,8 +1882,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
TranslateModifiers(property.GetMethod ?? property.SetMethod, p);
p.ReturnType = ReadTypeReference(property.PropertyType, typeAttributes: property);
p.Getter = ReadMethod(property.GetMethod, parentType);
p.Setter = ReadMethod(property.SetMethod, parentType);
p.Getter = ReadMethod(property.GetMethod, parentType, p);
p.Setter = ReadMethod(property.SetMethod, parentType, p);
if (property.HasParameters) {
foreach (ParameterDefinition par in property.Parameters) {
@ -1904,9 +1910,9 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1904,9 +1910,9 @@ namespace ICSharpCode.NRefactory.TypeSystem
TranslateModifiers(ev.AddMethod, e);
e.ReturnType = ReadTypeReference(ev.EventType, typeAttributes: ev);
e.AddAccessor = ReadMethod(ev.AddMethod, parentType);
e.RemoveAccessor = ReadMethod(ev.RemoveMethod, parentType);
e.InvokeAccessor = ReadMethod(ev.InvokeMethod, parentType);
e.AddAccessor = ReadMethod(ev.AddMethod, parentType, e);
e.RemoveAccessor = ReadMethod(ev.RemoveMethod, parentType, e);
e.InvokeAccessor = ReadMethod(ev.InvokeMethod, parentType, e);
AddAttributes(ev, e);

17
ICSharpCode.NRefactory/TypeSystem/IMethod.cs

@ -39,6 +39,12 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -39,6 +39,12 @@ namespace ICSharpCode.NRefactory.TypeSystem
bool IsPartialMethodDeclaration { get; }
bool IsPartialMethodImplementation { get; }
/// <summary>
/// If this method is an accessor, returns a reference to the corresponding property/event.
/// Otherwise, returns null.
/// </summary>
IUnresolvedMember AccessorOwner { get; }
/// <summary>
/// Resolves the member.
/// </summary>
@ -75,5 +81,16 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -75,5 +81,16 @@ namespace ICSharpCode.NRefactory.TypeSystem
bool IsConstructor { get; }
bool IsDestructor { get; }
bool IsOperator { get; }
/// <summary>
/// Gets whether the method is a property/event accessor.
/// </summary>
bool IsAccessor { get; }
/// <summary>
/// If this method is an accessor, returns the corresponding property/event.
/// Otherwise, returns null.
/// </summary>
IMember AccessorOwner { get; }
}
}

14
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedMethod.cs

@ -191,6 +191,20 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -191,6 +191,20 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
get { return ((IUnresolvedMethod)unresolved).IsOperator; }
}
public bool IsAccessor {
get { return ((IUnresolvedMethod)unresolved).AccessorOwner != null; }
}
public IMember AccessorOwner {
get {
var reference = ((IUnresolvedMethod)unresolved).AccessorOwner;
if (reference != null)
return reference.Resolve(context);
else
return null;
}
}
public override IMemberReference ToMemberReference()
{
var declTypeRef = this.DeclaringType.ToTypeReference();

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

@ -32,6 +32,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -32,6 +32,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
IList<IUnresolvedAttribute> returnTypeAttributes;
IList<IUnresolvedTypeParameter> typeParameters;
IList<IUnresolvedParameter> parameters;
IUnresolvedMember accessorOwner;
protected override void FreezeInternal()
{
@ -125,6 +126,14 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -125,6 +126,14 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
}
}
public IUnresolvedMember AccessorOwner {
get { return accessorOwner; }
set {
ThrowIfFrozen();
accessorOwner = value;
}
}
public override string ToString()
{
StringBuilder b = new StringBuilder("[");
@ -150,6 +159,29 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -150,6 +159,29 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public override IMember Resolve(ITypeResolveContext context)
{
if (accessorOwner != null) {
var owner = accessorOwner.Resolve(context);
if (owner != null) {
IProperty p = owner as IProperty;
if (p != null) {
if (p.CanGet && p.Getter.Name == this.Name)
return p.Getter;
if (p.CanSet && p.Setter.Name == this.Name)
return p.Setter;
}
IEvent e = owner as IEvent;
if (e != null) {
if (e.CanAdd && e.AddAccessor.Name == this.Name)
return e.AddAccessor;
if (e.CanRemove && e.RemoveAccessor.Name == this.Name)
return e.RemoveAccessor;
if (e.CanInvoke && e.InvokeAccessor.Name == this.Name)
return e.InvokeAccessor;
}
}
return null;
}
ITypeReference interfaceTypeReference = null;
if (this.IsExplicitInterfaceImplementation && this.ExplicitInterfaceImplementations.Count == 1)
interfaceTypeReference = this.ExplicitInterfaceImplementations[0].DeclaringTypeReference;

9
ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMember.cs

@ -101,10 +101,13 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -101,10 +101,13 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
if (accessorDefinition == null)
return null;
var result = LazyInit.VolatileRead(ref cachingField);
if (result != null)
if (result != null) {
return result;
else
return LazyInit.GetOrSet(ref cachingField, new SpecializedMethod(accessorDefinition, substitution));
} else {
var sm = new SpecializedMethod(accessorDefinition, substitution);
//sm.AccessorOwner = this;
return LazyInit.GetOrSet(ref cachingField, sm);
}
}
/// <summary>

23
ICSharpCode.NRefactory/TypeSystem/Implementation/SpecializedMethod.cs

@ -21,7 +21,7 @@ using System.Collections.Generic; @@ -21,7 +21,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
@ -121,6 +121,27 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -121,6 +121,27 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
get { return methodDefinition.IsOperator; }
}
public bool IsAccessor {
get { return methodDefinition.IsAccessor; }
}
IMember accessorOwner;
public IMember AccessorOwner {
get {
var result = LazyInit.VolatileRead(ref accessorOwner);
if (result != null) {
return result;
} else {
result = SpecializedMember.Create(methodDefinition.AccessorOwner, this.Substitution);
return LazyInit.GetOrSet(ref accessorOwner, result);
}
}
internal set {
accessorOwner = value;
}
}
public override IMemberReference ToMemberReference()
{
// Pass the MethodTypeArguments to the SpecializingMemberReference only if

10
ICSharpCode.NRefactory/TypeSystem/KnownTypeReference.cs

@ -101,6 +101,12 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -101,6 +101,12 @@ namespace ICSharpCode.NRefactory.TypeSystem
IEnumerableOfT,
/// <summary><c>System.Collections.Generic.IEnumerator{T}</c></summary>
IEnumeratorOfT,
/// <summary><c>System.Collections.Generic.ICollection</c></summary>
ICollection,
/// <summary><c>System.Collections.Generic.ICollection{T}</c></summary>
ICollectionOfT,
/// <summary><c>System.Collections.Generic.IList</c></summary>
IList,
/// <summary><c>System.Collections.Generic.IList{T}</c></summary>
IListOfT,
/// <summary><c>System.Collections.Generic.IReadOnlyList{T}</c></summary>
@ -158,7 +164,11 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -158,7 +164,11 @@ namespace ICSharpCode.NRefactory.TypeSystem
new KnownTypeReference(KnownTypeCode.IEnumerator, "System.Collections", "IEnumerator"),
new KnownTypeReference(KnownTypeCode.IEnumerableOfT, "System.Collections.Generic", "IEnumerable", 1),
new KnownTypeReference(KnownTypeCode.IEnumeratorOfT, "System.Collections.Generic", "IEnumerator", 1),
new KnownTypeReference(KnownTypeCode.ICollection, "System.Collections", "ICollection"),
new KnownTypeReference(KnownTypeCode.ICollectionOfT, "System.Collections.Generic", "ICollection", 1),
new KnownTypeReference(KnownTypeCode.IList, "System.Collections", "IList"),
new KnownTypeReference(KnownTypeCode.IListOfT, "System.Collections.Generic", "IList", 1),
new KnownTypeReference(KnownTypeCode.IReadOnlyListOfT, "System.Collections.Generic", "IReadOnlyList", 1),
new KnownTypeReference(KnownTypeCode.Task, "System.Threading.Tasks", "Task"),
new KnownTypeReference(KnownTypeCode.TaskOfT, "System.Threading.Tasks", "Task", 1, baseType: KnownTypeCode.Task),

Loading…
Cancel
Save