Skip to content

Commit

Permalink
(cake-build#261) Add LiveTemplates for Frosting (cake-build#286)
Browse files Browse the repository at this point in the history
  • Loading branch information
nils-a authored Sep 30, 2022
1 parent 7f22a9e commit 5460d34
Show file tree
Hide file tree
Showing 39 changed files with 768 additions and 39 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,5 @@ obj/
!/src/projectTemplates/**/build
.vs/
*.user
/src/dotnet/packages/
/src/dotnet/test/packages/
1 change: 1 addition & 0 deletions src/dotnet/.idea/.idea.cake-rider/.idea/indexLayout.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion src/dotnet/.run/cake-rider_ Rider (Unix).run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
<option name="ADDITIONAL_IIS_EXPRESS_ARGUMENTS" value="" />
<method v="2">
<option name="Build" />
<option name="RunConfigurationTask" enabled="true" run_configuration_name="cake-rider: Rider - Frontend (Unix)" run_configuration_type="LaunchSettings" />
</method>
</configuration>
</component>
1 change: 0 additions & 1 deletion src/dotnet/.run/cake-rider_ Rider (Windows).run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
<option name="ADDITIONAL_IIS_EXPRESS_ARGUMENTS" value="" />
<method v="2">
<option name="Build" />
<option name="RunConfigurationTask" enabled="true" run_configuration_name="cake-rider: Rider - Frontend (Windows)" run_configuration_type="LaunchSettings" />
</method>
</configuration>
</component>
22 changes: 22 additions & 0 deletions src/dotnet/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project>
<PropertyGroup>
<DefineConstants>$(DefineConstants);RIDER</DefineConstants>
<IsPackable>false</IsPackable>
<NoWarn>MSB3277</NoWarn> <!-- Is this a good idea?? -->
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<DebugType>pdbonly</DebugType>
<!-- will be injected by gradle at build -->
<SdkVersion Condition="'$(SdkVersion)' == ''">2022.2.0</SdkVersion>
<WaveVersion>$(SdkVersion.Substring(2,2))$(SdkVersion.Substring(5,1)).0.0</WaveVersion>
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<DebugType>full</DebugType>
<DefineConstants>$(DefineConstants);TRACE;DEBUG;JET_MODE_ASSERT</DefineConstants>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
</ItemGroup>
</Project>
19 changes: 19 additions & 0 deletions src/dotnet/cake-rider.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ VisualStudioVersion = 15.0.26124.0
MinimumVisualStudioVersion = 15.0.26124.0
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "cake-rider", "cake-rider\cake-rider.csproj", "{3F26C70E-CBC1-4605-9133-D18E3CDD7D9E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "globals", "globals", "{F3E1CD98-594F-482C-8BA8-6DADCCBBE21F}"
ProjectSection(SolutionItems) = preProject
Directory.Build.props = Directory.Build.props
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "cake-rider.tests", "test\src\cake-rider.tests\cake-rider.tests.csproj", "{323866B5-58D6-4D0C-92D6-78FAA38BADCF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -30,5 +37,17 @@ Global
{3F26C70E-CBC1-4605-9133-D18E3CDD7D9E}.Release|x64.Build.0 = Release|Any CPU
{3F26C70E-CBC1-4605-9133-D18E3CDD7D9E}.Release|x86.ActiveCfg = Release|Any CPU
{3F26C70E-CBC1-4605-9133-D18E3CDD7D9E}.Release|x86.Build.0 = Release|Any CPU
{323866B5-58D6-4D0C-92D6-78FAA38BADCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{323866B5-58D6-4D0C-92D6-78FAA38BADCF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{323866B5-58D6-4D0C-92D6-78FAA38BADCF}.Debug|x64.ActiveCfg = Debug|Any CPU
{323866B5-58D6-4D0C-92D6-78FAA38BADCF}.Debug|x64.Build.0 = Debug|Any CPU
{323866B5-58D6-4D0C-92D6-78FAA38BADCF}.Debug|x86.ActiveCfg = Debug|Any CPU
{323866B5-58D6-4D0C-92D6-78FAA38BADCF}.Debug|x86.Build.0 = Debug|Any CPU
{323866B5-58D6-4D0C-92D6-78FAA38BADCF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{323866B5-58D6-4D0C-92D6-78FAA38BADCF}.Release|Any CPU.Build.0 = Release|Any CPU
{323866B5-58D6-4D0C-92D6-78FAA38BADCF}.Release|x64.ActiveCfg = Release|Any CPU
{323866B5-58D6-4D0C-92D6-78FAA38BADCF}.Release|x64.Build.0 = Release|Any CPU
{323866B5-58D6-4D0C-92D6-78FAA38BADCF}.Release|x86.ActiveCfg = Release|Any CPU
{323866B5-58D6-4D0C-92D6-78FAA38BADCF}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
50 changes: 39 additions & 11 deletions src/dotnet/cake-rider/CakeFrostingProjectsHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,17 @@
namespace net.cakebuild;

[SolutionComponent]
public class CakeFrostingProjectsHost
public class CakeFrostingProjectsHost : IDetectFrostingModules, ICakeFrostingProjectsHost
{
private static readonly AssemblyNameInfo CakeFrostingAssemblyName = AssemblyNameInfoFactory.Create2("Cake.Frosting", null);
private static readonly AssemblyNameInfo CakeFrostingAssemblyName =
AssemblyNameInfoFactory.Create2("Cake.Frosting", null);

private readonly ILogger _logger;
private readonly ISolution _solution;
private readonly CakeFrostingProjectsModel _model;
private readonly ISymbolCache _symbolCache;
private readonly ShellRdDispatcher _shellRdDispatcher;

private readonly Dictionary<IProjectMark, CakeFrostingProject> _cakeFrostingProjects =
new Dictionary<IProjectMark, CakeFrostingProject>();

Expand All @@ -42,19 +45,27 @@ public class CakeFrostingProjectsHost

private bool _isSolutionLoaded;

public CakeFrostingProjectsHost(ILogger logger, ISolution solution, ISymbolCache symbolCache, ShellRdDispatcher shellRdDispatcher, ISolutionLoadTasksScheduler solutionLoadTasksScheduler)
public CakeFrostingProjectsHost(
ILogger logger,
ISolution solution,
ISymbolCache symbolCache,
ShellRdDispatcher shellRdDispatcher,
ISolutionLoadTasksScheduler solutionLoadTasksScheduler)
{
_logger = logger;
_solution = solution;
_symbolCache = symbolCache;
_shellRdDispatcher = shellRdDispatcher;
_model = solution.GetProtocolSolution().GetCakeFrostingProjectsModel();

solutionLoadTasksScheduler.EnqueueTask(new SolutionLoadTask("Initialize cake projects", SolutionLoadTaskKinds.AfterDone, () =>
{
LoadAllTasks();
_isSolutionLoaded = true;
}));
solutionLoadTasksScheduler.EnqueueTask(new SolutionLoadTask(
"Initialize cake projects",
SolutionLoadTaskKinds.AfterDone,
() =>
{
LoadAllTasks();
_isSolutionLoaded = true;
}));
}

public void Refresh(IProjectMark projectMark)
Expand Down Expand Up @@ -148,11 +159,15 @@ public void ProcessTasks(ICSharpFile file, IDocument document)
});
}

private static bool IsCakeFrostingProject(IProject project)
public bool IsCakeFrostingProject(IProject project)
{
return !project.IsSharedProject()
&& project.ProjectProperties.ProjectKind == ProjectKind.REGULAR_PROJECT
&& ReferencedAssembliesService.IsProjectReferencingAssemblyByName(project, project.GetCurrentTargetFrameworkId(), CakeFrostingAssemblyName, out _);
&& ReferencedAssembliesService.IsProjectReferencingAssemblyByName(
project,
project.GetCurrentTargetFrameworkId(),
CakeFrostingAssemblyName,
out _);
}

private void ProjectRemoved(IProjectMark projectMark)
Expand All @@ -178,7 +193,8 @@ private void ProjectAdded(IProject project)

var cakeFrostingProject = new CakeFrostingProject();
cakeFrostingProject.Name.Set(project.Name);
cakeFrostingProject.ProjectFilePath.Set(project.ProjectFileLocation.NormalizeSeparators(FileSystemPathEx.SeparatorStyle.Unix));
cakeFrostingProject.ProjectFilePath.Set(
project.ProjectFileLocation.NormalizeSeparators(FileSystemPathEx.SeparatorStyle.Unix));
_model.Projects.Add(cakeFrostingProject);
_cakeFrostingProjects.Add(projectMark, cakeFrostingProject);
_cakeFrostingTasks.Add(projectMark, new Dictionary<IPsiSourceFile, HashSet<string>>());
Expand Down Expand Up @@ -215,3 +231,15 @@ private void LoadAllTasks()
}
}
}

public interface IDetectFrostingModules
{
bool IsCakeFrostingProject(IProject project);
}

public interface ICakeFrostingProjectsHost
{
void ProcessTasks(ICSharpFile file, IDocument document);

void Refresh(IProjectMark changeProjectMark);
}
2 changes: 2 additions & 0 deletions src/dotnet/cake-rider/CakeIcons.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ namespace net.cakebuild;
public static class CakeIcons
{
public static IconId CakeGutterMark { get; } = new FrontendIconId("icons/CakeIcon16.svg");

public static IconId CakeFile { get; } = new FrontendIconId("icons/CakeIcon16.svg");
}
11 changes: 8 additions & 3 deletions src/dotnet/cake-rider/CakePredefinedType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@ namespace net.cakebuild;

public class CakePredefinedType
{
public static readonly IClrTypeName IFrostingTaskFqn = new ClrTypeName("Cake.Frosting.IFrostingTask");

// ReSharper disable MemberCanBePrivate.Global
public static readonly IClrTypeName TaskNameAttributeFqn = new ClrTypeName("Cake.Frosting.TaskNameAttribute");

private static readonly Dictionary<IClrTypeName, int> PredefinedTypeNamesIndex = new Dictionary<IClrTypeName, int>();
// ReSharper disable once InconsistentNaming
public static readonly IClrTypeName IFrostingTaskFqn = new ClrTypeName("Cake.Frosting.IFrostingTask");

// ReSharper restore MemberCanBePrivate.Global
private static readonly Dictionary<IClrTypeName, int>
PredefinedTypeNamesIndex = new Dictionary<IClrTypeName, int>();

private readonly IPsiModule _module;

Expand All @@ -39,6 +43,7 @@ internal CakePredefinedType(IPsiModule module)
_module = module;
}

// ReSharper disable once InconsistentNaming
public IDeclaredType IFrostingTask => CreateType(IFrostingTaskFqn);

public IDeclaredType TaskNameAttribute => CreateType(TaskNameAttributeFqn);
Expand Down
2 changes: 1 addition & 1 deletion src/dotnet/cake-rider/CakeSolutionHostSyncListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public CakeSolutionHostSyncListener(ISolution solution)
_solution = solution;
}

private CakeFrostingProjectsHost Host => _solution.TryGetComponent<CakeFrostingProjectsHost>();
private ICakeFrostingProjectsHost Host => _solution.TryGetComponent<ICakeFrostingProjectsHost>();

public override void AfterUpdateProject(ProjectHostChange change) => Host?.Refresh(change.ProjectMark);

Expand Down
8 changes: 4 additions & 4 deletions src/dotnet/cake-rider/CakeTaskCollectorStage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ namespace net.cakebuild;
[DaemonStage(StagesAfter = new[] { typeof(FilteringHighlightingDaemonStage) })]
public sealed class CakeTaskCollectorStage : CSharpDaemonStageBase
{
private readonly CakeFrostingProjectsHost _host;
private readonly ICakeFrostingProjectsHost _host;

public CakeTaskCollectorStage(CakeFrostingProjectsHost host)
public CakeTaskCollectorStage(ICakeFrostingProjectsHost host)
{
_host = host;
}
Expand All @@ -35,9 +35,9 @@ protected override IDaemonStageProcess CreateProcess(IDaemonProcess process, ICo

public sealed class CakeTaskCollectorProcess : CSharpDaemonStageProcessBase
{
private readonly CakeFrostingProjectsHost _host;
private readonly ICakeFrostingProjectsHost _host;

public CakeTaskCollectorProcess([NotNull] IDaemonProcess process, [NotNull] ICSharpFile file, CakeFrostingProjectsHost host)
public CakeTaskCollectorProcess([NotNull] IDaemonProcess process, [NotNull] ICSharpFile file, ICakeFrostingProjectsHost host)
: base(process, file)
{
_host = host;
Expand Down
1 change: 1 addition & 0 deletions src/dotnet/cake-rider/FrostingTemplates/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
templates.generated.dotSettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.IO;
using System.Reflection;

using JetBrains.Application;
using JetBrains.Application.Settings;
using JetBrains.Diagnostics;
using JetBrains.Lifetimes;

namespace net.cakebuild.FrostingTemplates;

[ShellComponent]
public class FrostingTemplatesDefaultSettings : IHaveDefaultSettingsStream
{
public string Name => "Frosting default LiveTemplates";

public Stream GetDefaultSettingsStream(Lifetime lifetime)
{
var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("net.cakebuild.FrostingTemplates.templates.dotSettings");
Assertion.AssertNotNull(stream);
lifetime.AddDispose(stream);
return stream;
}
}
13 changes: 13 additions & 0 deletions src/dotnet/cake-rider/FrostingTemplates/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Templates

## All

### Live Templates

Shortcut | Description
---------|------------
[cake-async-task](Templates/cake-async-task.md) | Create a new async Cake task.
[cake-async-task-ctx](Templates/cake-async-task-ctx.md) | Create a new async Cake task with a custom build context
[cake-task](Templates/cake-task.md) | define a new Cake task
[cake-task-ctx](Templates/cake-task-ctx.md) | Create a new Cake task with a custom build context

Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System.Collections.Generic;

using JetBrains.Application;
using JetBrains.ProjectModel;
using JetBrains.ReSharper.Feature.Services.LiveTemplates.Context;
using JetBrains.ReSharper.Feature.Services.LiveTemplates.Scope;
using JetBrains.ReSharper.Psi;

using net.cakebuild.FrostingTemplates.Scopes;

namespace net.cakebuild.FrostingTemplates.ScopeProviders;

// Provides the scope points that are valid for the given context
[ShellComponent]
public class FrostingProjectScopeProvider : ScopeProvider
{
public FrostingProjectScopeProvider()
{
// Used when creating scope point from settings
Creators.Add(TryToCreate<InFrostingProject>);
}

public override IEnumerable<ITemplateScopePoint> ProvideScopePoints(TemplateAcceptanceContext context)
{
var sourceFile = context.SourceFile;

// Do not dispose IProject!
#pragma warning disable IDISP001
var project = sourceFile?.GetProject();
#pragma warning restore IDISP001
if (project == null)
{
// not a "real" SourceFile or not in a project.
yield break;
}

var solution = context.Solution;
var host = solution.GetComponent<IDetectFrostingModules>();
var isFrostingProject = host.IsCakeFrostingProject(project);
if (!isFrostingProject)
{
// Cake.Frosting is not referenced -> no Frosting project.
yield break;
}

// So, we've found Cake.Frosting
yield return new InFrostingProject();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System.Collections.Generic;

using JetBrains.ReSharper.Feature.Services.LiveTemplates.Scope;
using JetBrains.UI.Icons;

using net.cakebuild.FrostingTemplates.Scopes;

namespace net.cakebuild.FrostingTemplates.ScopeProviders;

// Defines a category for the UI, and the scope points that it includes
[ScopeCategoryUIProvider(Priority = Priority, ScopeFilter = ScopeFilter.Project)]
public class FrostingProjectScopeCategoryUiProvider : ScopeCategoryUIProvider
{
// Needs to be less than other priorities in R#'s built in ScopeCategoryUIProvider
// to push it to the end of the list
private const int Priority = -200;

public FrostingProjectScopeCategoryUiProvider()
{
// The main scope point is used to the UID of the QuickList for this category.
// It does nothing unless there is also a QuickList stored in settings.
MainPoint = new InFrostingProject();
}

public override string CategoryCaption => "Frosting";

public override IconId Icon => CakeIcons.CakeFile;

public override IEnumerable<ITemplateScopePoint> BuildAllPoints()
{
// Only Project-related scopes. (i.e. scopes used in File-Templates)
yield return new InFrostingProject();
}
}
Loading

0 comments on commit 5460d34

Please sign in to comment.