Skip to content

Commit

Permalink
2024.1 (#44)
Browse files Browse the repository at this point in the history
Add support for Rider 2024.1
  • Loading branch information
Garethp authored May 10, 2024
1 parent 9c00833 commit 816f5e6
Show file tree
Hide file tree
Showing 33 changed files with 912 additions and 293 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## 2024.1
* Built for 2024.1
* Adding defName auto-completion in C# for DefDatabase and `[DefOf]`
* When defining a RunConfig, you can now select a ModList config and Save file to be loaded for just this one launch
* Added support for `[LoadAlias]`
* New Mod Template now adds a PublisherPlus configuration file

## 2023.4
* Added support for Custom Def Classes
* Implemented XML Def Find Usages, so you can just Right-Click a defName and see all usages of that def in XML
Expand Down
28 changes: 21 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,32 @@ into the definitions on which the XML sits.

## Features so far

* Enjoy autocompletion of DefTypes and their properties
* Ctrl+Click into a tag in order to view the Class or Property that the tag is referring to
* Autocomplete from classes defined in `Class=""` attributes, such as for comps.
* When referring to other XML Defs (such as `<thought>ThoughtDefName</thought>`), auto complete and link to that defs XML
* Autocomplete certain values for properties with fixed options (Such as Altitude Layer, boolean and directions)
* A Rimworld Run Configuration with a Debug option
* Autocompletion for Defs
* Autocomplete the DefTypes available
* Autocomplete the properties available for a given DefType
* Autocomplete the available DefNames when referencing other defs
* Autocomplete DefNames when using `DefDatabase<Def>.GetNamed()`
* Autocomplete DefNames when creating fields in `[DefOf]` classes
* Autocomplete certain values for properties with fixed options (Such as Altitude Layer, boolean and directions)
* Use `Ctrl+Click` to go references
* When using them on DefTypes, just to the C# class for that Def
* When using them on XML Properties, jump to the C# definition for that property
* When using them on DefName references, jump to the XML definition for that DefName
* When using them on certain XML values, jump to the C# definition for that value
* When using them on `[DefOf]` fields, or `DefDatabase<Def>.GetNamed()` calls, jump to the XML definition for that DefName
* Read the values in `Class=""` attributes to fetch the correct class to autocomplete from, such as in comps
* Support for Custom Def Classes (Such as `<MyMod.CustomThingDef>`)
* A Rimworld Run Configuration
* Automatically loads Unity Doorstop if run in Debug mode
* Specify a ModList and Save file to load for just this one launch
* Rimworld Mod support in New Solution
* Custom Rimworld XML Projects
* Automatically includes Rimworlds Core and DLC defs
* Reads your `About.xml` to automatically include the defs of mods that you rely on in your workspace
* Basic validation for some XML Values
* Support for Custom Def Classes (Such as `<MyMod.CustomThingDef>`)
* The ability to perform Find Usages on XML Defs
* A "Generate" menu option to generate properties for a given XML Def
* Includes a Rimworld Dictionary so that Rimworld terms don't get flagged as not real words by Rider

## Quick Architecture For Developers

Expand Down
2 changes: 1 addition & 1 deletion buildPlugin.ps1
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Param(
$Version = "2023.4"
$Version = "2024.1-EAP"
)

Set-StrictMode -Version Latest
Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
DotnetPluginId=ReSharperPlugin.RimworldDev
DotnetSolution=ReSharperPlugin.RimworldDev.sln
RiderPluginId=com.jetbrains.rider.plugins.rimworlddev
PluginVersion=2023.4
PluginVersion=2024.1.1

BuildConfiguration=Release

Expand All @@ -14,7 +14,7 @@ PublishToken="_PLACEHOLDER_"
# Release: 2020.2
# Nightly: 2020.3-SNAPSHOT
# EAP: 2020.3-EAP2-SNAPSHOT
ProductVersion=2023.3
ProductVersion=2024.1.1

# Kotlin 1.4 will bundle the stdlib dependency by default, causing problems with the version bundled with the IDE
# https://blog.jetbrains.com/kotlin/2020/07/kotlin-1-4-rc-released/#stdlib-default
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Update="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" />
<PackageReference Include="Lib.Harmony" Version="2.3.3" />
</ItemGroup>

<ItemGroup>
Expand Down
25 changes: 25 additions & 0 deletions src/dotnet/ReSharperPlugin.RimworldDev/DefNameValue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.Linq;

namespace ReSharperPlugin.RimworldDev;

public class DefNameValue
{
public readonly string DefType;

public readonly string DefName;

public string TagId => $"{DefType}/{DefName}";

public DefNameValue(string tagId)
{
var split = tagId.Split('/');
DefType = split.First();
DefName = split.Last();
}

public DefNameValue(string defType, string defName)
{
DefType = defType;
DefName = defName;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System.Linq;
using JetBrains.ProjectModel;
using JetBrains.ReSharper.Feature.Services.CodeCompletion.Infrastructure;
using JetBrains.ReSharper.Feature.Services.CodeCompletion.Infrastructure.LookupItems;
using JetBrains.ReSharper.Feature.Services.CSharp.CodeCompletion.Infrastructure;
using JetBrains.ReSharper.Psi;
using JetBrains.ReSharper.Psi.CSharp;
using JetBrains.ReSharper.Psi.CSharp.Tree;
using JetBrains.ReSharper.Psi.Tree;
using ReSharperPlugin.RimworldDev.SymbolScope;
using ReSharperPlugin.RimworldDev.TypeDeclaration;

namespace ReSharperPlugin.RimworldDev.ItemCompletion;

[Language(typeof(CSharpLanguage))]
public class CSharpDefsOfItemProvider : ItemsProviderOfSpecificContext<CSharpCodeCompletionContext>
{
private static RimworldCSharpLookupFactory LookupFactory = new();

protected override bool IsAvailable(CSharpCodeCompletionContext context)
{
var node = context.NodeInFile;
if (!node.Language.IsLanguage(CSharpLanguage.Instance)) return false;
if (node.Parent is not IFieldDeclaration fieldDeclaration) return false;
if (fieldDeclaration.Type is not IDeclaredType) return false;
if (fieldDeclaration.GetContainingTypeElement() is not IClass containingClass) return false;
if (containingClass
.GetAttributeInstances(AttributesSource.Self)
.FirstOrDefault(attribute => attribute.GetClrName().FullName == "RimWorld.DefOf") is null) return false;

return true;
}

protected override bool AddLookupItems(CSharpCodeCompletionContext context, IItemsCollector collector)
{
var node = context.NodeInFile;

if (node.Parent is not IFieldDeclaration fieldDeclaration) return false;
if (fieldDeclaration.Type is not IDeclaredType fieldType) return false;

var defTypeName = fieldType.GetClrName().ShortName;
var xmlSymbolTable = context.NodeInFile.GetSolution().GetComponent<RimworldSymbolScope>();

var allDefs = xmlSymbolTable.GetDefsByType(defTypeName);

foreach (var key in allDefs)
{
var defType = key.Split('/').First();
var defName = key.Split('/').Last();

var item = xmlSymbolTable.GetTagByDef(defType, defName);

var lookup = LookupFactory.CreateDeclaredElementLookupItem(context, defName,
new DeclaredElementInstance(new XMLTagDeclaredElement(item, defType, defName, false)));
collector.Add(lookup);
}

return base.AddLookupItems(context, collector);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System.Linq;
using JetBrains.ProjectModel;
using JetBrains.ReSharper.Feature.Services.CodeCompletion.Infrastructure;
using JetBrains.ReSharper.Feature.Services.CodeCompletion.Infrastructure.LookupItems;
using JetBrains.ReSharper.Feature.Services.CSharp.CodeCompletion.Infrastructure;
using JetBrains.ReSharper.Psi;
using JetBrains.ReSharper.Psi.CSharp;
using JetBrains.ReSharper.Psi.CSharp.Impl.Tree;
using JetBrains.ReSharper.Psi.CSharp.Parsing;
using JetBrains.ReSharper.Psi.CSharp.Tree;
using JetBrains.ReSharper.Psi.Tree;
using ReSharperPlugin.RimworldDev.SymbolScope;
using ReSharperPlugin.RimworldDev.TypeDeclaration;

namespace ReSharperPlugin.RimworldDev.ItemCompletion;

[Language(typeof(CSharpLanguage))]
public class RimworldDefCSharpItemProvider: ItemsProviderOfSpecificContext<CSharpCodeCompletionContext>
{
private static RimworldCSharpLookupFactory LookupFactory = new();

protected override bool IsAvailable(CSharpCodeCompletionContext context)
{
var node = context.NodeInFile;
if (!node.Language.IsLanguage(CSharpLanguage.Instance)) return false;
if (node is not CSharpGenericToken) return false;
if (node.NodeType != CSharpTokenType.STRING_LITERAL_REGULAR) return false;

return true;
}

protected override bool AddLookupItems(CSharpCodeCompletionContext context, IItemsCollector collector)
{
var node = context.NodeInFile;
if (node?.Parent?.Parent?.Parent?.Parent is not IInvocationExpression invocationExpression
|| !invocationExpression.GetText().Contains("DefDatabase")
|| invocationExpression.Type() is not IDeclaredType declaredType) return false;

var defTypeName = declaredType.GetClrName().ShortName;
var xmlSymbolTable = context.NodeInFile.GetSolution().GetComponent<RimworldSymbolScope>();

var allDefs = xmlSymbolTable.GetDefsByType(defTypeName);

foreach (var key in allDefs)
{
var defType = key.Split('/').First();
var defName = key.Split('/').Last();

var item = xmlSymbolTable.GetTagByDef(defType, defName);

var lookup = LookupFactory.CreateDeclaredElementLookupItem(context, defName,
new DeclaredElementInstance(new XMLTagDeclaredElement(item, defType, defName, false)));
collector.Add(lookup);
}

return base.AddLookupItems(context, collector);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@
using JetBrains.Diagnostics;
using JetBrains.ReSharper.Psi;
using JetBrains.ReSharper.Psi.Caches;
using JetBrains.ReSharper.Psi.CSharp;
using JetBrains.ReSharper.Psi.ExtensionsAPI;
using JetBrains.ReSharper.Psi.ExtensionsAPI.Finder;
using JetBrains.ReSharper.Psi.Files;
using JetBrains.ReSharper.Psi.Search;
using JetBrains.ReSharper.Psi.Tree;
using JetBrains.ReSharper.Psi.Xml;

namespace ReSharperPlugin.RimworldDev.Navigation;

public class CustomSearcher<TLanguage> : IDomainSpecificSearcher where TLanguage : KnownLanguage
public class CustomSearcher : IDomainSpecificSearcher
{
private readonly JetHashSet<string> myNames;
private readonly JetHashSet<string> myWordsInText;
Expand Down Expand Up @@ -50,7 +52,8 @@ public bool ProcessProjectItem<TResult>(
{
if (!CanContainWord(sourceFile)) return false;

foreach (ITreeNode psiFile in sourceFile.GetPsiFiles<TLanguage>())
foreach (var psiFile in sourceFile.GetPsiFiles<XmlLanguage>()
.Concat(sourceFile.GetPsiFiles<CSharpLanguage>()))
{
if (ProcessElement(psiFile, consumer))
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ public override IDomainSpecificSearcher CreateReferenceSearcher(
elements = new DeclaredElementsSet(elements.Where(element =>
IsCompatibleWithLanguage(element.PresentationLanguage)));

return new CustomSearcher<XmlLanguage>(this,
elements, referenceSearcherParameters, false);
return new CustomSearcher(this, elements, referenceSearcherParameters, false);
}

public override IEnumerable<string> GetAllPossibleWordsInFile(IDeclaredElement element)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"datatype": "text",
"replaces": "ModName",
"isRequired": "false",
"defaultValue": "teds"
"defaultValue": ""
},
"ModAuthor": {
"type": "parameter",
Expand Down Expand Up @@ -101,6 +101,9 @@
{
"path": ".gitignore"
},
{
"path": "_PublisherPlus.xml"
},
{
"path": "Languages/Keyed/English.xml"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Verse;

namespace MyRimWorldMod;

public class MyRimWorldMod : Mod
{
public MyRimWorldMod(ModContentPack content) : base(content)
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<RootNamespace>MyRimworldMod</RootNamespace>
<AssemblyName>MyRimworldMod</AssemblyName>
<RootNamespace>MyRimWorldMod</RootNamespace>
<AssemblyName>MyRimWorldMod</AssemblyName>
<TargetFramework>net472</TargetFramework>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<Configuration>
<Excluded>
<exclude>.git</exclude>
<exclude>.idea</exclude>
<exclude>.run</exclude>
<exclude>MyRimWorldMod.sln</exclude>
<exclude>packages</exclude>
<exclude>Source</exclude>
</Excluded>
</Configuration>
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@

<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2023.3.0" />
<PackageReference Include="JetBrains.Lifetimes" Version="2023.3.3" />
<PackageReference Include="JetBrains.RdFramework" Version="2023.3.3" />
<PackageReference Include="JetBrains.Rider.SDK" Version="2023.3.1">
<PackageReference Include="JetBrains.Lifetimes" Version="2024.1.1" />
<PackageReference Include="JetBrains.RdFramework" Version="2024.1.1" />
<PackageReference Include="JetBrains.Rider.SDK" Version="2024.1.0-eap09">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Lib.Harmony" Version="2.3.3" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading

0 comments on commit 816f5e6

Please sign in to comment.