Browse Source

Fixed two small code completion bugs:

- code completion does not show members of base class when some interface of the class does not exist
- when referenced assemblies had inter-dependencies (Assembly A depends on B), code completion on properties in A that used a type in B would not work.
ReflectionParameter: Read "ref/out/params" modifier correctly.
ReflectionProjectContent: Use ReflectionLoad also for GAC assemblies specified by partial name.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@348 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 20 years ago
parent
commit
d992e73b07
  1. 7
      src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetAmbience.cs
  2. 2
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  3. 4
      src/Main/Base/Project/Src/Dom/IParameter.cs
  4. 11
      src/Main/Base/Project/Src/Dom/Implementations/DefaultClass.cs
  5. 5
      src/Main/Base/Project/Src/Dom/Implementations/DefaultParameter.cs
  6. 2
      src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryASTConvertVisitor.cs
  7. 34
      src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs
  8. 23
      src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionParameter.cs
  9. 5
      src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionReturnType.cs
  10. 22
      src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs
  11. 2
      src/Main/Base/Project/Src/Services/ParserService/ParserService.cs
  12. 53
      src/Main/Base/Project/Src/Services/ParserService/ProjectContentRegistry.cs
  13. 20
      src/Main/Base/Project/Src/Services/ParserService/ReflectionProjectContent.cs
  14. 7
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/CompletionWindow/CodeCompletionDataProvider.cs

7
src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetAmbience.cs

@ -564,12 +564,13 @@ namespace VBNetBinding @@ -564,12 +564,13 @@ namespace VBNetBinding
builder.Append("<i>");
}
if (param.IsOptional) {
builder.Append("Optional ");
}
if (param.IsRef || param.IsOut) {
builder.Append("ByRef ");
} else if (param.IsParams) {
builder.Append("ByVal ParamArray ");
} else {
builder.Append("ByVal ");
builder.Append("ParamArray ");
}
if (IncludeHTMLMarkup) {
builder.Append("</i>");

2
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -183,7 +183,7 @@ @@ -183,7 +183,7 @@
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Src\Gui\Dialogs\CommonAboutDialog.cs">
<SubType>Form</SubType>
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Src\Gui\Dialogs\DirtyFilesDialog.cs" />
<Compile Include="Src\Gui\Dialogs\FolderDialog.cs" />

4
src/Main/Base/Project/Src/Dom/IParameter.cs

@ -50,5 +50,9 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -50,5 +50,9 @@ namespace ICSharpCode.SharpDevelop.Dom
bool IsParams {
get;
}
bool IsOptional {
get;
}
}
}

11
src/Main/Base/Project/Src/Dom/Implementations/DefaultClass.cs

@ -230,25 +230,28 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -230,25 +230,28 @@ namespace ICSharpCode.SharpDevelop.Dom
Queue<IReturnType> typesToVisit = new Queue<IReturnType>();
bool enqueuedLastBaseType = false;
IClass currentClass = this;
IReturnType nextType;
do {
if (currentClass != null) {
if (!visitedList.Contains(currentClass)) {
visitedList.Add(currentClass);
foreach (IReturnType type in currentClass.BaseTypes) {
typesToVisit.Enqueue(type);
}
}
IReturnType nextType;
}
if (typesToVisit.Count > 0) {
nextType = typesToVisit.Dequeue();
} else {
nextType = enqueuedLastBaseType ? null : GetBaseTypeByClassType();
enqueuedLastBaseType = true;
}
currentClass = (nextType != null) ? nextType.GetUnderlyingClass() : null;
} while (currentClass != null);
if (nextType != null) {
currentClass = nextType.GetUnderlyingClass();
}
} while (nextType != null);
if (UseInheritanceCache)
inheritanceTreeCache = visitedList;
currentClass = ReflectionReturnType.Object.GetUnderlyingClass();
return visitedList;
}
}

5
src/Main/Base/Project/Src/Dom/Implementations/DefaultParameter.cs

@ -64,6 +64,11 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -64,6 +64,11 @@ namespace ICSharpCode.SharpDevelop.Dom
return (modifier & ParameterModifiers.Params) == ParameterModifiers.Params;
}
}
public bool IsOptional {
get {
return (modifier & ParameterModifiers.Optional) == ParameterModifiers.Optional;
}
}
public virtual string Name {
get {

2
src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryASTConvertVisitor.cs

@ -285,7 +285,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -285,7 +285,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
}
currentClass.Push(c);
if (typeDeclaration.BaseTypes != null) {
if (c.ClassType != ClassType.Enum && typeDeclaration.BaseTypes != null) {
foreach (AST.TypeReference type in typeDeclaration.BaseTypes) {
c.BaseTypes.Add(CreateReturnType(type));
}

34
src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs

@ -101,16 +101,16 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -101,16 +101,16 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
Expression ParseExpression(string expression)
{
Expression expr = SpecialConstructs(expression);
if (expr == null) {
using (ICSharpCode.NRefactory.Parser.IParser p = ParserFactory.CreateParser(language, new System.IO.StringReader(expression))) {
return p.ParseExpression();
expr = p.ParseExpression();
}
}
return expr;
}
public ResolveResult Resolve(ExpressionResult expressionResult,
int caretLineNumber,
int caretColumn,
string fileName,
string fileContent)
string GetFixedExpression(ExpressionResult expressionResult)
{
string expression = expressionResult.Expression;
if (expression == null) {
@ -121,6 +121,16 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -121,6 +121,16 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (expressionResult.Context.IsObjectCreation) {
expression = "new " + expression;
}
return expression;
}
public ResolveResult Resolve(ExpressionResult expressionResult,
int caretLineNumber,
int caretColumn,
string fileName,
string fileContent)
{
string expression = GetFixedExpression(expressionResult);
this.caretLine = caretLineNumber;
this.caretColumn = caretColumn;
@ -146,20 +156,24 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -146,20 +156,24 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return new NamespaceResolveResult(null, null, "");
}
}
if (expr == null) {
expr = SpecialConstructs(expression);
if (expr == null) {
expr = ParseExpression(expression);
if (expr == null) {
return null;
}
}
}
if (expressionResult.Context == ExpressionContext.Attribute) {
return ResolveAttribute(expr);
}
RunLookupTableVisitor(fileContent);
return ResolveInternal(expr, expressionResult.Context);
}
void RunLookupTableVisitor(string fileContent)
{
lookupTableVisitor = new LookupTableVisitor(languageProperties.NameComparer);
callingMember = GetCurrentMember();
@ -171,8 +185,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -171,8 +185,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
lookupTableVisitor.Visit(p.CompilationUnit, null);
}
}
return ResolveInternal(expr, expressionResult.Context);
}
string GetAttributeName(Expression expr)

23
src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionParameter.cs

@ -31,18 +31,25 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -31,18 +31,25 @@ namespace ICSharpCode.SharpDevelop.Dom
this.parameterInfo = parameterInfo;
this.member = member;
Type type = parameterInfo.ParameterType;
if (parameterInfo.IsOut) {
modifier = ParameterModifiers.Out;
} else if (type.Name.EndsWith("&")) {
// seems there is no other way to determine a ref parameter
modifier = ParameterModifiers.Ref;
}
Type type = parameterInfo.ParameterType;
// TODO read param attribute
//if (type.IsArray && type != typeof(Array) && Attribute.IsDefined(parameterInfo, typeof(ParamArrayAttribute), true)) {
// modifier |= ParameterModifier.Params;
//}
// seems there is no other way to determine a ref parameter
if (type.Name.EndsWith("&")) {
modifier |= ParameterModifiers.Ref;
if (parameterInfo.IsOptional) {
modifier |= ParameterModifiers.Optional;
}
if (type.IsArray && type != typeof(Array)) {
foreach (CustomAttributeData data in CustomAttributeData.GetCustomAttributes(parameterInfo)) {
if (data.Constructor.DeclaringType.FullName == typeof(ParamArrayAttribute).FullName) {
modifier |= ParameterModifiers.Params;
break;
}
}
}
}
}

5
src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionReturnType.cs

@ -116,6 +116,11 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -116,6 +116,11 @@ namespace ICSharpCode.SharpDevelop.Dom
string name = type.FullName;
if (name == null)
return null;
if (name.Length > 1) {
if (name[name.Length - 1] == '&') {
name = name.Substring(0, name.Length - 1);
}
}
if (name.Length > 2) {
if (name[name.Length - 2] == '`') {
name = name.Substring(0, name.Length - 2);

22
src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs

@ -59,23 +59,33 @@ namespace ICSharpCode.Core @@ -59,23 +59,33 @@ namespace ICSharpCode.Core
switch (item.ItemType) {
case ItemType.Reference:
case ItemType.ProjectReference:
AddReference(item as ReferenceProjectItem);
AddReference(item as ReferenceProjectItem, false);
break;
}
}
UpdateReferenceInterDependencies();
}
delegate void AddReferenceDelegate(ReferenceProjectItem reference);
void UpdateReferenceInterDependencies()
{
foreach (IProjectContent referencedContent in this.ReferencedContents) {
if (referencedContent is ReflectionProjectContent) {
((ReflectionProjectContent)referencedContent).InitializeReferences();
}
}
}
delegate void AddReferenceDelegate(ReferenceProjectItem reference, bool updateInterDependencies);
void AddReference(ReferenceProjectItem reference)
void AddReference(ReferenceProjectItem reference, bool updateInterDependencies)
{
try {
IProjectContent referencedContent = ProjectContentRegistry.GetProjectContentForReference(reference);
if (referencedContent != null) {
ReferencedContents.Add(referencedContent);
}
if (referencedContent is ReflectionProjectContent) {
((ReflectionProjectContent)referencedContent).InitializeReferences();
if (updateInterDependencies) {
UpdateReferenceInterDependencies();
}
} catch (Exception e) {
MessageService.ShowError(e);
@ -87,7 +97,7 @@ namespace ICSharpCode.Core @@ -87,7 +97,7 @@ namespace ICSharpCode.Core
if (e.Project != project) return;
ReferenceProjectItem reference = e.ProjectItem as ReferenceProjectItem;
if (reference != null) {
new AddReferenceDelegate(AddReference).BeginInvoke(reference, null, null);
new AddReferenceDelegate(AddReference).BeginInvoke(reference, true, null, null);
}
if (e.ProjectItem.ItemType == ItemType.Import) {
UpdateDefaultImports(project.Items.ToArray());

2
src/Main/Base/Project/Src/Services/ParserService/ParserService.cs

@ -181,6 +181,7 @@ namespace ICSharpCode.Core @@ -181,6 +181,7 @@ namespace ICSharpCode.Core
static void ParserUpdateThread()
{
LoggingService.Info("ParserUpdateThread started");
// preload mscorlib, we're going to need it anyway
IProjectContent dummyVar = ProjectContentRegistry.Mscorlib;
@ -196,6 +197,7 @@ namespace ICSharpCode.Core @@ -196,6 +197,7 @@ namespace ICSharpCode.Core
}
Thread.Sleep(2000);
}
LoggingService.Info("ParserUpdateThread stopped");
}
static object[] GetWorkbench()

53
src/Main/Base/Project/Src/Services/ParserService/ProjectContentRegistry.cs

@ -81,16 +81,19 @@ namespace ICSharpCode.Core @@ -81,16 +81,19 @@ namespace ICSharpCode.Core
return ParserService.GetProjectContent(((ProjectReferenceProjectItem)item).ReferencedProject);
}
lock (contents) {
if (contents.ContainsKey(item.FileName)) {
return contents[item.FileName];
string itemInclude = item.Include;
string itemFileName = item.FileName;
if (contents.ContainsKey(itemFileName)) {
return contents[itemFileName];
}
if (contents.ContainsKey(item.Include)) {
return contents[item.Include];
if (contents.ContainsKey(itemInclude)) {
return contents[itemInclude];
}
string shortName = item.Include;
LoggingService.Debug("Loading PC for " + shortName);
LoggingService.Debug("Loading PC for " + itemInclude);
string shortName = itemInclude;
int pos = shortName.IndexOf(',');
if (pos > 0)
shortName = shortName.Substring(0, pos);
@ -101,47 +104,46 @@ namespace ICSharpCode.Core @@ -101,47 +104,46 @@ namespace ICSharpCode.Core
string how = "??";
#endif
Assembly assembly = GetDefaultAssembly(shortName);
try {
if (assembly != null) {
contents[item.Include] = new ReflectionProjectContent(assembly);
#if DEBUG
how = "typeof";
#endif
return contents[item.Include];
return contents[itemInclude];
}
lookupDirectory = Path.GetDirectoryName(item.FileName);
lookupDirectory = Path.GetDirectoryName(itemFileName);
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += AssemblyResolve;
try {
assembly = Assembly.ReflectionOnlyLoadFrom(item.FileName);
assembly = Assembly.ReflectionOnlyLoadFrom(itemFileName);
if (assembly != null) {
contents[item.FileName] = new ReflectionProjectContent(assembly);
contents[itemFileName] = new ReflectionProjectContent(assembly);
contents[assembly.FullName] = contents[itemFileName];
#if DEBUG
how = "ReflectionOnly";
#endif
return contents[item.FileName];
}
} finally {
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve -= AssemblyResolve;
lookupDirectory = null;
return contents[itemFileName];
}
} catch (FileNotFoundException) {
try {
assembly = LoadGACAssembly(item.Include, true);
assembly = LoadGACAssembly(itemInclude, true);
if (assembly != null) {
contents[item.Include] = new ReflectionProjectContent(assembly);
contents[itemInclude] = new ReflectionProjectContent(assembly);
contents[assembly.FullName] = contents[itemInclude];
#if DEBUG
how = "PartialName";
#endif
return contents[item.Include];
return contents[itemInclude];
}
} catch (Exception e) {
LoggingService.Debug("Can't load assembly '" + item.Include + "' : " + e.Message);
LoggingService.Debug("Can't load assembly '" + itemInclude + "' : " + e.Message);
}
} catch (BadImageFormatException) {
LoggingService.Warn("BadImageFormat: " + shortName);
LoggingService.Warn("BadImageFormat: " + itemInclude);
} finally {
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve -= AssemblyResolve;
lookupDirectory = null;
#if DEBUG
LoggingService.DebugFormatted("Loaded {0} with {2} in {1}ms", item.Include, Environment.TickCount - time, how);
LoggingService.DebugFormatted("Loaded {0} with {2} in {1}ms", itemInclude, Environment.TickCount - time, how);
#endif
StatusBarService.ProgressMonitor.Done();
}
@ -279,9 +281,16 @@ namespace ICSharpCode.Core @@ -279,9 +281,16 @@ namespace ICSharpCode.Core
public static Assembly LoadGACAssembly(string partialName, bool reflectionOnly)
{
if (reflectionOnly) {
AssemblyName name = FindBestMatchingAssemblyName(partialName);
if (name == null)
return null;
return Assembly.ReflectionOnlyLoad(name.FullName);
} else {
#pragma warning disable 618
return Assembly.LoadWithPartialName(partialName);
#pragma warning restore 618
}
}
}
}

20
src/Main/Base/Project/Src/Services/ParserService/ReflectionProjectContent.cs

@ -57,15 +57,33 @@ namespace ICSharpCode.Core @@ -57,15 +57,33 @@ namespace ICSharpCode.Core
}
bool initialized = false;
ArrayList missingNames;
public void InitializeReferences()
{
if (initialized) return;
if (initialized) {
if (missingNames != null) {
for (int i = 0; i < missingNames.Count; i++) {
IProjectContent content = ProjectContentRegistry.GetExistingProjectContent((AssemblyName)missingNames[i]);
if (content != null) {
ReferencedContents.Add(content);
missingNames.RemoveAt(i--);
}
}
if (missingNames.Count == 0)
missingNames = null;
}
return;
}
initialized = true;
foreach (AssemblyName name in assembly.GetReferencedAssemblies()) {
IProjectContent content = ProjectContentRegistry.GetExistingProjectContent(name);
if (content != null) {
ReferencedContents.Add(content);
} else {
if (missingNames == null)
missingNames = new ArrayList();
missingNames.Add(name);
}
}
}

7
src/Main/Base/Project/Src/TextEditor/Gui/Editor/CompletionWindow/CodeCompletionDataProvider.cs

@ -42,16 +42,13 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -42,16 +42,13 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
else
LoggingService.DebugFormatted("GenerateCompletionData for >>{0}<<, context={1}", expressionResult.Expression, expressionResult.Context);
}
string textContent = textArea.Document.TextContent;
#if DEBUG
if (DebugMode) {
Debugger.Break();
}
#endif
AddResolveResults(ParserService.Resolve(expressionResult,
caretLineNumber,
caretColumn,
fileName,
textArea.Document.TextContent),
AddResolveResults(ParserService.Resolve(expressionResult, caretLineNumber, caretColumn, fileName, textContent),
expressionResult.Context);
}
}

Loading…
Cancel
Save