Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: obsolete/Microsoft.VisualStudio.Project/AssemblyReferenceNode.cs

Issue 10928195: First round of dead file removal (Closed) Base URL: https://github.com/samclegg/nativeclient-sdk.git@master
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /// Copyright (c) Microsoft Corporation. All rights reserved.
2
3 using System;
4 using System.Collections;
5 using System.Diagnostics;
6 using System.IO;
7 using System.Reflection;
8 using System.Runtime.InteropServices;
9 using Microsoft.VisualStudio;
10 using Microsoft.VisualStudio.Shell;
11 using Microsoft.VisualStudio.Shell.Interop;
12 using MSBuild = Microsoft.Build.BuildEngine;
13
14 namespace Microsoft.VisualStudio.Project
15 {
16 [CLSCompliant(false)]
17 [ComVisible(true)]
18 public class AssemblyReferenceNode : ReferenceNode
19 {
20 #region fieds
21 /// <summary>
22 /// The name of the assembly this refernce represents
23 /// </summary>
24 private System.Reflection.AssemblyName assemblyName;
25 private AssemblyName resolvedAssemblyName;
26
27 private string assemblyPath = String.Empty;
28
29 /// <summary>
30 /// Defines the listener that would listen on file changes on th e nested project node.
31 /// </summary>
32 private FileChangeManager fileChangeListener;
33
34 /// <summary>
35 /// A flag for specifying if the object was disposed.
36 /// </summary>
37 private bool isDisposed;
38 #endregion
39
40 #region properties
41 /// <summary>
42 /// The name of the assembly this reference represents.
43 /// </summary>
44 /// <value></value>
45 internal System.Reflection.AssemblyName AssemblyName
46 {
47 get
48 {
49 return this.assemblyName;
50 }
51 }
52
53 /// <summary>
54 /// Returns the name of the assembly this reference refers to on this specific
55 /// machine. It can be different from the AssemblyName property because it can
56 /// be more specific.
57 /// </summary>
58 internal System.Reflection.AssemblyName ResolvedAssembly
59 {
60 get { return resolvedAssemblyName; }
61 }
62
63 public override string Url
64 {
65 get
66 {
67 return this.assemblyPath;
68 }
69 }
70
71 public override string Caption
72 {
73 get
74 {
75 return this.assemblyName.Name;
76 }
77 }
78
79 private Automation.OAAssemblyReference assemblyRef;
80 internal override object Object
81 {
82 get
83 {
84 if(null == assemblyRef)
85 {
86 assemblyRef = new Automation.OAAssemblyR eference(this);
87 }
88 return assemblyRef;
89 }
90 }
91 #endregion
92
93 #region ctors
94 /// <summary>
95 /// Constructor for the ReferenceNode
96 /// </summary>
97 public AssemblyReferenceNode(ProjectNode root, ProjectElement el ement)
98 : base(root, element)
99 {
100 this.GetPathNameFromProjectFile();
101
102 this.InitializeFileChangeEvents();
103
104 string include = this.ItemNode.GetMetadata(ProjectFileCo nstants.Include);
105
106 this.CreateFromAssemblyName(new System.Reflection.Assemb lyName(include));
107 }
108
109 /// <summary>
110 /// Constructor for the AssemblyReferenceNode
111 /// </summary>
112 public AssemblyReferenceNode(ProjectNode root, string assemblyPa th)
113 : base(root)
114 {
115 // Validate the input parameters.
116 if(null == root)
117 {
118 throw new ArgumentNullException("root");
119 }
120 if(string.IsNullOrEmpty(assemblyPath))
121 {
122 throw new ArgumentNullException("assemblyPath");
123 }
124
125 this.InitializeFileChangeEvents();
126
127 // The assemblyPath variable can be an actual path on di sk or a generic assembly name.
128 if(File.Exists(assemblyPath))
129 {
130 // The assemblyPath parameter is an actual file on disk; try to load it.
131 this.assemblyName = System.Reflection.AssemblyNa me.GetAssemblyName(assemblyPath);
132 this.assemblyPath = assemblyPath;
133
134 // We register with listeningto chnages onteh pa th here. The rest of teh cases will call into resolving the assembly and registr ation is done there.
135 this.fileChangeListener.ObserveItem(this.assembl yPath);
136 }
137 else
138 {
139 // The file does not exist on disk. This can be because the file / path is not
140 // correct or because this is not a path, but an assembly name.
141 // Try to resolve the reference as an assembly n ame.
142 this.CreateFromAssemblyName(new System.Reflectio n.AssemblyName(assemblyPath));
143 }
144 }
145 #endregion
146
147 #region methods
148 /// <summary>
149 /// Closes the node.
150 /// </summary>
151 /// <returns></returns>
152 public override int Close()
153 {
154 try
155 {
156 this.Dispose(true);
157 }
158 finally
159 {
160 base.Close();
161 }
162
163 return VSConstants.S_OK;
164 }
165
166 /// <summary>
167 /// Links a reference node to the project and hierarchy.
168 /// </summary>
169 protected override void BindReferenceData()
170 {
171 Debug.Assert(this.assemblyName != null, "The AssemblyNam e field has not been initialized");
172
173 // If the item has not been set correctly like in case o f a new reference added it now.
174 // The constructor for the AssemblyReference node will c reate a default project item. In that case the Item is null.
175 // We need to specify here the correct project element.
176 if(this.ItemNode == null || this.ItemNode.Item == null)
177 {
178 this.ItemNode = new ProjectElement(this.ProjectM gr, this.assemblyName.FullName, ProjectFileConstants.Reference);
179 }
180
181 // Set the basic information we know about
182 this.ItemNode.SetMetadata(ProjectFileConstants.Name, thi s.assemblyName.Name);
183 this.ItemNode.SetMetadata(ProjectFileConstants.AssemblyN ame, Path.GetFileName(this.assemblyPath));
184
185 this.SetReferenceProperties();
186 }
187
188 /// <summary>
189 /// Disposes the node
190 /// </summary>
191 /// <param name="disposing"></param>
192 protected override void Dispose(bool disposing)
193 {
194 if(this.isDisposed)
195 {
196 return;
197 }
198
199 try
200 {
201 this.UnregisterFromFileChangeService();
202 }
203 finally
204 {
205 base.Dispose(disposing);
206 this.isDisposed = true;
207 }
208 }
209
210 private void CreateFromAssemblyName(AssemblyName name)
211 {
212 this.assemblyName = name;
213
214 // Use MsBuild to resolve the assemblyname
215 this.ResolveAssemblyReference();
216
217 if(String.IsNullOrEmpty(this.assemblyPath) && (null != t his.ItemNode.Item))
218 {
219 // Try to get the assmbly name from the hintpath .
220 this.GetPathNameFromProjectFile();
221 if(this.assemblyPath == null)
222 {
223 // Try to get the assembly name from the path
224 this.assemblyName = System.Reflection.As semblyName.GetAssemblyName(this.assemblyPath);
225 }
226 }
227 if(null == resolvedAssemblyName)
228 {
229 resolvedAssemblyName = assemblyName;
230 }
231 }
232
233 /// <summary>
234 /// Checks if an assembly is already added. The method parses al l references and compares the full assemblynames, or the location of the assembl ies to decide whether two assemblies are the same.
235 /// </summary>
236 /// <returns>true if the assembly has already been added.</retur ns>
237 protected override bool IsAlreadyAdded()
238 {
239 ReferenceContainerNode referencesFolder = this.ProjectMg r.FindChild(ReferenceContainerNode.ReferencesNodeVirtualName) as ReferenceContai nerNode;
240 Debug.Assert(referencesFolder != null, "Could not find t he References node");
241 bool shouldCheckPath = !string.IsNullOrEmpty(this.Url);
242
243 for(HierarchyNode n = referencesFolder.FirstChild; n != null; n = n.NextSibling)
244 {
245 AssemblyReferenceNode assemblyRefererenceNode = n as AssemblyReferenceNode;
246 if(null != assemblyRefererenceNode)
247 {
248 // We will check if the full assemblynam es are the same or if the Url of the assemblies is the same.
249 if(String.Compare(assemblyRefererenceNod e.AssemblyName.FullName, this.assemblyName.FullName, StringComparison.OrdinalIgn oreCase) == 0 ||
250 (shouldCheckPath && NativeMethod s.IsSamePath(assemblyRefererenceNode.Url, this.Url)))
251 {
252 return true;
253 }
254 }
255 }
256
257 return false;
258 }
259
260 /// <summary>
261 /// Determines if this is node a valid node for painting the def ault reference icon.
262 /// </summary>
263 /// <returns></returns>
264 protected override bool CanShowDefaultIcon()
265 {
266 if(String.IsNullOrEmpty(this.assemblyPath) || !File.Exis ts(this.assemblyPath) || !this.ProjectMgr.HasPassedSecurityChecks)
267 {
268 return false;
269 }
270
271 return true;
272 }
273
274 private void GetPathNameFromProjectFile()
275 {
276 string result = this.ItemNode.GetMetadata(ProjectFileCon stants.HintPath);
277 if(String.IsNullOrEmpty(result))
278 {
279 result = this.ItemNode.GetMetadata(ProjectFileCo nstants.AssemblyName);
280 if(String.IsNullOrEmpty(result))
281 {
282 this.assemblyPath = String.Empty;
283 }
284 else if(!result.EndsWith(".dll", StringCompariso n.OrdinalIgnoreCase))
285 {
286 result += ".dll";
287 this.assemblyPath = result;
288 }
289 }
290 else
291 {
292 this.assemblyPath = this.GetFullPathFromPath(res ult);
293 }
294 }
295
296 private string GetFullPathFromPath(string path)
297 {
298 if(Path.IsPathRooted(path))
299 {
300 return path;
301 }
302 else
303 {
304 Uri uri = new Uri(this.ProjectMgr.BaseURI.Uri, p ath);
305
306 if(uri != null)
307 {
308 return Microsoft.VisualStudio.Shell.Url. Unescape(uri.LocalPath, true);
309 }
310 }
311
312 return String.Empty;
313 }
314
315 protected override void ResolveReference()
316 {
317 this.ResolveAssemblyReference();
318 }
319
320 private void SetHintPathAndPrivateValue()
321 {
322
323 // Private means local copy; we want to know if it is al ready set to not override the default
324 string privateValue = this.ItemNode.GetMetadata(ProjectF ileConstants.Private);
325
326 // Get the list of items which require HintPath
327 Microsoft.Build.BuildEngine.BuildItemGroup references = this.ProjectMgr.BuildProject.GetEvaluatedItemsByName(MsBuildGeneratedItemType.Re ferenceCopyLocalPaths);
328
329 // Remove the HintPath, we will re-add it below if it is needed
330 if(!String.IsNullOrEmpty(this.assemblyPath))
331 {
332 this.ItemNode.SetMetadata(ProjectFileConstants.H intPath, null);
333 }
334
335 // Now loop through the generated References to find the corresponding one
336 foreach(Microsoft.Build.BuildEngine.BuildItem reference in references)
337 {
338 string fileName = Path.GetFileNameWithoutExtensi on(reference.FinalItemSpec);
339 if(String.Compare(fileName, this.assemblyName.Na me, StringComparison.OrdinalIgnoreCase) == 0)
340 {
341 // We found it, now set some properties based on this.
342
343 string hintPath = reference.GetMetadata( ProjectFileConstants.HintPath);
344 if(!String.IsNullOrEmpty(hintPath))
345 {
346 if(Path.IsPathRooted(hintPath))
347 {
348 hintPath = PackageUtilit ies.GetPathDistance(this.ProjectMgr.BaseURI.Uri, new Uri(hintPath));
349 }
350
351 this.ItemNode.SetMetadata(Projec tFileConstants.HintPath, hintPath);
352 // If this is not already set, w e default to true
353 if(String.IsNullOrEmpty(privateV alue))
354 {
355 this.ItemNode.SetMetadat a(ProjectFileConstants.Private, true.ToString());
356 }
357 }
358 break;
359 }
360
361 }
362
363 }
364
365 /// <summary>
366 /// This function ensures that some properies of the reference a re set.
367 /// </summary>
368 private void SetReferenceProperties()
369 {
370 // Set a default HintPath for msbuild to be able to reso lve the reference.
371 this.ItemNode.SetMetadata(ProjectFileConstants.HintPath, this.assemblyPath);
372
373 // Resolve assembly referernces. This is needed to make sure that properties like the full path
374 // to the assembly or the hint path are set.
375 if(this.ProjectMgr.Build(MsBuildTarget.ResolveAssemblyRe ferences) != MSBuildResult.Successful)
376 {
377 return;
378 }
379
380 // Check if we have to resolve again the path to the ass embly.
381 if(string.IsNullOrEmpty(this.assemblyPath))
382 {
383 ResolveReference();
384 }
385
386 // Make sure that the hint path if set (if needed).
387 SetHintPathAndPrivateValue();
388 }
389
390 /// <summary>
391 /// Does the actual job of resolving an assembly reference. We n eed a private method that does not violate
392 /// calling virtual method from the constructor.
393 /// </summary>
394 private void ResolveAssemblyReference()
395 {
396 if(this.ProjectMgr == null || this.ProjectMgr.IsClosed | | !this.ProjectMgr.HasPassedSecurityChecks)
397 {
398 return;
399 }
400
401 MSBuild.BuildItemGroup group = this.ProjectMgr.BuildProj ect.GetEvaluatedItemsByName(ProjectFileConstants.ReferencePath);
402 if(group != null)
403 {
404 IEnumerator enumerator = group.GetEnumerator();
405
406 while(enumerator.MoveNext())
407 {
408 MSBuild.BuildItem item = (MSBuild.BuildI tem)enumerator.Current;
409
410 string fullPath = this.GetFullPathFromPa th(item.FinalItemSpec);
411
412 System.Reflection.AssemblyName name = Sy stem.Reflection.AssemblyName.GetAssemblyName(fullPath);
413
414 // Try with full assembly name and then with weak assembly name.
415 if(String.Compare(name.FullName, this.as semblyName.FullName, StringComparison.OrdinalIgnoreCase) == 0 || String.Compare( name.Name, this.assemblyName.Name, StringComparison.OrdinalIgnoreCase) == 0)
416 {
417 if(!NativeMethods.IsSamePath(ful lPath, this.assemblyPath))
418 {
419 // set the full path now .
420 this.assemblyPath = full Path;
421
422 // We have a new item to listen too, since the assembly reference is resolved from a different place.
423 this.fileChangeListener. ObserveItem(this.assemblyPath);
424 }
425
426 this.resolvedAssemblyName = name ;
427
428 // No hint path is needed since the assembly path will always be resolved.
429 return;
430 }
431 }
432 }
433 }
434
435 /// <summary>
436 /// Registers with File change events
437 /// </summary>
438 private void InitializeFileChangeEvents()
439 {
440 this.fileChangeListener = new FileChangeManager(this.Pro jectMgr.Site);
441 this.fileChangeListener.FileChangedOnDisk += this.OnAsse mblyReferenceChangedOnDisk;
442 }
443
444 /// <summary>
445 /// Unregisters this node from file change notifications.
446 /// </summary>
447 private void UnregisterFromFileChangeService()
448 {
449 this.fileChangeListener.FileChangedOnDisk -= this.OnAsse mblyReferenceChangedOnDisk;
450 this.fileChangeListener.Dispose();
451 }
452
453 /// <summary>
454 /// Event callback. Called when one of the assembly file is chan ged.
455 /// </summary>
456 /// <param name="sender">The FileChangeManager object.</param>
457 /// <param name="e">Event args containing the file name that was updated.</param>
458 private void OnAssemblyReferenceChangedOnDisk(object sender, Fil eChangedOnDiskEventArgs e)
459 {
460 Debug.Assert(e != null, "No event args specified for the FileChangedOnDisk event");
461
462 // We only care about file deletes, so check for one bef ore enumerating references.
463 if((e.FileChangeFlag & _VSFILECHANGEFLAGS.VSFILECHG_Del) == 0)
464 {
465 return;
466 }
467
468
469 if(NativeMethods.IsSamePath(e.FileName, this.assemblyPat h))
470 {
471 this.OnInvalidateItems(this.Parent);
472 }
473 }
474 #endregion
475 }
476 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698