Skip to content

Commit 3aa5920

Browse files
author
Paul van Brenk
committed
More checks
1 parent 93baf47 commit 3aa5920

File tree

2 files changed

+112
-88
lines changed

2 files changed

+112
-88
lines changed

Nodejs/Product/Nodejs/SharedProject/CommonProjectNode.FileSystemChange.cs

Lines changed: 94 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,19 @@ internal abstract partial class CommonProjectNode
1414
/// Represents an individual change to the file system. We process these in bulk on the
1515
/// UI thread.
1616
/// </summary>
17-
[DebuggerDisplay("FileSystemChange: {isRename} {Type} {path}")]
17+
[DebuggerDisplay("FileSystemChange: {Type} {path}")]
1818
private sealed class FileSystemChange
1919
{
2020
private readonly CommonProjectNode project;
2121
private readonly string path;
22-
private readonly bool isRename;
2322

2423
public readonly WatcherChangeTypes Type;
2524

26-
public FileSystemChange(CommonProjectNode project, WatcherChangeTypes changeType, string path, bool isRename = false)
25+
public FileSystemChange(CommonProjectNode project, WatcherChangeTypes changeType, string path)
2726
{
2827
this.project = project;
2928
this.Type = changeType;
3029
this.path = path;
31-
this.isRename = isRename;
3230
}
3331

3432
private void RedrawIcon(HierarchyNode node)
@@ -50,12 +48,26 @@ public async Task ProcessChangeAsync()
5048
{
5149
child = this.project.FindNodeByFullPath(this.path + Path.DirectorySeparatorChar);
5250
}
51+
5352
switch (this.Type)
5453
{
5554
case WatcherChangeTypes.Deleted:
56-
ChildDeleted(child);
55+
if (child != null)
56+
{
57+
ChildDeleted(child);
58+
}
5759
break;
5860
case WatcherChangeTypes.Created:
61+
if (child != null)
62+
{
63+
// this child already exists redraw the icon
64+
this.project.ReDrawNode(child, UIHierarchyElement.Icon);
65+
}
66+
else
67+
{
68+
await ChildCreatedAsync(child);
69+
}
70+
break;
5971
case WatcherChangeTypes.Changed:
6072
// we only care about the attributes
6173
if (this.project.IsFileHidden(this.path))
@@ -68,9 +80,11 @@ public async Task ProcessChangeAsync()
6880
}
6981
else
7082
{
71-
// either a new or attributes have changed
72-
// add the file
73-
await ChildCreatedAsync(child);
83+
if (child == null)
84+
{
85+
// attributes must of changed from hidden, add the file
86+
await ChildCreatedAsync(null);
87+
}
7488
}
7589
break;
7690
}
@@ -96,110 +110,104 @@ private void RemoveAllFilesChildren(HierarchyNode parent)
96110

97111
private void ChildDeleted(HierarchyNode child)
98112
{
99-
if (child != null)
113+
if (child == null)
100114
{
101-
this.project.TryDeactivateSymLinkWatcher(child);
115+
throw new InvalidOperationException("Deleted, but child is null.");
116+
}
102117

103-
// rapid changes can arrive out of order, if the file or directory
104-
// actually exists ignore the event.
105-
if ((!File.Exists(child.Url) && !Directory.Exists(child.Url)) ||
106-
this.project.IsFileHidden(child.Url))
118+
this.project.TryDeactivateSymLinkWatcher(child);
119+
120+
// rapid changes can arrive out of order, if the file or directory
121+
// actually exists ignore the event.
122+
if ((!File.Exists(child.Url) && !Directory.Exists(child.Url)) ||
123+
this.project.IsFileHidden(child.Url))
124+
{
125+
if (child.ItemNode == null)
107126
{
108-
if (child.ItemNode == null)
109-
{
110-
// nodes should all have ItemNodes, the project is special.
111-
Debug.Assert(child is ProjectNode);
112-
return;
113-
}
127+
// nodes should all have ItemNodes, the project is special.
128+
Debug.Assert(child is ProjectNode);
129+
return;
130+
}
114131

115-
if (child.ItemNode.IsExcluded)
116-
{
117-
this.RemoveAllFilesChildren(child);
118-
// deleting a show all files item, remove the node.
119-
this.project.OnItemDeleted(child);
120-
child.Parent.RemoveChild(child);
121-
child.Close();
122-
}
123-
else
124-
{
125-
Debug.Assert(!child.IsNonMemberItem);
126-
// deleting an item in the project, fix the icon, also
127-
// fix the icon of all children which we may have not
128-
// received delete notifications for
129-
this.RedrawIcon(child);
130-
}
132+
if (child.ItemNode.IsExcluded)
133+
{
134+
this.RemoveAllFilesChildren(child);
135+
// deleting a show all files item, remove the node.
136+
this.project.OnItemDeleted(child);
137+
child.Parent.RemoveChild(child);
138+
child.Close();
139+
}
140+
else
141+
{
142+
Debug.Assert(!child.IsNonMemberItem);
143+
// deleting an item in the project, fix the icon, also
144+
// fix the icon of all children which we may have not
145+
// received delete notifications for
146+
this.RedrawIcon(child);
131147
}
132148
}
133149
}
134150

135151
private async Task ChildCreatedAsync(HierarchyNode child)
136152
{
137-
if (child != null)
153+
if (this.project.IsFileHidden(this.path))
138154
{
139-
// creating an item which was in the project, fix the icon.
140-
this.project.ReDrawNode(child, UIHierarchyElement.Icon);
155+
// don't add hidden files/folders
156+
return;
141157
}
142-
else
143-
{
144-
if (this.project.IsFileHidden(this.path))
145-
{
146-
// don't add hidden files/folders
147-
return;
148-
}
149158

150-
// creating a new item, need to create the on all files node
151-
var parent = this.project.GetParentFolderForPath(this.path);
159+
// creating a new item, need to create the on all files node
160+
var parent = this.project.GetParentFolderForPath(this.path);
152161

153-
if (parent == null)
154-
{
155-
// we've hit an error while adding too many files, the file system watcher
156-
// couldn't keep up. That's alright, we'll merge the files in correctly
157-
// in a little while...
158-
return;
159-
}
162+
if (parent == null)
163+
{
164+
// we've hit an error while adding too many files, the file system watcher
165+
// couldn't keep up. That's alright, we'll merge the files in correctly
166+
// in a little while...
167+
return;
168+
}
160169

161-
var wasExpanded = parent.GetIsExpanded();
170+
var wasExpanded = parent.GetIsExpanded();
162171

163-
if (Directory.Exists(this.path))
172+
if (Directory.Exists(this.path))
173+
{
174+
if (IsFileSymLink(this.path))
164175
{
165-
if (IsFileSymLink(this.path))
176+
var parentDir = CommonUtils.GetParent(this.path);
177+
if (IsRecursiveSymLink(parentDir, this.path))
166178
{
167-
var parentDir = CommonUtils.GetParent(this.path);
168-
if (IsRecursiveSymLink(parentDir, this.path))
169-
{
170-
// don't add recusrive sym link directory
171-
return;
172-
}
173-
174-
// otherwise we're going to need a new file system watcher
175-
this.project.CreateSymLinkWatcher(this.path);
179+
// don't add recusrive sym link directory
180+
return;
176181
}
177182

178-
var folderNode = this.project.AddAllFilesFolder(parent, this.path + Path.DirectorySeparatorChar);
179-
var folderNodeWasExpanded = folderNode.GetIsExpanded();
183+
// otherwise we're going to need a new file system watcher
184+
this.project.CreateSymLinkWatcher(this.path);
185+
}
180186

181-
// then add the folder nodes
182-
await this.project.MergeDiskNodesAsync(folderNode, this.path).ConfigureAwait(true);
187+
var folderNode = this.project.AddAllFilesFolder(parent, this.path + Path.DirectorySeparatorChar);
188+
var folderNodeWasExpanded = folderNode.GetIsExpanded();
183189

184-
// Assert we're back on the UI thread
185-
this.project.Site.GetUIThread().MustBeCalledFromUIThread();
186-
187-
this.project.OnInvalidateItems(folderNode);
190+
// then add the folder nodes
191+
await this.project.MergeDiskNodesAsync(folderNode, this.path).ConfigureAwait(true);
188192

189-
folderNode.ExpandItem(folderNodeWasExpanded ? EXPANDFLAGS.EXPF_ExpandFolder : EXPANDFLAGS.EXPF_CollapseFolder);
190-
}
191-
else if (File.Exists(this.path))
193+
// Assert we're back on the UI thread
194+
this.project.Site.GetUIThread().MustBeCalledFromUIThread();
195+
196+
this.project.OnInvalidateItems(folderNode);
197+
198+
folderNode.ExpandItem(folderNodeWasExpanded ? EXPANDFLAGS.EXPF_ExpandFolder : EXPANDFLAGS.EXPF_CollapseFolder);
199+
}
200+
else if (File.Exists(this.path))
201+
{
202+
// rapid changes can arrive out of order, make sure the file still exists
203+
this.project.AddAllFilesFile(parent, this.path);
204+
if (StringComparer.OrdinalIgnoreCase.Equals(this.project.GetStartupFile(), this.path))
192205
{
193-
// rapid changes can arrive out of order, make sure the file still exists
194-
this.project.AddAllFilesFile(parent, this.path);
195-
if (StringComparer.OrdinalIgnoreCase.Equals(this.project.GetStartupFile(), this.path))
196-
{
197-
this.project.BoldStartupItem();
198-
}
206+
this.project.BoldStartupItem();
199207
}
200-
201-
parent.ExpandItem(wasExpanded ? EXPANDFLAGS.EXPF_ExpandFolder : EXPANDFLAGS.EXPF_CollapseFolder);
202208
}
209+
210+
parent.ExpandItem(wasExpanded ? EXPANDFLAGS.EXPF_ExpandFolder : EXPANDFLAGS.EXPF_CollapseFolder);
203211
}
204212
}
205213
}

Nodejs/Product/Nodejs/SharedProject/HierarchyIdMap.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,28 @@ public void Remove(HierarchyNode node)
5757
{
5858
VisualStudio.Shell.ThreadHelper.ThrowIfNotOnUIThread();
5959

60+
if (node == null)
61+
{
62+
throw new ArgumentNullException(nameof(node));
63+
}
64+
6065
lock (this.theLock)
6166
{
6267
var i = (int)node.ID - 1;
63-
if (i < 0 || i >= this.ids.Count || (this.ids[i].TryGetTarget(out var found) && !object.ReferenceEquals(node, found)))
68+
if (0 > i || i >= this.ids.Count)
69+
{
70+
throw new InvalidOperationException($"Invalid id. {i}");
71+
}
72+
73+
var weakRef = this.ids[i];
74+
if (weakRef == null)
75+
{
76+
throw new InvalidOperationException("Trying to retrieve a node before adding.");
77+
}
78+
79+
if (weakRef.TryGetTarget(out var found) && !object.ReferenceEquals(node, found))
6480
{
65-
throw new InvalidOperationException("Removing node with invalid ID or map is corrupted");
81+
throw new InvalidOperationException("The node has the wrong id.");
6682
}
6783

6884
this.ids[i] = null;

0 commit comments

Comments
 (0)