Browse Source

Added code completion after keywords like 'using', 'new', 'as', 'is', ...

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@204 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 20 years ago
parent
commit
6b07312f2b
  1. 58
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs
  2. 1
      src/Libraries/NRefactory/Project/Src/Parser/Visitors/VBNetToCSharpConvertVisitor.cs
  3. 11
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  4. 88
      src/Main/Base/Project/Src/Dom/ExpressionContext.cs
  5. 21
      src/Main/Base/Project/Src/Dom/IExpressionFinder.cs
  6. 4
      src/Main/Base/Project/Src/Dom/Implementations/DefaultClass.cs
  7. 98
      src/Main/Base/Project/Src/Dom/Implementations/GetClassReturnType.cs
  8. 85
      src/Main/Base/Project/Src/Dom/Implementations/SearchClassReturnType.cs
  9. 10
      src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs
  10. 20
      src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionReturnType.cs
  11. 6
      src/Main/Base/Project/Src/Services/ParserService/ReflectionProjectContent.cs
  12. 44
      src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs
  13. 2
      src/Main/Base/Project/Src/TextEditor/Actions.cs
  14. 2
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/CodeCompletionBinding.cs
  15. 136
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/CompletionWindow/AbstractCompletionDataProvider.cs
  16. 177
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/CompletionWindow/CodeCompletionDataProvider.cs
  17. 6
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/SharpDevelopTextAreaControl.cs
  18. 1
      src/Main/Base/Test/ICSharpCode.SharpDevelop.Tests.csproj
  19. 47
      src/Main/Base/Test/InnerClassesResolverTests.cs
  20. 44
      src/Main/Base/Test/RefactoringTests.cs
  21. 82
      src/SharpDevelop.sln

58
src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs

@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
// </file>
using System;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor;
namespace CSharpBinding
@ -16,5 +17,62 @@ namespace CSharpBinding @@ -16,5 +17,62 @@ namespace CSharpBinding
{
this.EnableXmlCommentCompletion = true;
}
public override bool HandleKeyPress(SharpDevelopTextAreaControl editor, char ch)
{
if (!CheckExtension(editor))
return false;
if (ch == '(') {
ExpressionContext context;
switch (editor.GetWordBeforeCaret().Trim()) {
case "for":
case "lock":
context = ExpressionContext.Default;
break;
case "using":
context = ExpressionContext.TypeDerivingFrom(ReflectionReturnType.Disposable.GetUnderlyingClass(), false);
break;
case "catch":
context = ExpressionContext.TypeDerivingFrom(ReflectionReturnType.Exception.GetUnderlyingClass(), false);
break;
case "foreach":
case "typeof":
case "sizeof":
case "default":
context = ExpressionContext.Type;
break;
default:
context = null;
break;
}
if (context != null) {
editor.ShowCompletionWindow(new CtrlSpaceCompletionDataProvider(context), ' ');
return true;
}
}
return base.HandleKeyPress(editor, ch);
}
public override bool HandleKeyword(SharpDevelopTextAreaControl editor, string word)
{
// TODO: Assistance writing Methods/Fields/Properties/Events:
// use public/static/etc. as keywords to display a list with other modifiers
// and possible return types.
switch (word) {
case "using":
// TODO: check if we are inside class/namespace
editor.ShowCompletionWindow(new CtrlSpaceCompletionDataProvider(ExpressionContext.Namespace), ' ');
return true;
case "as":
case "is":
editor.ShowCompletionWindow(new CtrlSpaceCompletionDataProvider(ExpressionContext.Type), ' ');
return true;
case "new":
editor.ShowCompletionWindow(new CtrlSpaceCompletionDataProvider(ExpressionContext.ConstructableType), ' ');
return true;
default:
return base.HandleKeyword(editor, word);
}
}
}
}

1
src/Libraries/NRefactory/Project/Src/Parser/Visitors/VBNetToCSharpConvertVisitor.cs

@ -27,6 +27,7 @@ namespace ICSharpCode.NRefactory.Parser @@ -27,6 +27,7 @@ namespace ICSharpCode.NRefactory.Parser
// The following conversions should be implemented in the future:
// Public Event EventName(param As String) -> automatic delegate declaration
// Function A() \n A = SomeValue \n End Function -> convert to return statement
public override object Visit(ConstructorDeclaration constructorDeclaration, object data)
{

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

@ -197,10 +197,10 @@ @@ -197,10 +197,10 @@
<SubType>Form</SubType>
</Compile>
<Compile Include="Src\Gui\Dialogs\TipOfTheDay.cs">
<SubType>Form</SubType>
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Src\Gui\Dialogs\TreeViewOptions.cs">
<SubType>Form</SubType>
<SubType>Component</SubType>
</Compile>
<Compile Include="Src\Gui\Dialogs\ViewGPLDialog.cs">
<SubType>Form</SubType>
@ -652,7 +652,7 @@ @@ -652,7 +652,7 @@
<Compile Include="Src\Dom\Implementations\DefaultTypeParameter.cs" />
<Compile Include="Src\Dom\Implementations\ProxyReturnType.cs" />
<Compile Include="Src\Dom\Implementations\DefaultReturnType.cs" />
<Compile Include="Src\Dom\Implementations\LazyReturnType.cs" />
<Compile Include="Src\Dom\Implementations\GetClassReturnType.cs" />
<Compile Include="Src\Dom\Implementations\GenericReturnType.cs" />
<Compile Include="Src\Dom\Implementations\ArrayReturnType.cs" />
<Compile Include="Src\Dom\Implementations\SpecificReturnType.cs" />
@ -669,7 +669,10 @@ @@ -669,7 +669,10 @@
<Compile Include="Src\Services\ProjectService\ParseableFileContentEnumerator.cs" />
<Compile Include="Src\Services\ParserService\ParseProjectContent.cs" />
<Compile Include="Src\Services\ParserService\ReflectionProjectContent.cs" />
</ItemGroup>
<Compile Include="Src\Dom\Implementations\SearchClassReturnType.cs" />
<Compile Include="Src\TextEditor\Gui\Editor\CompletionWindow\AbstractCompletionDataProvider.cs" />
<Compile Include="Src\Dom\ExpressionContext.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Libraries\DockPanel_Src\WinFormsUI\WinFormsUI.csproj">
<Project>{D3C782BA-178E-4235-A3BA-8C11DEBB6BEE}</Project>

88
src/Main/Base/Project/Src/Dom/ExpressionContext.cs

@ -0,0 +1,88 @@ @@ -0,0 +1,88 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version value="$version"/>
// </file>
using System;
namespace ICSharpCode.SharpDevelop.Dom
{
/// <summary>
/// Class describing a contexts in which an expressions can be.
/// Serves as filter for code completion results.
/// </summary>
public abstract class ExpressionContext
{
public abstract bool ShowEntry(object o);
/// <summary>Default/unknown context</summary>
public static ExpressionContext Default = new DefaultExpressionContext();
/// <summary>Context expects a namespace name</summary>
/// <example>using *expr*;</example>
public static ExpressionContext Namespace = new NamespaceExpressionContext();
/// <summary>Context expects a type name</summary>
/// <example>typeof(*expr*), is *expr*, using(*expr* ...)</example>
public static ExpressionContext Type = new TypeExpressionContext(null, false);
/// <summary>Context expects a non-abstract type that has accessible constructors</summary>
/// <example>new *expr*();</example>
public static ExpressionContext ConstructableType = new TypeExpressionContext(null, true);
/// <summary>Context expects a type name which has special base type</summary>
/// <param name="baseClass">The class the expression must derive from.</param>
/// <param name="allowAbstract">Specifies whether classes must be constructable.</param>
/// <example>catch(*expr* ...), using(*expr* ...), throw new ***</example>
public static ExpressionContext TypeDerivingFrom(IClass baseClass, bool mustBeConstructable)
{
return new TypeExpressionContext(baseClass, mustBeConstructable);
}
class DefaultExpressionContext : ExpressionContext
{
public override bool ShowEntry(object o)
{
return true;
}
}
class NamespaceExpressionContext : ExpressionContext
{
public override bool ShowEntry(object o)
{
return o is string;
}
}
class TypeExpressionContext : ExpressionContext
{
IClass baseClass;
bool mustBeConstructable;
public TypeExpressionContext(IClass baseClass, bool mustBeConstructable)
{
this.baseClass = baseClass;
this.mustBeConstructable = mustBeConstructable;
}
public override bool ShowEntry(object o)
{
if (o is string)
return true;
IClass c = o as IClass;
if (c == null)
return false;
if (mustBeConstructable) {
if (c.IsAbstract || c.IsStatic) return false;
if (c.ClassType == ClassType.Enum) return false;
}
if (baseClass == null)
return true;
return c.IsTypeInInheritanceTree(baseClass);
}
}
}
}

21
src/Main/Base/Project/Src/Dom/IExpressionFinder.cs

@ -22,27 +22,6 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -22,27 +22,6 @@ namespace ICSharpCode.SharpDevelop.Dom
ExpressionResult FindFullExpression(string text, int offset);
}
/// <summary>
/// Enumeration for possible contexts in which expressions can be.
/// </summary>
public enum ExpressionContext
{
/// <summary>Default/unknown context</summary>
Default,
/// <summary>Context expects a type name</summary>
/// <example>typeof(*expr*), is *expr*, using(*expr* ...)</example>
Type,
/// <summary>Context expects a type deriving from exception</summary>
/// <example>catch(*expr*), throw new *expr*</example>
ExceptionType,
/// <summary>Context expects a non-abstract type that has accessible constructors</summary>
/// <example>new *expr*();</example>
ConstructableType,
/// <summary>Context expects a namespace name.</summary>
/// <example>using *expr*;</example>
Namespace,
}
/// <summary>
/// Structure containing the result of a call to an expression finder.
/// </summary>

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

@ -239,6 +239,10 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -239,6 +239,10 @@ namespace ICSharpCode.SharpDevelop.Dom
return CompareTo((IClass)o);
}
// TODO: Cache ClassInheritanceTree as it is called many times (for GetFields(), GetProperties() etc.)
// and it is expensive to execute SearchType so often.
// ReflectionClass should cache it forever; DefaultClass only as long as no new CompilationUnits
// are created.
public IEnumerable ClassInheritanceTree {
get {
return new ClassInheritanceEnumerator(this);

98
src/Main/Base/Project/Src/Dom/Implementations/GetClassReturnType.cs

@ -0,0 +1,98 @@ @@ -0,0 +1,98 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version value="$version"/>
// </file>
using System;
using System.Collections.Generic;
using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop.Dom
{
/// <summary>
/// The GetClassReturnType is used when the class should be resolved on demand, but the
/// full name is already known. Example: ReflectionReturnType
/// </summary>
public sealed class GetClassReturnType : ProxyReturnType
{
IProjectContent content;
string fullName;
string shortName;
public GetClassReturnType(IProjectContent content, string fullName)
{
this.content = content;
this.fullName = fullName;
int pos = fullName.LastIndexOf('.');
if (pos < 0)
shortName = fullName;
else
shortName = fullName.Substring(pos + 1);
}
public override bool IsDefaultReturnType {
get {
return true;
}
}
public override bool Equals(object o)
{
GetClassReturnType rt = o as GetClassReturnType;
if (rt == null) {
IReturnType rt2 = o as IReturnType;
if (rt2 != null && rt2.IsDefaultReturnType)
return rt2.FullyQualifiedName == fullName;
else
return false;
}
return fullName == rt.fullName;
}
public override int GetHashCode()
{
return content.GetHashCode() ^ fullName.GetHashCode();
}
// TODO: Cache BaseType until a new CompilationUnit is generated (static counter in ParserService)
public override IReturnType BaseType {
get {
IClass c = content.GetClass(fullName);
return (c != null) ? c.DefaultReturnType : null;
}
}
public override string FullyQualifiedName {
get {
return fullName;
}
}
public override string Name {
get {
return shortName;
}
}
public override string Namespace {
get {
IReturnType baseType = BaseType;
return (baseType != null) ? baseType.Namespace : fullName.Substring(0, fullName.LastIndexOf('.'));
}
}
public override string DotNetName {
get {
IReturnType baseType = BaseType;
return (baseType != null) ? baseType.DotNetName : fullName;
}
}
public override string ToString()
{
return String.Format("[GetClassReturnType: {0}]", fullName);
}
}
}

85
src/Main/Base/Project/Src/Dom/Implementations/LazyReturnType.cs → src/Main/Base/Project/Src/Dom/Implementations/SearchClassReturnType.cs

@ -11,90 +11,6 @@ using ICSharpCode.Core; @@ -11,90 +11,6 @@ using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop.Dom
{
/// <summary>
/// The GetClassReturnType is used when the class should be resolved on demand, but the
/// full name is already known. Example: ReflectionReturnType
/// </summary>
public sealed class GetClassReturnType : ProxyReturnType
{
IProjectContent content;
string fullName;
string shortName;
public GetClassReturnType(IProjectContent content, string fullName)
{
this.content = content;
this.fullName = fullName;
int pos = fullName.LastIndexOf('.');
if (pos < 0)
shortName = fullName;
else
shortName = fullName.Substring(pos + 1);
}
public override bool IsDefaultReturnType {
get {
return true;
}
}
public override bool Equals(object o)
{
GetClassReturnType rt = o as GetClassReturnType;
if (rt == null) {
IReturnType rt2 = o as IReturnType;
if (rt2 != null && rt2.IsDefaultReturnType)
return rt2.FullyQualifiedName == fullName;
else
return false;
}
return fullName == rt.fullName;
}
public override int GetHashCode()
{
return content.GetHashCode() ^ fullName.GetHashCode();
}
public override IReturnType BaseType {
get {
IClass c = content.GetClass(fullName);
return (c != null) ? c.DefaultReturnType : null;
}
}
public override string FullyQualifiedName {
get {
return fullName;
}
}
public override string Name {
get {
return shortName;
}
}
public override string Namespace {
get {
IReturnType baseType = BaseType;
return (baseType != null) ? baseType.Namespace : fullName.Substring(0, fullName.LastIndexOf('.'));
}
}
public override string DotNetName {
get {
IReturnType baseType = BaseType;
return (baseType != null) ? baseType.DotNetName : fullName;
}
}
public override string ToString()
{
return String.Format("[GetClassReturnType: {0}]", fullName);
}
}
/// <summary>
/// The SearchClassReturnType is used when only a part of the class name is known and the
/// type can only be resolved on demand (the ConvertVisitor uses SearchClassReturnType's).
@ -139,6 +55,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -139,6 +55,7 @@ namespace ICSharpCode.SharpDevelop.Dom
return declaringClass.GetHashCode() ^ name.GetHashCode();
}
// TODO: Cache BaseType until a new CompilationUnit is generated (static counter in ParserService)
public override IReturnType BaseType {
get {
IClass c = declaringClass.ProjectContent.SearchType(name, declaringClass, caretLine, caretColumn);

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

@ -751,11 +751,13 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -751,11 +751,13 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (callingMember != null)
inStatic = callingMember.IsStatic;
if (!inStatic) {
result.AddRange(callingClass.GetAccessibleMembers(callingClass, false));
if (callingClass != null) {
if (!inStatic) {
result.AddRange(callingClass.GetAccessibleMembers(callingClass, false));
}
result.AddRange(callingClass.GetAccessibleMembers(callingClass, true));
result.AddRange(callingClass.GetAccessibleTypes(callingClass));
}
result.AddRange(callingClass.GetAccessibleMembers(callingClass, true));
result.AddRange(callingClass.GetAccessibleTypes(callingClass));
foreach (KeyValuePair<string, List<LocalLookupVariable>> pair in lookupTableVisitor.Variables) {
if (pair.Value != null && pair.Value.Count > 0) {
foreach (LocalLookupVariable v in pair.Value) {

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

@ -13,7 +13,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -13,7 +13,7 @@ namespace ICSharpCode.SharpDevelop.Dom
public static class ReflectionReturnType
{
#region Primitive Types
static IReturnType @object, @int, @string, @bool, type, @void, array;
static IReturnType @object, @int, @string, @bool, type, @void, array, disposable, exception;
/// <summary>Gets a ReturnType describing System.Object.</summary>
public static IReturnType Object {
@ -78,6 +78,24 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -78,6 +78,24 @@ namespace ICSharpCode.SharpDevelop.Dom
return array;
}
}
/// <summary>Gets a ReturnType describing System.IDisposable.</summary>
public static IReturnType Disposable {
get {
if (disposable == null) {
disposable = CreatePrimitive(typeof(IDisposable));
}
return disposable;
}
}
/// <summary>Gets a ReturnType describing System.IDisposable.</summary>
public static IReturnType Exception {
get {
if (exception == null) {
exception = CreatePrimitive(typeof(Exception));
}
return exception;
}
}
/// <summary>
/// Create a primitive return type.

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

@ -21,10 +21,10 @@ namespace ICSharpCode.Core @@ -21,10 +21,10 @@ namespace ICSharpCode.Core
ICompilationUnit assemblyCompilationUnit = new DefaultCompilationUnit(this);
foreach (Type type in assembly.GetTypes()) {
if (!type.FullName.StartsWith("<") && type.IsPublic) {
foreach (Type type in assembly.GetExportedTypes()) {
//if (!type.FullName.StartsWith("<") && type.IsPublic) {
AddClassToNamespaceListInternal(new ReflectionClass(assemblyCompilationUnit, type, null));
}
//}
}
if (assembly == typeof(void).Assembly) {

44
src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs

@ -102,12 +102,23 @@ namespace ICSharpCode.Core @@ -102,12 +102,23 @@ namespace ICSharpCode.Core
int pos = -1;
IExpressionFinder expressionFinder = null;
while ((pos = lowerFileContent.IndexOf(lowerMemberName, pos + 1)) >= 0) {
if (pos > 0 && char.IsLetterOrDigit(fileContent, pos - 1)) {
continue; // memberName is not a whole word (a.SomeName cannot reference Name)
}
if (pos < fileContent.Length - lowerMemberName.Length - 1
&& char.IsLetterOrDigit(fileContent, pos + lowerMemberName.Length))
{
continue; // memberName is not a whole word (a.Name2 cannot reference Name)
}
if (expressionFinder == null) {
expressionFinder = ParserService.GetExpressionFinder(fileName);
}
string expr = expressionFinder.FindFullExpression(fileContent, pos + 1).Expression;
if (expr != null) {
Point position = GetPosition(fileContent, pos);
// TODO: Optimize by re-using the same resolver if multiple expressions were
// found in this file (the resolver should parse all methods at once)
ResolveResult rr = ParserService.Resolve(expr, position.Y, position.X, fileName, fileContent);
if (IsReferenceToMember(member, rr)) {
list.Add(new Reference(fileName, pos, lowerMemberName.Length, expr, rr));
@ -133,14 +144,39 @@ namespace ICSharpCode.Core @@ -133,14 +144,39 @@ namespace ICSharpCode.Core
static List<ProjectItem> GetPossibleFiles(IClass ownerClass, IMember member)
{
// TODO: Optimize when member is not public
List<ProjectItem> resultList = new List<ProjectItem>();
if (member.IsPrivate) {
string fileName = ownerClass.CompilationUnit.FileName;
foreach (IProject p in ProjectService.OpenSolution.Projects) {
foreach (ProjectItem item in p.Items) {
if (item.ItemType == ItemType.Compile) {
if (FileUtility.IsEqualFileName(fileName, item.FileName)) {
resultList.Add(item);
return resultList;
}
}
}
}
}
if (member.IsProtected) {
// TODO: Optimize when member is protected
}
bool internalOnly = member.IsInternal && !member.IsProtected;
foreach (IProject p in ProjectService.OpenSolution.Projects) {
IProjectContent pc = ParserService.GetProjectContent(p);
if (pc == null) continue;
if (pc != ownerClass.ProjectContent && !pc.HasReferenceTo(ownerClass.ProjectContent)) {
// unreferences project contents cannot reference the class
continue;
if (pc != ownerClass.ProjectContent) {
if (internalOnly) {
// internal = can be only referenced from same project content
continue;
}
if (!pc.HasReferenceTo(ownerClass.ProjectContent)) {
// unreferences project contents cannot reference the class
continue;
}
}
foreach (ProjectItem item in p.Items) {
if (item.ItemType == ItemType.Compile) {

2
src/Main/Base/Project/Src/TextEditor/Actions.cs

@ -36,7 +36,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Actions @@ -36,7 +36,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Actions
{
SharpDevelopTextAreaControl sdtac = (SharpDevelopTextAreaControl)services.MotherTextEditorControl;
sdtac.ShowCompletionWindow(sdtac.CreateCodeCompletionDataProvider(true), '\0');
sdtac.ShowCompletionWindow(new CtrlSpaceCompletionDataProvider(ExpressionContext.Default), '\0');
}
}

2
src/Main/Base/Project/Src/TextEditor/Gui/Editor/CodeCompletionBinding.cs

@ -103,7 +103,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -103,7 +103,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
}
case '.':
if (enableDotCompletion) {
editor.ShowCompletionWindow(editor.CreateCodeCompletionDataProvider(false), ch);
editor.ShowCompletionWindow(new CodeCompletionDataProvider(), ch);
return true;
} else {
return false;

136
src/Main/Base/Project/Src/TextEditor/Gui/Editor/CompletionWindow/AbstractCompletionDataProvider.cs

@ -0,0 +1,136 @@ @@ -0,0 +1,136 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version value="$version"/>
// </file>
using System;
using System.Drawing;
using System.Diagnostics;
using System.Windows.Forms;
using System.Reflection;
using System.Collections;
using System.Collections.Specialized;
using System.Xml;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Internal.Templates;
using ICSharpCode.TextEditor.Document;
using ICSharpCode.TextEditor;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.TextEditor.Gui.CompletionWindow;
namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
{
public abstract class AbstractCompletionDataProvider : ICompletionDataProvider
{
Hashtable insertedElements = new Hashtable();
Hashtable insertedPropertiesElements = new Hashtable();
Hashtable insertedEventElements = new Hashtable();
public ImageList ImageList {
get {
return ClassBrowserIconService.ImageList;
}
}
protected int caretLineNumber;
protected int caretColumn;
protected string fileName;
protected string preSelection = null;
public string PreSelection {
get {
return preSelection;
}
}
protected ArrayList completionData = null;
protected ExpressionContext context = ExpressionContext.Default;
public ICompletionData[] GenerateCompletionData(string fileName, TextArea textArea, char charTyped)
{
completionData = new ArrayList();
this.fileName = fileName;
IDocument document = textArea.Document;
// the parser works with 1 based coordinates
caretLineNumber = document.GetLineNumberForOffset(textArea.Caret.Offset) + 1;
caretColumn = textArea.Caret.Offset - document.GetLineSegment(caretLineNumber - 1).Offset + 1;
GenerateCompletionData(textArea, charTyped);
return (ICompletionData[])completionData.ToArray(typeof(ICompletionData));
}
protected string GetExpression(TextArea textArea)
{
IDocument document = textArea.Document;
IExpressionFinder expressionFinder = ParserService.GetExpressionFinder(fileName);
if (expressionFinder == null) {
return TextUtilities.GetExpressionBeforeOffset(textArea, textArea.Caret.Offset);
} else {
ExpressionResult er = expressionFinder.FindExpression(document.GetText(0, textArea.Caret.Offset), textArea.Caret.Offset - 1);
if (er.Context != ExpressionContext.Default)
context = er.Context;
return er.Expression;
}
}
protected abstract void GenerateCompletionData(TextArea textArea, char charTyped);
protected void AddResolveResults(ICollection list)
{
if (list == null) {
return;
}
completionData.Capacity += list.Count;
foreach (object o in list) {
if (context != null && !context.ShowEntry(o))
continue;
if (o is string) {
completionData.Add(new CodeCompletionData(o.ToString(), ClassBrowserIconService.NamespaceIndex));
} else if (o is IClass) {
completionData.Add(new CodeCompletionData((IClass)o));
} else if (o is IProperty) {
IProperty property = (IProperty)o;
if (property.Name != null && insertedPropertiesElements[property.Name] == null) {
completionData.Add(new CodeCompletionData(property));
insertedPropertiesElements[property.Name] = property;
}
} else if (o is IMethod) {
IMethod method = (IMethod)o;
if (method.Name != null &&!method.IsConstructor) {
CodeCompletionData ccd = new CodeCompletionData(method);
if (insertedElements[method.Name] == null) {
completionData.Add(ccd);
insertedElements[method.Name] = ccd;
} else {
CodeCompletionData oldMethod = (CodeCompletionData)insertedElements[method.Name];
++oldMethod.Overloads;
}
}
} else if (o is IField) {
completionData.Add(new CodeCompletionData((IField)o));
} else if (o is IEvent) {
IEvent e = (IEvent)o;
if (e.Name != null && insertedEventElements[e.Name] == null) {
completionData.Add(new CodeCompletionData(e));
insertedEventElements[e.Name] = e;
}
}
}
}
protected void AddResolveResults(ResolveResult results)
{
insertedElements.Clear();
insertedPropertiesElements.Clear();
insertedEventElements.Clear();
if (results != null) {
AddResolveResults(results.GetCompletionData(ParserService.CurrentProjectContent));
}
}
}
}

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

@ -26,154 +26,61 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -26,154 +26,61 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
/// <summary>
/// Data provider for code completion.
/// </summary>
public class CodeCompletionDataProvider : ICompletionDataProvider
public class CodeCompletionDataProvider : AbstractCompletionDataProvider
{
Hashtable insertedElements = new Hashtable();
Hashtable insertedPropertiesElements = new Hashtable();
Hashtable insertedEventElements = new Hashtable();
public ImageList ImageList {
get {
return ClassBrowserIconService.ImageList;
}
}
int caretLineNumber;
int caretColumn;
string fileName;
string preSelection = null;
public string PreSelection {
get {
return preSelection;
}
}
ArrayList completionData = null;
bool ctrlSpace;
ExpressionContext context;
public CodeCompletionDataProvider(bool ctrlSpace)
protected override void GenerateCompletionData(TextArea textArea, char charTyped)
{
this.ctrlSpace = ctrlSpace;
preSelection = null;
GenerateCompletionData(textArea, GetExpression(textArea));
}
public ICompletionData[] GenerateCompletionData(string fileName, TextArea textArea, char charTyped)
protected void GenerateCompletionData(TextArea textArea, string expression)
{
IDocument document = textArea.Document;
completionData = new ArrayList();
this.fileName = fileName;
// the parser works with 1 based coordinates
caretLineNumber = document.GetLineNumberForOffset(textArea.Caret.Offset) + 1;
caretColumn = textArea.Caret.Offset - document.GetLineSegment(caretLineNumber - 1).Offset + 1;
IExpressionFinder expressionFinder = ParserService.GetExpressionFinder(fileName);
string expression;
if (expressionFinder == null) {
expression = TextUtilities.GetExpressionBeforeOffset(textArea, textArea.Caret.Offset);
context = ExpressionContext.Default;
} else {
ExpressionResult er = expressionFinder.FindExpression(textArea.Document.GetText(0, textArea.Caret.Offset), textArea.Caret.Offset - 1);
expression = er.Expression;
context = er.Context;
}
ResolveResult results;
preSelection = null;
if (ctrlSpace) {
if (expression == null || expression.Length == 0) {
preSelection = "";
if (charTyped != '\0') {
preSelection = null;
}
AddResolveResults(ParserService.CtrlSpace(caretLineNumber, caretColumn, fileName, document.TextContent));
return (ICompletionData[])completionData.ToArray(typeof(ICompletionData));
}
int idx = expression.LastIndexOf('.');
if (idx > 0) {
preSelection = expression.Substring(idx + 1);
expression = expression.Substring(0, idx);
if (charTyped != '\0') {
preSelection = null;
}
} else {
preSelection = expression;
if (charTyped != '\0') {
preSelection = null;
}
AddResolveResults(ParserService.CtrlSpace(caretLineNumber, caretColumn, fileName, document.TextContent));
return (ICompletionData[])completionData.ToArray(typeof(ICompletionData));
}
}
//Console.WriteLine("Expression: >{0}<", expression);
if (expression == null || expression.Length == 0) {
return null;
return;
}
results = ParserService.Resolve(expression,
caretLineNumber,
caretColumn,
fileName,
document.TextContent);
AddResolveResults(results);
return (ICompletionData[])completionData.ToArray(typeof(ICompletionData));
AddResolveResults(ParserService.Resolve(expression,
caretLineNumber,
caretColumn,
fileName,
textArea.Document.TextContent));
}
void AddResolveResults(ICollection list)
}
public class CtrlSpaceCompletionDataProvider : CodeCompletionDataProvider
{
public CtrlSpaceCompletionDataProvider(ExpressionContext context)
{
if (list == null) {
return;
}
completionData.Capacity += list.Count;
foreach (object o in list) {
if (context == ExpressionContext.Namespace && !(o is string)) continue;
if (o is string) {
completionData.Add(new CodeCompletionData(o.ToString(), ClassBrowserIconService.NamespaceIndex));
} else if (o is IClass) {
completionData.Add(new CodeCompletionData((IClass)o));
} else if (o is IProperty) {
IProperty property = (IProperty)o;
if (property.Name != null && insertedPropertiesElements[property.Name] == null) {
completionData.Add(new CodeCompletionData(property));
insertedPropertiesElements[property.Name] = property;
}
} else if (o is IMethod) {
IMethod method = (IMethod)o;
if (method.Name != null &&!method.IsConstructor) {
CodeCompletionData ccd = new CodeCompletionData(method);
if (insertedElements[method.Name] == null) {
completionData.Add(ccd);
insertedElements[method.Name] = ccd;
} else {
CodeCompletionData oldMethod = (CodeCompletionData)insertedElements[method.Name];
++oldMethod.Overloads;
}
}
} else if (o is IField) {
completionData.Add(new CodeCompletionData((IField)o));
} else if (o is IEvent) {
IEvent e = (IEvent)o;
if (e.Name != null && insertedEventElements[e.Name] == null) {
completionData.Add(new CodeCompletionData(e));
insertedEventElements[e.Name] = e;
}
}
}
this.context = context;
}
void AddResolveResults(ResolveResult results)
protected override void GenerateCompletionData(TextArea textArea, char charTyped)
{
insertedElements.Clear();
insertedPropertiesElements.Clear();
insertedEventElements.Clear();
string expression = GetExpression(textArea);
preSelection = null;
if (expression == null || expression.Length == 0) {
preSelection = "";
if (charTyped != '\0') {
preSelection = null;
}
AddResolveResults(ParserService.CtrlSpace(caretLineNumber, caretColumn, fileName, textArea.Document.TextContent));
return;
}
if (results != null) {
AddResolveResults(results.GetCompletionData(ParserService.CurrentProjectContent));
int idx = expression.LastIndexOf('.');
if (idx > 0) {
preSelection = expression.Substring(idx + 1);
expression = expression.Substring(0, idx);
if (charTyped != '\0') {
preSelection = null;
}
GenerateCompletionData(textArea, expression);
} else {
preSelection = expression;
if (charTyped != '\0') {
preSelection = null;
}
AddResolveResults(ParserService.CtrlSpace(caretLineNumber, caretColumn, fileName, textArea.Document.TextContent));
}
}
}

6
src/Main/Base/Project/Src/TextEditor/Gui/Editor/SharpDevelopTextAreaControl.cs

@ -70,12 +70,6 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -70,12 +70,6 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
}
}
public virtual ICompletionDataProvider CreateCodeCompletionDataProvider(bool ctrlSpace)
{
//ivoko: please do not touch or discuss with me: we use another CCDP
return new CodeCompletionDataProvider(ctrlSpace);
}
protected override void InitializeTextAreaControl(TextAreaControl newControl)
{
base.InitializeTextAreaControl(newControl);

1
src/Main/Base/Test/ICSharpCode.SharpDevelop.Tests.csproj

@ -45,6 +45,7 @@ @@ -45,6 +45,7 @@
<Compile Include="ReflectionLayerTests.cs" />
<Compile Include="GenericResolverTests.cs" />
<Compile Include="InnerClassesResolverTests.cs" />
<Compile Include="RefactoringTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Project\ICSharpCode.SharpDevelop.csproj">

47
src/Main/Base/Test/InnerClassesResolverTests.cs

@ -25,6 +25,36 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -25,6 +25,36 @@ namespace ICSharpCode.SharpDevelop.Tests
}
#endregion
[Test]
public void SimpleInnerClass()
{
string program = @"class A {
void Test() {
}
class B { }
}
";
ResolveResult result = Resolve(program, "B", 3);
Assert.IsTrue(result is TypeResolveResult);
Assert.AreEqual("A.B", result.ResolvedType.FullyQualifiedName);
}
[Test]
public void ReflectionInnerClass()
{
string program = @"using System;
class A {
void Test() {
}
}
";
ResolveResult result = Resolve(program, "Environment.SpecialFolder", 3);
Assert.IsTrue(result is TypeResolveResult);
Assert.AreEqual("System.Environment.SpecialFolder", result.ResolvedType.FullyQualifiedName);
}
[Test]
public void OuterclassPrivateFieldResolveTest()
{
@ -53,5 +83,22 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -53,5 +83,22 @@ namespace ICSharpCode.SharpDevelop.Tests
}
Assert.Fail("private field not visible from inner class");
}
[Test]
public void InheritedInnerClass()
{
string program = @"class A {
class B { }
}
class C : A {
void Main() {
}
}
";
ResolveResult result = Resolve(program, "B", 6);
Assert.IsTrue(result is TypeResolveResult);
Assert.AreEqual("A.B", result.ResolvedType.FullyQualifiedName);
}
}
}

44
src/Main/Base/Test/RefactoringTests.cs

@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
using System;
using System.Collections;
using System.IO;
using NUnit.Framework;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver;
namespace ICSharpCode.SharpDevelop.Tests
{
[TestFixture]
public class RefactoringTests
{
const string code = @"using System;
abstract class BaseClass {
protected abstract void FirstMethod();
protected virtual void SecondMethod()
{
}
}
class DerivedClass : BaseClass
{
protected override void FirstMethod()
{
SecondMethod();
}
}
class SecondDerivedClass : DerivedClass
{
protected override void FirstMethod()
{
Console.Beep();
}
protected override void SecondMethod()
{
FirstMethod();
}
}
";
// TODO: Write unit tests for find references / find overrides / go to base class.
}
}

82
src/SharpDevelop.sln

@ -1,5 +1,35 @@ @@ -1,5 +1,35 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# SharpDevelop 2.0.0.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Main", "Main", "{5A3EBEBA-0560-41C1-966B-23F7D03A5486}"
ProjectSection(SolutionItems) = postProject
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Tests", "Main\Base\Test\ICSharpCode.SharpDevelop.Tests.csproj", "{4980B743-B32F-4aba-AABD-45E2CAD3568D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop", "Main\Base\Project\ICSharpCode.SharpDevelop.csproj", "{2748AD25-9C63-4E12-877B-4DCE96FBED54}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Core", "Main\Core\Project\ICSharpCode.Core.csproj", "{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StartUp", "Main\StartUp\Project\StartUp.csproj", "{1152B71B-3C05-4598-B20D-823B5D40559E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Core.Tests", "Main\Core\Test\ICSharpCode.Core.Tests.csproj", "{AD6FAA08-D6F5-4DBA-AF85-F4DA9F40C3B5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{9421EDF4-9769-4BE9-B5A6-C87DE221D73C}"
ProjectSection(SolutionItems) = postProject
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit.framework.dll", "Tools\NUnit\src\NUnitFramework\framework\nunit.framework.dll.csproj", "{83DD7E12-A705-4DBA-9D71-09C8973D9382}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit.core.dll", "Tools\NUnit\src\NUnitFramework\core\nunit.core.dll.csproj", "{EBD43A7F-AFCA-4281-BB53-5CDD91F966A3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinFormsUI", "Libraries\DockPanel_Src\WinFormsUI\WinFormsUI.csproj", "{D3C782BA-178E-4235-A3BA-8C11DEBB6BEE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.TextEditor", "Libraries\ICSharpCode.TextEditor\Project\ICSharpCode.TextEditor.csproj", "{2D18BE89-D210-49EB-A9DD-2246FBB3DF6D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactory", "Libraries\NRefactory\Project\NRefactory.csproj", "{3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit.extensions.dll", "Tools\NUnit\src\NUnitFramework\extensions\nunit.extensions.dll.csproj", "{98B10E98-003C-45A0-9587-119142E39986}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AddIns", "AddIns", "{14A277EE-7DF1-4529-B639-7D1EF334C1C5}"
ProjectSection(SolutionItems) = postProject
EndProjectSection
@ -48,36 +78,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StartPage", "AddIns\Misc\St @@ -48,36 +78,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StartPage", "AddIns\Misc\St
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddinScout", "AddIns\Misc\AddinScout\Project\AddinScout.csproj", "{4B8F0F98-8BE1-402B-AA8B-C8D548577B38}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{9421EDF4-9769-4BE9-B5A6-C87DE221D73C}"
ProjectSection(SolutionItems) = postProject
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit.framework.dll", "Tools\NUnit\src\NUnitFramework\framework\nunit.framework.dll.csproj", "{83DD7E12-A705-4DBA-9D71-09C8973D9382}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit.core.dll", "Tools\NUnit\src\NUnitFramework\core\nunit.core.dll.csproj", "{EBD43A7F-AFCA-4281-BB53-5CDD91F966A3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinFormsUI", "Libraries\DockPanel_Src\WinFormsUI\WinFormsUI.csproj", "{D3C782BA-178E-4235-A3BA-8C11DEBB6BEE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.TextEditor", "Libraries\ICSharpCode.TextEditor\Project\ICSharpCode.TextEditor.csproj", "{2D18BE89-D210-49EB-A9DD-2246FBB3DF6D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactory", "Libraries\NRefactory\Project\NRefactory.csproj", "{3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit.extensions.dll", "Tools\NUnit\src\NUnitFramework\extensions\nunit.extensions.dll.csproj", "{98B10E98-003C-45A0-9587-119142E39986}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Main", "Main", "{5A3EBEBA-0560-41C1-966B-23F7D03A5486}"
ProjectSection(SolutionItems) = postProject
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Tests", "Main\Base\Test\ICSharpCode.SharpDevelop.Tests.csproj", "{4980B743-B32F-4aba-AABD-45E2CAD3568D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop", "Main\Base\Project\ICSharpCode.SharpDevelop.csproj", "{2748AD25-9C63-4E12-877B-4DCE96FBED54}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Core", "Main\Core\Project\ICSharpCode.Core.csproj", "{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StartUp", "Main\StartUp\Project\StartUp.csproj", "{1152B71B-3C05-4598-B20D-823B5D40559E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Core.Tests", "Main\Core\Test\ICSharpCode.Core.Tests.csproj", "{AD6FAA08-D6F5-4DBA-AF85-F4DA9F40C3B5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -159,6 +159,17 @@ Global @@ -159,6 +159,17 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{AD6FAA08-D6F5-4DBA-AF85-F4DA9F40C3B5} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486}
{1152B71B-3C05-4598-B20D-823B5D40559E} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486}
{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486}
{2748AD25-9C63-4E12-877B-4DCE96FBED54} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486}
{4980B743-B32F-4aba-AABD-45E2CAD3568D} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486}
{98B10E98-003C-45A0-9587-119142E39986} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C}
{3A9AE6AA-BC07-4A2F-972C-581E3AE2F195} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C}
{2D18BE89-D210-49EB-A9DD-2246FBB3DF6D} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C}
{D3C782BA-178E-4235-A3BA-8C11DEBB6BEE} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C}
{EBD43A7F-AFCA-4281-BB53-5CDD91F966A3} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C}
{83DD7E12-A705-4DBA-9D71-09C8973D9382} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C}
{CE5B42B7-6E8C-4385-9E97-F4023FC16BF2} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5}
{FEB825FA-4AD8-425D-8E4A-B5A18EE1B81C} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5}
{4EA396ED-64AD-4AD0-A67A-AB363F3E0C79} = {14A277EE-7DF1-4529-B639-7D1EF334C1C5}
@ -177,16 +188,5 @@ Global @@ -177,16 +188,5 @@ Global
{B08385CD-F0CC-488C-B4F4-EEB34B6D2688} = {6604365C-C702-4C10-9BA8-637F1E3D4D0D}
{1D18D788-F7EE-4585-A23B-34DC8EC63CB8} = {6604365C-C702-4C10-9BA8-637F1E3D4D0D}
{EC06F96A-AEEC-49D6-B03D-AB87C6EB674C} = {6604365C-C702-4C10-9BA8-637F1E3D4D0D}
{98B10E98-003C-45A0-9587-119142E39986} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C}
{3A9AE6AA-BC07-4A2F-972C-581E3AE2F195} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C}
{2D18BE89-D210-49EB-A9DD-2246FBB3DF6D} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C}
{D3C782BA-178E-4235-A3BA-8C11DEBB6BEE} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C}
{EBD43A7F-AFCA-4281-BB53-5CDD91F966A3} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C}
{83DD7E12-A705-4DBA-9D71-09C8973D9382} = {9421EDF4-9769-4BE9-B5A6-C87DE221D73C}
{AD6FAA08-D6F5-4DBA-AF85-F4DA9F40C3B5} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486}
{1152B71B-3C05-4598-B20D-823B5D40559E} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486}
{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486}
{2748AD25-9C63-4E12-877B-4DCE96FBED54} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486}
{4980B743-B32F-4aba-AABD-45E2CAD3568D} = {5A3EBEBA-0560-41C1-966B-23F7D03A5486}
EndGlobalSection
EndGlobal

Loading…
Cancel
Save