Skip to content

Commit 15e9fde

Browse files
Merge pull request #315 from reduckted/feature/known-physiscal-file-attributes
Allowed PhysicalFile attributes to be set using known attribute names
2 parents 1926a5d + 7d28ada commit 15e9fde

File tree

1 file changed

+141
-3
lines changed

1 file changed

+141
-3
lines changed

src/toolkit/Community.VisualStudio.Toolkit.Shared/Solution/PhysicalFile.cs

Lines changed: 141 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,22 @@ namespace Community.VisualStudio.Toolkit
1717
/// </summary>
1818
public class PhysicalFile : SolutionItem
1919
{
20+
private static readonly Dictionary<PhysicalFileAttribute, string> _knownFileAttributeNames = new()
21+
{
22+
{ PhysicalFileAttribute.BuildAction, "{ItemType}" },
23+
{ PhysicalFileAttribute.CopyToOutputDirectory, "CopyToOutputDirectory" },
24+
{ PhysicalFileAttribute.CustomToolNamespace, "CustomToolNamespace" },
25+
{ PhysicalFileAttribute.Generator, "Generator" },
26+
{ PhysicalFileAttribute.SubType, "SubType" },
27+
{ PhysicalFileAttribute.Visible, "Visible" },
28+
{ PhysicalFileAttribute.DependentUpon, "DependentUpon" },
29+
{ PhysicalFileAttribute.DesignTimeSharedInput, "DesignTimeSharedInput" },
30+
{ PhysicalFileAttribute.LastGenOutput, "LastGenOutput" },
31+
{ PhysicalFileAttribute.DesignTime, "DesignTime" },
32+
{ PhysicalFileAttribute.CustomTool, "CustomTool" },
33+
{ PhysicalFileAttribute.AutoGen, "AutoGen" }
34+
};
35+
2036
internal PhysicalFile(IVsHierarchyItem item, SolutionItemType type) : base(item, type)
2137
{ ThreadHelper.ThrowIfNotOnUIThread(); }
2238

@@ -86,12 +102,20 @@ public async Task<bool> TryRemoveAsync()
86102
/// Nests a file under this file by setting its <c>DependentUpon</c> property..
87103
/// </summary>
88104
public Task AddNestedFileAsync(PhysicalFile fileToNest)
89-
=> fileToNest.TrySetAttributeAsync("DependentUpon", Name);
105+
=> fileToNest.TrySetAttributeAsync(PhysicalFileAttribute.DependentUpon, Name);
106+
107+
/// <summary>
108+
/// Tries to set an attribute in the project file for the item.
109+
/// </summary>
110+
public Task<bool> TrySetAttributeAsync(PhysicalFileAttribute attribute, object value)
111+
{
112+
return TrySetAttributeAsync(_knownFileAttributeNames[attribute], value);
113+
}
90114

91115
/// <summary>
92116
/// Tries to set an attribute in the project file for the item.
93117
/// </summary>
94-
public async Task<bool> TrySetAttributeAsync(string name, string value)
118+
public async Task<bool> TrySetAttributeAsync(string name, object value)
95119
{
96120
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
97121

@@ -125,7 +149,7 @@ public async Task<bool> TrySetAttributeAsync(string name, string value)
125149
// Then write straight to project file
126150
else if (hierarchy is IVsBuildPropertyStorage storage)
127151
{
128-
ErrorHandler.ThrowOnFailure(storage.SetItemAttribute(itemId, name, value));
152+
ErrorHandler.ThrowOnFailure(storage.SetItemAttribute(itemId, name, value?.ToString()));
129153
return true;
130154
}
131155

@@ -198,4 +222,118 @@ public static async Task<IEnumerable<PhysicalFile>> FromFilesAsync(params string
198222
return items;
199223
}
200224
}
225+
226+
/// <summary>
227+
/// Known attributes of a <see cref="PhysicalFile"/>.
228+
/// This can be used to set an attribute of a file using the <see cref="PhysicalFile.TrySetAttributeAsync(PhysicalFileAttribute, string)"/> method.
229+
/// </summary>
230+
public enum PhysicalFileAttribute
231+
{
232+
/// <summary>
233+
/// Sets the <c>AutoGen</c> attribute.
234+
/// <para>
235+
/// Type: <see cref="string"/>
236+
/// </para>
237+
/// </summary>
238+
AutoGen,
239+
/// <summary>
240+
/// How the file relates to the build and deployment processes.
241+
/// <para>
242+
/// Type: <see cref="string"/>
243+
/// </para>
244+
/// </summary>
245+
BuildAction,
246+
/// <summary>
247+
/// Specifies the source file will be copied to the output directory.
248+
/// <para>
249+
/// Type: <see cref="CopyToOutputDirectory"/>
250+
/// </para>
251+
/// </summary>
252+
CopyToOutputDirectory,
253+
/// <summary>
254+
/// The name of the single-file generator.
255+
/// <para>
256+
/// Type: <see cref="string"/>
257+
/// </para>
258+
/// </summary>
259+
CustomTool,
260+
/// <summary>
261+
/// The namespace into which the output of the custom tool is placed.
262+
/// <para>
263+
/// Type: <see cref="string"/>
264+
/// </para>
265+
/// </summary>
266+
CustomToolNamespace,
267+
/// <summary>
268+
/// The other file that this file is dependent upon.
269+
/// <para>
270+
/// Type: <see cref="string"/>
271+
/// </para>
272+
/// </summary>
273+
DependentUpon,
274+
/// <summary>
275+
/// Sets the <c>DesignTime</c> attribute.
276+
/// <para>
277+
/// Type: <see cref="string"/>
278+
/// </para>
279+
/// </summary>
280+
DesignTime,
281+
/// <summary>
282+
/// Sets the <c>DesignTimeSharedInput</c> attribute.
283+
/// <para>
284+
/// Type: <see cref="bool"/>
285+
/// </para>
286+
/// </summary>
287+
DesignTimeSharedInput,
288+
/// <summary>
289+
/// Specifies the tool that transforms a file at design time and places the output of that transformation into another file. For example, a dataset (.xsd) file comes with a default custom tool.
290+
/// <para>
291+
/// Type: <see cref="string"/>
292+
/// </para>
293+
/// </summary>
294+
Generator,
295+
/// <summary>
296+
/// Sets the <c>LastGenOutput</c> attribute.
297+
/// <para>
298+
/// Type: <see cref="string"/>
299+
/// </para>
300+
/// </summary>
301+
LastGenOutput,
302+
/// <summary>
303+
/// File sub-type.
304+
/// <para>
305+
/// Type: <see cref="string"/>
306+
/// </para>
307+
/// </summary>
308+
SubType,
309+
/// <summary>
310+
/// Whether to show the file in Solution Explorer.
311+
/// <para>
312+
/// Type: <see cref="bool"/>
313+
/// </para>
314+
/// </summary>
315+
Visible
316+
}
317+
318+
/// <summary>
319+
/// Defines whether a file will be copied to the build's output directory.
320+
/// </summary>
321+
/// <remarks>
322+
/// Equivalent to the <c>Microsoft.VisualStudio.ProjectFlavoring.CopyToOutputDirectory</c> enum.
323+
/// </remarks>
324+
public enum CopyToOutputDirectory
325+
{
326+
/// <summary>
327+
/// The file will never be copied.
328+
/// </summary>
329+
DoNotCopy,
330+
/// <summary>
331+
/// The file will always be copied.
332+
/// </summary>
333+
Always,
334+
/// <summary>
335+
/// The file will be copied, but only if it is newer that the file that is already in the build's output directory.
336+
/// </summary>
337+
PreserveNewest
338+
}
201339
}

0 commit comments

Comments
 (0)