1
- using System ;
2
- using System . Collections . Generic ;
1
+ using System . Collections . Generic ;
2
+ using System . IO ;
3
3
using System . Linq ;
4
4
using System . Runtime . InteropServices ;
5
- using System . Text ;
6
- using System . Threading . Tasks ;
7
5
using Rubberduck . Interaction ;
8
6
using Rubberduck . Parsing . ComReflection ;
9
- using Rubberduck . Parsing . Symbols ;
10
7
using Rubberduck . Resources ;
11
8
using Rubberduck . Settings ;
12
9
using Rubberduck . SettingsProvider ;
13
10
using Rubberduck . UI . AddRemoveReferences ;
14
11
using Rubberduck . VBEditor . SafeComWrappers . Abstract ;
15
- using Rubberduck . VBEditor . Utility ;
16
12
17
13
namespace Rubberduck . AddRemoveReferences
18
14
{
@@ -23,15 +19,16 @@ public interface IReferenceReconciler
23
19
ReferenceModel TryAddReference ( IVBProject project , string path ) ;
24
20
ReferenceModel TryAddReference ( IVBProject project , ReferenceModel reference ) ;
25
21
ReferenceModel GetLibraryInfoFromPath ( string path ) ;
22
+ void UpdateSettings ( IAddRemoveReferencesModel model , bool recent = false ) ;
26
23
}
27
24
28
25
public class ReferenceReconciler : IReferenceReconciler
29
26
{
30
27
private readonly IMessageBox _messageBox ;
31
- private readonly IConfigProvider < GeneralSettings > _settings ;
28
+ private readonly IConfigProvider < ReferenceSettings > _settings ;
32
29
private readonly IComLibraryProvider _tlbProvider ;
33
30
34
- public ReferenceReconciler ( IMessageBox messageBox , IConfigProvider < GeneralSettings > settings , IComLibraryProvider tlbProvider )
31
+ public ReferenceReconciler ( IMessageBox messageBox , IConfigProvider < ReferenceSettings > settings , IComLibraryProvider tlbProvider )
35
32
{
36
33
_messageBox = messageBox ;
37
34
_settings = settings ;
@@ -40,11 +37,22 @@ public ReferenceReconciler(IMessageBox messageBox, IConfigProvider<GeneralSettin
40
37
41
38
public void ReconcileReferences ( IAddRemoveReferencesModel model )
42
39
{
40
+ if ( model ? . NewReferences is null || ! model . NewReferences . Any ( ) )
41
+ {
42
+ return ;
43
+ }
44
+
43
45
ReconcileReferences ( model , model . NewReferences . ToList ( ) ) ;
44
46
}
45
47
48
+ //TODO test for simple adds.
46
49
public List < ReferenceModel > ReconcileReferences ( IAddRemoveReferencesModel model , List < ReferenceModel > allReferences )
47
50
{
51
+ if ( model is null || allReferences is null || ! allReferences . Any ( ) )
52
+ {
53
+ return new List < ReferenceModel > ( ) ;
54
+ }
55
+
48
56
var selected = allReferences . Where ( reference => ! reference . IsBuiltIn && reference . Priority . HasValue )
49
57
. ToDictionary ( reference => reference . FullPath ) ;
50
58
@@ -67,25 +75,38 @@ public List<ReferenceModel> ReconcileReferences(IAddRemoveReferencesModel model,
67
75
reference . Dispose ( ) ;
68
76
}
69
77
}
70
-
71
78
output . AddRange ( selected . Values . OrderBy ( selection => selection . Priority )
72
79
. Select ( reference => TryAddReference ( project , reference ) ) . Where ( added => added != null ) ) ;
73
80
}
74
81
82
+ UpdateSettings ( model , true ) ;
75
83
return output ;
76
84
}
77
85
86
+ private static readonly List < string > InterestingExtensions = new List < string > { ".olb" , ".tlb" , ".dll" , ".ocx" , ".exe" } ;
87
+
78
88
public ReferenceModel GetLibraryInfoFromPath ( string path )
79
89
{
80
90
try
81
91
{
82
- return new ReferenceModel ( _tlbProvider . LoadTypeLibrary ( path ) ) ;
92
+ var extension = Path . GetExtension ( path ) ? . ToLowerInvariant ( ) ?? string . Empty ;
93
+ if ( string . IsNullOrEmpty ( extension ) )
94
+ {
95
+ return null ;
96
+ }
97
+
98
+ // LoadTypeLibrary will attempt to open files in the host, so only attempt on possible COM servers.
99
+ if ( InterestingExtensions . Contains ( extension ) )
100
+ {
101
+ return new ReferenceModel ( _tlbProvider . LoadTypeLibrary ( path ) ) ;
102
+ }
103
+ return new ReferenceModel ( path ) ;
83
104
}
84
105
catch
85
106
{
86
- // Most likely this is a project . If not, it we can't fail here because it could have come from the Apply
107
+ // Most likely this is unloadable . If not, it we can't fail here because it could have come from the Apply
87
108
// button in the AddRemoveReferencesDialog. Wait for it... :-P
88
- return new ReferenceModel ( path ) ;
109
+ return new ReferenceModel ( path , true ) ;
89
110
}
90
111
}
91
112
@@ -97,7 +118,7 @@ public ReferenceModel TryAddReference(IVBProject project, string path)
97
118
{
98
119
using ( var reference = references . AddFromFile ( path ) )
99
120
{
100
- return reference is null ? null : new ReferenceModel ( reference , references . Count ) ;
121
+ return reference is null ? null : new ReferenceModel ( reference , references . Count ) { IsRecent = true } ;
101
122
}
102
123
}
103
124
catch ( COMException ex )
@@ -117,6 +138,7 @@ public ReferenceModel TryAddReference(IVBProject project, ReferenceModel referen
117
138
using ( references . AddFromFile ( reference . FullPath ) )
118
139
{
119
140
reference . Priority = references . Count ;
141
+ reference . IsRecent = true ;
120
142
return reference ;
121
143
}
122
144
}
@@ -127,5 +149,27 @@ public ReferenceModel TryAddReference(IVBProject project, ReferenceModel referen
127
149
return null ;
128
150
}
129
151
}
152
+
153
+ public void UpdateSettings ( IAddRemoveReferencesModel model , bool recent = false )
154
+ {
155
+ if ( model ? . Settings is null || model . References is null )
156
+ {
157
+ return ;
158
+ }
159
+
160
+ if ( recent )
161
+ {
162
+ model . Settings . UpdateRecentReferencesForHost ( model . HostApplication ,
163
+ model . References . Where ( reference => reference . IsReferenced && ! reference . IsBuiltIn )
164
+ . Select ( reference => reference . ToReferenceInfo ( ) ) . ToList ( ) ) ;
165
+
166
+ }
167
+
168
+ model . Settings . UpdatePinnedReferencesForHost ( model . HostApplication ,
169
+ model . References . Where ( reference => reference . IsPinned ) . Select ( reference => reference . ToReferenceInfo ( ) )
170
+ . ToList ( ) ) ;
171
+
172
+ _settings . Save ( model . Settings ) ;
173
+ }
130
174
}
131
175
}
0 commit comments