diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/Parser.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/Parser.cs index 6c67939438..ff6b55fc26 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/Parser.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/Parser.cs @@ -3,9 +3,11 @@ using System; using System.IO; +using System.Threading; using ICSharpCode.Core; using ICSharpCode.Editor; using ICSharpCode.NRefactory.CSharp; +using ICSharpCode.NRefactory.CSharp.Resolver; using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Parser; @@ -68,13 +70,16 @@ namespace CSharpBinding.Parser bool fullParseInformationRequested) { CSharpParser parser = new CSharpParser(); - parser.GenerateTypeSystemMode = true; + parser.GenerateTypeSystemMode = !fullParseInformationRequested; CompilationUnit cu = parser.Parse(fileContent.CreateReader()); TypeSystemConvertVisitor cv = new TypeSystemConvertVisitor(projectContent, fileName); ParsedFile file = cv.Convert(cu); - return new ParseInformation(file, true); + ParseInformation info = new ParseInformation(file, fullParseInformationRequested); + if (fullParseInformationRequested) + info.AddAnnotation(cu); + return info; } /*void AddCommentTags(ICompilationUnit cu, System.Collections.Generic.List tagComments) @@ -86,5 +91,28 @@ namespace CSharpBinding.Parser } } */ + + public ResolveResult Resolve(ParseInformation parseInfo, TextLocation location, ITypeResolveContext context, CancellationToken cancellationToken) + { + CompilationUnit cu = parseInfo.Annotation(); + if (cu == null) + throw new ArgumentException("Parse info does not have CompilationUnit"); + ParsedFile parsedFile = parseInfo.ParsedFile as ParsedFile; + if (parsedFile == null) + throw new ArgumentException("Parse info does not have a C# ParsedFile"); + + AstNode node = cu.GetResolveableNodeAt(location); + if (node == null) { + LoggingService.Debug("Could not find resolvable node at " + location); + return null; + } + LoggingService.DebugFormatted("Resolving '{0}' at {1}", node, location); + var navigator = new NodeListResolveVisitorNavigator(new[] { node }); + var resolver = new CSharpResolver(context, cancellationToken); + ResolveVisitor visitor = new ResolveVisitor(resolver, parsedFile, navigator); + visitor.Scan(cu); + + return visitor.GetResolveResult(node); + } } } diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs index 419628d086..d5c4f9a61e 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs @@ -118,7 +118,7 @@ namespace ICSharpCode.AvalonEdit.AddIn } else { this.errorPainter.UpdateErrors(); } - changeWatcher.Initialize(this.Document); + changeWatcher.Initialize(this.Document, value); FetchParseInformation(); } diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/DefaultChangeWatcher.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/DefaultChangeWatcher.cs index f2d4595c8a..9bfa4394a6 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/DefaultChangeWatcher.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/DefaultChangeWatcher.cs @@ -9,6 +9,7 @@ using System.Linq; using ICSharpCode.AvalonEdit.AddIn.MyersDiff; using ICSharpCode.AvalonEdit.Document; using ICSharpCode.AvalonEdit.Utils; +using ICSharpCode.Core; using ICSharpCode.Editor; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Editor; @@ -24,6 +25,7 @@ namespace ICSharpCode.AvalonEdit.AddIn IDocument baseDocument; IDocumentVersionProvider usedProvider; IDisposable watcher; + FileName fileName; public event EventHandler ChangeOccurred; @@ -39,19 +41,19 @@ namespace ICSharpCode.AvalonEdit.AddIn return changeList[lineNumber]; } - public void Initialize(IDocument document) + public void Initialize(IDocument document, FileName fileName) { if (changeList != null && changeList.Any()) return; this.document = document; + this.fileName = fileName; this.textDocument = (TextDocument)document.GetService(typeof(TextDocument)); this.changeList = new CompressingTreeList((x, y) => x.Equals(y)); InitializeBaseDocument(); if (usedProvider != null) { - string fileName = ((ITextEditor)document.GetService(typeof(ITextEditor))).FileName; watcher = usedProvider.WatchBaseVersionChanges(fileName, HandleBaseVersionChanges); } @@ -140,8 +142,6 @@ namespace ICSharpCode.AvalonEdit.AddIn Stream GetBaseVersion() { - string fileName = ((ITextEditor)document.GetService(typeof(ITextEditor))).FileName; - foreach (IDocumentVersionProvider provider in VersioningServices.Instance.DocumentVersionProviders) { var result = provider.OpenBaseVersion(fileName); if (result != null) { @@ -153,7 +153,7 @@ namespace ICSharpCode.AvalonEdit.AddIn return null; } - void UndoStackPropertyChanged(object sender, PropertyChangedEventArgs e) + void UndoStackPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { if (e.PropertyName == "IsOriginalFile" && textDocument.UndoStack.IsOriginalFile) SetupInitialFileState(true); diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/LineChangeInfo.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/LineChangeInfo.cs index 283503d09a..a8af407a01 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/LineChangeInfo.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/LineChangeInfo.cs @@ -2,6 +2,7 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using ICSharpCode.Core; using ICSharpCode.Editor; using ICSharpCode.SharpDevelop.Editor; @@ -16,7 +17,7 @@ namespace ICSharpCode.AvalonEdit.AddIn /// Pass 0 to get the changes before the first line. /// LineChangeInfo GetChange(int lineNumber); - void Initialize(IDocument document); + void Initialize(IDocument document, FileName fileName); string GetOldVersionFromLine(int lineNumber, out int newStartLine, out bool added); bool GetNewVersionFromLine(int lineNumber, out int offset, out int length); IDocument CurrentDocument { get; } diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory/CSharp/Refactoring/TypeSystemAstBuilder.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory/CSharp/Refactoring/TypeSystemAstBuilder.cs index b67ab0cd9f..78d5951b23 100644 --- a/src/Libraries/NRefactory/ICSharpCode.NRefactory/CSharp/Refactoring/TypeSystemAstBuilder.cs +++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory/CSharp/Refactoring/TypeSystemAstBuilder.cs @@ -671,5 +671,19 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring return c; } #endregion + + #region Convert Variable + public VariableDeclarationStatement ConvertVariable(IVariable v) + { + VariableDeclarationStatement decl = new VariableDeclarationStatement(); + decl.Modifiers = v.IsConst ? Modifiers.Const : Modifiers.None; + decl.Type = ConvertType(v.Type.Resolve(context)); + Expression initializer = null; + if (v.IsConst) + initializer = ConvertConstantValue(v.ConstantValue); + decl.Variables.Add(new VariableInitializer(v.Name, initializer)); + return decl; + } + #endregion } } diff --git a/src/Main/Base/Project/Src/Services/AmbienceService/CSharpAmbience.cs b/src/Main/Base/Project/Src/Services/AmbienceService/CSharpAmbience.cs index 37ab0bb557..c42e2343a8 100644 --- a/src/Main/Base/Project/Src/Services/AmbienceService/CSharpAmbience.cs +++ b/src/Main/Base/Project/Src/Services/AmbienceService/CSharpAmbience.cs @@ -30,6 +30,18 @@ namespace ICSharpCode.SharpDevelop } } + public string ConvertVariable(IVariable v) + { + using (var ctx = ParserService.CurrentTypeResolveContext.Synchronize()) { + TypeSystemAstBuilder astBuilder = new TypeSystemAstBuilder(ctx); + AstNode astNode = astBuilder.ConvertVariable(v); + CSharpFormattingOptions formatting = new CSharpFormattingOptions(); + StringWriter writer = new StringWriter(); + astNode.AcceptVisitor(new OutputVisitor(writer, formatting), null); + return writer.ToString(); + } + } + public string ConvertType(IType type) { using (var ctx = ParserService.CurrentTypeResolveContext.Synchronize()) { diff --git a/src/Main/Base/Project/Src/Services/AmbienceService/IAmbience.cs b/src/Main/Base/Project/Src/Services/AmbienceService/IAmbience.cs index df977c4603..857ba2c2ac 100644 --- a/src/Main/Base/Project/Src/Services/AmbienceService/IAmbience.cs +++ b/src/Main/Base/Project/Src/Services/AmbienceService/IAmbience.cs @@ -83,8 +83,10 @@ namespace ICSharpCode.SharpDevelop string ConvertEntity(IEntity e); string ConvertType(IType type); + string ConvertVariable(IVariable variable); string WrapAttribute(string attribute); string WrapComment(string comment); + } } diff --git a/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs b/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs index d23692110c..da8ec0277e 100644 --- a/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs +++ b/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs @@ -4,16 +4,19 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Text; using System.Windows; using System.Windows.Forms; - using ICSharpCode.Core; using ICSharpCode.Editor; using ICSharpCode.NRefactory; +using ICSharpCode.NRefactory.CSharp.Resolver; +using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.SharpDevelop.Bookmarks; using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Gui; +using ICSharpCode.SharpDevelop.Parser; using ICSharpCode.SharpDevelop.Project; using Mono.Cecil; @@ -298,70 +301,39 @@ namespace ICSharpCode.SharpDevelop.Debugging /// internal static void HandleToolTipRequest(ToolTipRequestEventArgs e) { - /* if (!e.InDocument) return; - Location logicPos = e.LogicalPosition; - var doc = e.Editor.Document; + TextLocation logicPos = e.LogicalPosition; + IDocument document = e.Editor.Document; FileName fileName = e.Editor.FileName; - IExpressionFinder expressionFinder = ParserService.GetExpressionFinder(fileName); - if (expressionFinder == null) - return; - - var currentLine = doc.GetLineByNumber(logicPos.Y); - if (logicPos.X > currentLine.Length) - return; - - string textContent = doc.Text; - ExpressionResult expressionResult = expressionFinder.FindFullExpression(textContent, doc.PositionToOffset(logicPos.Line, logicPos.Column)); - string expression = (expressionResult.Expression ?? "").Trim(); - if (expression.Length > 0) { - // Look if it is variable - ResolveResult result = ParserService.Resolve(expressionResult, logicPos.Y, logicPos.X, fileName, textContent); - bool debuggerCanShowValue; - string toolTipText = GetText(result, expression, out debuggerCanShowValue); - if (Control.ModifierKeys == Keys.Control) { - toolTipText = "expr: " + expressionResult.ToString() + "\n" + toolTipText; - debuggerCanShowValue = false; - } - if (toolTipText != null) { - if (debuggerCanShowValue && currentDebugger != null) { - object toolTip = currentDebugger.GetTooltipControl(e.LogicalPosition, expressionResult.Expression); - if (toolTip != null) - e.SetToolTip(toolTip); - else - e.SetToolTip(toolTipText); - } else { + // Look if it is variable + ResolveResult result = ParserService.Resolve(fileName, logicPos, document); + bool debuggerCanShowValue; + string toolTipText = GetText(e, result, out debuggerCanShowValue); + if (toolTipText != null) { + if (debuggerCanShowValue && currentDebugger != null) { + object toolTip = currentDebugger.GetTooltipControl(e, result); + if (toolTip != null) + e.SetToolTip(toolTip); + else e.SetToolTip(toolTipText); - } - } - } else { - #if DEBUG - if (Control.ModifierKeys == Keys.Control) { - e.SetToolTip("no expr: " + expressionResult.ToString()); + } else { + e.SetToolTip(toolTipText); } - #endif - }*/ + } } - /* - static string GetText(ResolveResult result, string expression, out bool debuggerCanShowValue) + static string GetText(ToolTipRequestEventArgs e, ResolveResult result, out bool debuggerCanShowValue) { debuggerCanShowValue = false; - if (result == null) { - // when pressing control, show the expression even when it could not be resolved - return (Control.ModifierKeys == Keys.Control) ? "" : null; - } - if (result is MixedResolveResult) - return GetText(((MixedResolveResult)result).PrimaryResult, expression, out debuggerCanShowValue); - else if (result is DelegateCallResolveResult) - return GetText(((DelegateCallResolveResult)result).Target, expression, out debuggerCanShowValue); + if (result == null) + return null; IAmbience ambience = AmbienceService.GetCurrentAmbience(); ambience.ConversionFlags = ConversionFlags.StandardConversionFlags | ConversionFlags.UseFullyQualifiedMemberNames; if (result is MemberResolveResult) { - return GetMemberText(ambience, ((MemberResolveResult)result).ResolvedMember, expression, out debuggerCanShowValue); + return GetMemberText(ambience, ((MemberResolveResult)result).Member, e, result, out debuggerCanShowValue); } else if (result is LocalResolveResult) { LocalResolveResult rr = (LocalResolveResult)result; ambience.ConversionFlags = ConversionFlags.UseFullyQualifiedTypeNames @@ -371,9 +343,9 @@ namespace ICSharpCode.SharpDevelop.Debugging b.Append("parameter "); else b.Append("local variable "); - b.Append(ambience.Convert(rr.Field)); - if (currentDebugger != null) { - string currentValue = currentDebugger.GetValueAsString(rr.VariableName); + b.Append(ambience.ConvertVariable(rr.Variable)); + if (!rr.IsCompileTimeConstant && currentDebugger != null) { + string currentValue = currentDebugger.GetValueAsString(e, rr); if (currentValue != null) { debuggerCanShowValue = true; b.Append(" = "); @@ -384,72 +356,56 @@ namespace ICSharpCode.SharpDevelop.Debugging } return b.ToString(); } else if (result is NamespaceResolveResult) { - return "namespace " + ((NamespaceResolveResult)result).Name; + return "namespace " + ((NamespaceResolveResult)result).NamespaceName; } else if (result is TypeResolveResult) { - IClass c = ((TypeResolveResult)result).ResolvedClass; + ITypeDefinition c = result.Type.GetDefinition(); if (c != null) - return GetMemberText(ambience, c, expression, out debuggerCanShowValue); + return GetMemberText(ambience, c, e, result, out debuggerCanShowValue); else - return ambience.Convert(result.ResolvedType); + return ambience.ConvertType(result.Type); } else if (result is MethodGroupResolveResult) { MethodGroupResolveResult mrr = result as MethodGroupResolveResult; - IMethod m = mrr.GetMethodIfSingleOverload(); - IMethod m2 = mrr.GetMethodWithEmptyParameterList(); - if (m != null) - return GetMemberText(ambience, m, expression, out debuggerCanShowValue); - else if (ambience is VBNetAmbience && m2 != null) - return GetMemberText(ambience, m2, expression, out debuggerCanShowValue); + if (mrr.Methods.Count() == 1) + return GetMemberText(ambience, mrr.Methods.Single(), e, result, out debuggerCanShowValue); else - return "Overload of " + ambience.Convert(mrr.ContainingType) + "." + mrr.Name; + return "Overload of " + ambience.ConvertType(mrr.TargetType) + "." + mrr.MethodName; } else { + #if DEBUG if (Control.ModifierKeys == Keys.Control) { - if (result.ResolvedType != null) - return "expression of type " + ambience.Convert(result.ResolvedType); - else - return "ResolveResult without ResolvedType"; - } else { - return null; + return result.ToString(); } + #endif + return null; } } - static string GetMemberText(IAmbience ambience, IEntity member, string expression, out bool debuggerCanShowValue) + static string GetMemberText(IAmbience ambience, IEntity member, ToolTipRequestEventArgs e, ResolveResult result, out bool debuggerCanShowValue) { bool tryDisplayValue = false; debuggerCanShowValue = false; StringBuilder text = new StringBuilder(); - if (member is IField) { - text.Append(ambience.Convert(member as IField)); - tryDisplayValue = true; - } else if (member is IProperty) { - text.Append(ambience.Convert(member as IProperty)); - tryDisplayValue = true; - } else if (member is IEvent) { - text.Append(ambience.Convert(member as IEvent)); - } else if (member is IMethod) { - text.Append(ambience.Convert(member as IMethod)); - } else if (member is IClass) { - text.Append(ambience.Convert(member as IClass)); - } else { - text.Append("unknown member "); - text.Append(member.ToString()); - } + text.Append(ambience.ConvertEntity(member)); + tryDisplayValue = ((member is IField && !((IField)member).IsConst) || member is IProperty); + if (tryDisplayValue && currentDebugger != null) { - LoggingService.Info("asking debugger for value of '" + expression + "'"); - string currentValue = currentDebugger.GetValueAsString(expression); + LoggingService.Info("asking debugger for value of '" + result + "'"); + string currentValue = currentDebugger.GetValueAsString(e, result); if (currentValue != null) { debuggerCanShowValue = true; text.Append(" = "); + if (currentValue.Length > 256) + currentValue = currentValue.Substring(0, 256) + "..."; text.Append(currentValue); } } string documentation = member.Documentation; if (documentation != null && documentation.Length > 0) { text.Append('\n'); - text.Append(ICSharpCode.SharpDevelop.Editor.CodeCompletion.CodeCompletionItem.ConvertDocumentation(documentation)); + text.Append(documentation); + //text.Append(ICSharpCode.SharpDevelop.Editor.CodeCompletion.CodeCompletionItem.ConvertDocumentation(documentation)); } return text.ToString(); - }*/ + } #endregion } diff --git a/src/Main/Base/Project/Src/Services/Debugger/DefaultDebugger.cs b/src/Main/Base/Project/Src/Services/Debugger/DefaultDebugger.cs index 29bea3c822..f241652e28 100644 --- a/src/Main/Base/Project/Src/Services/Debugger/DefaultDebugger.cs +++ b/src/Main/Base/Project/Src/Services/Debugger/DefaultDebugger.cs @@ -3,8 +3,8 @@ using System; using System.Diagnostics; -using ICSharpCode.Editor; -using ICSharpCode.NRefactory; +using ICSharpCode.NRefactory.CSharp.Resolver; +using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Project; @@ -124,7 +124,7 @@ namespace ICSharpCode.SharpDevelop.Debugging /// /// Gets the current value of the variable as string that can be displayed in tooltips. /// - public string GetValueAsString(string variable) + public string GetValueAsString(ToolTipRequestEventArgs e, ResolveResult expression) { return null; } @@ -133,7 +133,7 @@ namespace ICSharpCode.SharpDevelop.Debugging /// Gets the tooltip control that shows the value of given variable. /// Return null if no tooltip is available. /// - public object GetTooltipControl(TextLocation logicalPosition, string variable) + public object GetTooltipControl(ToolTipRequestEventArgs e, ResolveResult expression) { return null; } diff --git a/src/Main/Base/Project/Src/Services/Debugger/IDebugger.cs b/src/Main/Base/Project/Src/Services/Debugger/IDebugger.cs index 35a8f54e8f..eec53cb809 100644 --- a/src/Main/Base/Project/Src/Services/Debugger/IDebugger.cs +++ b/src/Main/Base/Project/Src/Services/Debugger/IDebugger.cs @@ -5,6 +5,8 @@ using System; using System.Diagnostics; using ICSharpCode.Editor; using ICSharpCode.NRefactory; +using ICSharpCode.NRefactory.CSharp.Resolver; +using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Project; namespace ICSharpCode.SharpDevelop.Debugging @@ -76,13 +78,13 @@ namespace ICSharpCode.SharpDevelop.Debugging /// /// Gets the current value of the variable as string that can be displayed in tooltips. /// - string GetValueAsString(string variable); + string GetValueAsString(ToolTipRequestEventArgs e, ResolveResult expression); /// /// Gets the tooltip control that shows the value of given variable. /// Return null if no tooltip is available. /// - object GetTooltipControl(TextLocation logicalPosition, string variable); + object GetTooltipControl(ToolTipRequestEventArgs e, ResolveResult expression); /// /// Queries the debugger whether it is possible to set the instruction pointer to a given position. diff --git a/src/Main/Base/Project/Src/Services/ParserService/IParser.cs b/src/Main/Base/Project/Src/Services/ParserService/IParser.cs index b9830d3f99..cbfec78ad0 100644 --- a/src/Main/Base/Project/Src/Services/ParserService/IParser.cs +++ b/src/Main/Base/Project/Src/Services/ParserService/IParser.cs @@ -1,8 +1,10 @@ // Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) +using System.Threading; using ICSharpCode.Core; using ICSharpCode.Editor; +using ICSharpCode.NRefactory.CSharp.Resolver; using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.SharpDevelop.Editor; using System; @@ -49,6 +51,6 @@ namespace ICSharpCode.SharpDevelop.Project ParseInformation Parse(IProjectContent projectContent, FileName fileName, ITextSource fileContent, bool fullParseInformationRequested); - //IResolver CreateResolver(); + ResolveResult Resolve(ParseInformation parseInfo, TextLocation location, ITypeResolveContext context, CancellationToken cancellationToken); } } diff --git a/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs b/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs index ac8dad4e74..415988fdc1 100644 --- a/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs +++ b/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs @@ -2,16 +2,17 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; -using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; -using System.Windows.Threading; +using System.Threading; using System.Threading.Tasks; +using System.Windows.Threading; using ICSharpCode.Core; using ICSharpCode.Editor; +using ICSharpCode.NRefactory.CSharp.Resolver; using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem.Implementation; using ICSharpCode.SharpDevelop.Editor; @@ -455,17 +456,6 @@ namespace ICSharpCode.SharpDevelop.Parser // Don't bother reading the file if this FileEntry was already disposed. if (this.disposed) return; - - - - - - - - - - - } string fileAsString; try { @@ -536,6 +526,9 @@ namespace ICSharpCode.SharpDevelop.Parser } if (newParseInfo[i] == null) throw new NullReferenceException(parser.GetType().Name + ".Parse() returned null"); + if (fullParseInformationRequested && !newParseInfo[i].IsFullParseInformation) + throw new InvalidOperationException(parser.GetType().Name + ".Parse() did not return full parse info as requested."); + newUnits[i] = newParseInfo[i].ParsedFile; if (i == 0 || pc == parentProjectContent) { resultParseInfo = newParseInfo[i]; @@ -1075,5 +1068,24 @@ namespace ICSharpCode.SharpDevelop.Parser entry.Clear(); } #endregion + + public static ResolveResult Resolve(FileName fileName, TextLocation location, ITextSource fileContent = null, + CancellationToken cancellationToken = default(CancellationToken)) + { + var entry = GetFileEntry(fileName, true); + if (entry.parser == null) + return null; + var parseInfo = entry.Parse(fileContent); + if (parseInfo == null) + return null; + IProject project = GetProject(parseInfo.ProjectContent); + var context = project != null ? project.TypeResolveContext : GetDefaultTypeResolveContext(); + ResolveResult rr; + using (var ctx = context.Synchronize()) { + rr = entry.parser.Resolve(parseInfo, location, ctx, cancellationToken); + } + LoggingService.Debug("Resolved " + location + " to " + rr); + return rr; + } } }