Browse Source

Merge remote-tracking branch 'upstream/master' into mansheng

newNRvisualizers
Mansheng Yang 14 years ago
parent
commit
d1388d501e
  1. 88
      ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs
  2. 182
      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. 5
      ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj
  7. 18
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/InconsistentNamingIssue/WordParser.cs
  8. 67
      ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/CodeCompletionBugTests.cs
  9. 52
      ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/ParameterCompletionTests.cs
  10. 11
      ICSharpCode.NRefactory/Documentation/XmlDocumentationProvider.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);

182
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");
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");
throw new ArgumentNullException("ctx");
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);
}
}

5
ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj

@ -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>
@ -310,7 +309,6 @@ @@ -310,7 +309,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" />
@ -390,6 +388,7 @@ @@ -390,6 +388,7 @@
<Compile Include="Refactoring\CodeActions\ImplementInterfaceExplicitAction.cs" />
<Compile Include="Refactoring\CodeActions\ImplementAbstractMembersAction.cs" />
<Compile Include="Refactoring\CodeActions\ExtractFieldAction.cs" />
<Compile Include="Completion\ICompletionContextProvider.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj">

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)

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

@ -199,46 +199,48 @@ namespace ICSharpCode.NRefactory.CSharp.CodeCompletion @@ -199,46 +199,48 @@ namespace ICSharpCode.NRefactory.CSharp.CodeCompletion
#endregion
}
static CompletionDataList CreateProvider (string text, bool isCtrlSpace)
static CompletionDataList CreateProvider(string text, bool isCtrlSpace)
{
string parsedText;
string editorText;
int cursorPosition = text.IndexOf ('$');
int endPos = text.IndexOf ('$', cursorPosition + 1);
int cursorPosition = text.IndexOf('$');
int endPos = text.IndexOf('$', cursorPosition + 1);
if (endPos == -1) {
parsedText = editorText = text.Substring (0, cursorPosition) + text.Substring (cursorPosition + 1);
parsedText = editorText = text.Substring(0, cursorPosition) + text.Substring(cursorPosition + 1);
} 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);
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;
}
var doc = new ReadOnlyDocument (editorText);
var doc = new ReadOnlyDocument(editorText);
IProjectContent pctx = new CSharpProjectContent ();
pctx = pctx.AddAssemblyReferences (new [] { CecilLoaderTests.Mscorlib, CecilLoaderTests.SystemCore });
IProjectContent pctx = new CSharpProjectContent();
pctx = pctx.AddAssemblyReferences(new [] { CecilLoaderTests.Mscorlib, CecilLoaderTests.SystemCore });
var compilationUnit = new CSharpParser ().Parse (parsedText, "program.cs");
compilationUnit.Freeze ();
var compilationUnit = new CSharpParser().Parse(parsedText, "program.cs");
compilationUnit.Freeze();
var parsedFile = compilationUnit.ToTypeSystem ();
pctx = pctx.UpdateProjectContent (null, parsedFile);
var parsedFile = compilationUnit.ToTypeSystem();
pctx = pctx.UpdateProjectContent(null, parsedFile);
var cmp = pctx.CreateCompilation ();
var loc = doc.GetLocation (cursorPosition);
var cmp = pctx.CreateCompilation();
var loc = doc.GetLocation(cursorPosition);
var rctx = new CSharpTypeResolveContext (cmp.MainAssembly);
rctx = rctx.WithUsingScope (parsedFile.GetUsingScope (loc).Resolve (cmp));
var rctx = new CSharpTypeResolveContext(cmp.MainAssembly);
rctx = rctx.WithUsingScope(parsedFile.GetUsingScope(loc).Resolve(cmp));
var curDef = parsedFile.GetInnermostTypeDefinition (loc);
var curDef = parsedFile.GetInnermostTypeDefinition(loc);
if (curDef != null) {
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)
rctx = rctx.WithCurrentMember (curMember);
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) {
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 ();
@ -253,17 +255,18 @@ namespace ICSharpCode.NRefactory.CSharp.CodeCompletion @@ -253,17 +255,18 @@ namespace ICSharpCode.NRefactory.CSharp.CodeCompletion
};
}
Tuple<ReadOnlyDocument, CSharpCompletionEngine> GetContent (string text, CompilationUnit compilationUnit)
Tuple<ReadOnlyDocument, CSharpCompletionEngine> GetContent(string text, CompilationUnit compilationUnit)
{
var doc = new ReadOnlyDocument (text);
IProjectContent pctx = new CSharpProjectContent ();
pctx = pctx.AddAssemblyReferences (new [] { CecilLoaderTests.Mscorlib, CecilLoaderTests.SystemCore });
var parsedFile = compilationUnit.ToTypeSystem ();
var doc = new ReadOnlyDocument(text);
IProjectContent pctx = new CSharpProjectContent();
pctx = pctx.AddAssemblyReferences(new [] { CecilLoaderTests.Mscorlib, CecilLoaderTests.SystemCore });
var parsedFile = compilationUnit.ToTypeSystem();
pctx = pctx.UpdateProjectContent (null, parsedFile);
var cmp = pctx.CreateCompilation ();
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);

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

@ -254,43 +254,45 @@ namespace ICSharpCode.NRefactory.CSharp.CodeCompletion @@ -254,43 +254,45 @@ namespace ICSharpCode.NRefactory.CSharp.CodeCompletion
#endregion
}
internal static IParameterDataProvider CreateProvider (string text)
internal static IParameterDataProvider CreateProvider(string text)
{
string parsedText;
string editorText;
int cursorPosition = text.IndexOf ('$');
int endPos = text.IndexOf ('$', cursorPosition + 1);
if (endPos == -1)
parsedText = editorText = text.Substring (0, cursorPosition) + text.Substring (cursorPosition + 1);
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);
int cursorPosition = text.IndexOf('$');
int endPos = text.IndexOf('$', cursorPosition + 1);
if (endPos == -1) {
parsedText = editorText = text.Substring(0, cursorPosition) + text.Substring(cursorPosition + 1);
} 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;
}
var doc = new ReadOnlyDocument (editorText);
var doc = new ReadOnlyDocument(editorText);
IProjectContent pctx = new CSharpProjectContent ();
pctx = pctx.AddAssemblyReferences (new [] { CecilLoaderTests.Mscorlib, CecilLoaderTests.SystemCore });
IProjectContent pctx = new CSharpProjectContent();
pctx = pctx.AddAssemblyReferences(new [] { CecilLoaderTests.Mscorlib, CecilLoaderTests.SystemCore });
var compilationUnit = new CSharpParser ().Parse (parsedText, "program.cs");
compilationUnit.Freeze ();
var compilationUnit = new CSharpParser().Parse(parsedText, "program.cs");
compilationUnit.Freeze();
var parsedFile = compilationUnit.ToTypeSystem ();
pctx = pctx.UpdateProjectContent (null, parsedFile);
var cmp = pctx.CreateCompilation ();
var loc = doc.GetLocation (cursorPosition);
var parsedFile = compilationUnit.ToTypeSystem();
pctx = pctx.UpdateProjectContent(null, parsedFile);
var cmp = pctx.CreateCompilation();
var loc = doc.GetLocation(cursorPosition);
var rctx = new CSharpTypeResolveContext (cmp.MainAssembly);
rctx = rctx.WithUsingScope (parsedFile.GetUsingScope (loc).Resolve (cmp));
var curDef = parsedFile.GetInnermostTypeDefinition (loc);
var rctx = new CSharpTypeResolveContext(cmp.MainAssembly);
rctx = rctx.WithUsingScope(parsedFile.GetUsingScope(loc).Resolve(cmp));
var curDef = parsedFile.GetInnermostTypeDefinition(loc);
if (curDef != null) {
rctx = rctx.WithCurrentTypeDefinition (curDef.Resolve (rctx).GetDefinition ());
var curMember = parsedFile.GetMember (loc);
if (curMember != null)
rctx = rctx.WithCurrentMember (curMember.CreateResolved (rctx));
rctx = rctx.WithCurrentTypeDefinition(curDef.Resolve(rctx).GetDefinition());
var curMember = parsedFile.GetMember(loc);
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));
}

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)

Loading…
Cancel
Save