Skip to content

[Unfinished] Find Usages in scenes #50

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 21 commits into
base: net202
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions resharper/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<Project>
<Import Project="$(MSBuildThisFileDirectory)..\rider-godot\build\DotNetSdkPath.generated.props"
Condition="Exists('$(MSBuildThisFileDirectory)..\rider-godot\build\DotNetSdkPath.generated.props')" />
<!-- TODO: Test what happens without the condition if props are not generated yet -->
</Project>
22 changes: 22 additions & 0 deletions resharper/rider-godot.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "rider-godot", "src\rider-godot.csproj", "{E5F98D56-13E6-41B1-A70A-E1E1F81866C8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "tests.rider-godot", "test\src\tests.rider-godot.csproj", "{EE74970A-2AE8-43B2-8912-0418680FCDA1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E5F98D56-13E6-41B1-A70A-E1E1F81866C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E5F98D56-13E6-41B1-A70A-E1E1F81866C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E5F98D56-13E6-41B1-A70A-E1E1F81866C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E5F98D56-13E6-41B1-A70A-E1E1F81866C8}.Release|Any CPU.Build.0 = Release|Any CPU
{EE74970A-2AE8-43B2-8912-0418680FCDA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EE74970A-2AE8-43B2-8912-0418680FCDA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EE74970A-2AE8-43B2-8912-0418680FCDA1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EE74970A-2AE8-43B2-8912-0418680FCDA1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
14 changes: 14 additions & 0 deletions resharper/rider-godot.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSORHOLDER_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Constants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"&gt;&lt;ExtraRule Prefix="" Suffix="" Style="AA_BB" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"&gt;&lt;ExtraRule Prefix="" Suffix="" Style="AA_BB" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="my" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="our" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="our" Suffix="" Style="AaBb"&gt;&lt;ExtraRule Prefix="" Suffix="" Style="AA_BB" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=StaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"&gt;&lt;ExtraRule Prefix="" Suffix="" Style="AA_BB" /&gt;&lt;/Policy&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=TSCN/@EntryIndexedValue">True</s:Boolean>
</wpf:ResourceDictionary>
18 changes: 18 additions & 0 deletions resharper/src/ProjectModel/ProjectExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using JetBrains.Annotations;
using JetBrains.ProjectModel;

namespace JetBrains.ReSharper.Plugins.Godot.ProjectModel
{
public static class ProjectExtensions
{
// TODO: Add tests for this
public static bool IsGodotProject([CanBeNull] this IProject project)
{
if (project == null || !project.IsValid())
return false;

// TODO: Implement properly. Look for a Godot reference, just like in frontend
return true;
}
}
}
27 changes: 27 additions & 0 deletions resharper/src/Tscn/ProjectModel/TscnProjectFileType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using JetBrains.Annotations;
using JetBrains.ProjectModel;

namespace JetBrains.ReSharper.Plugins.Godot.Tscn.ProjectModel
{
[ProjectFileTypeDefinition(Name)]
public class TscnProjectFileType : KnownProjectFileType
{
public new const string Name = "TSCN";
public const string TEXT_SCENE_EXTENSION = ".tscn";
public const string TEXT_RESOURCE_EXTENSION = ".tres";
public const string EXPORTED_SCENE_EXTENSION = ".escn";

[CanBeNull, UsedImplicitly]
public new static TscnProjectFileType Instance { get; private set; }

private TscnProjectFileType()
: base(Name, "TSCN", new[]
{
TEXT_SCENE_EXTENSION,
TEXT_RESOURCE_EXTENSION,
EXPORTED_SCENE_EXTENSION
})
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using JetBrains.ReSharper.Psi;

namespace JetBrains.ReSharper.Plugins.Godot.Tscn.Psi.DeclaredElements
{
public interface ITscnDeclaredElement : IDeclaredElement
{
}
}
14 changes: 14 additions & 0 deletions resharper/src/Tscn/Psi/DeclaredElements/NodeDeclaredElement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using JetBrains.ReSharper.Psi;

namespace JetBrains.ReSharper.Plugins.Godot.Tscn.Psi.DeclaredElements
{
public class NodeDeclaredElement : TscnDeclaredElementBase
{
public NodeDeclaredElement(string shortName, IPsiSourceFile sourceFile, int treeOffset)
: base(shortName, sourceFile, treeOffset)
{
}

public override DeclaredElementType GetElementType() => TscnDeclaredElementType.Node;
}
}
79 changes: 79 additions & 0 deletions resharper/src/Tscn/Psi/DeclaredElements/TscnDeclaredElementBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using System.Collections.Generic;
using System.Xml;
using JetBrains.ReSharper.Plugins.Godot.Tscn.Psi.Tree;
using JetBrains.ReSharper.Psi;
using JetBrains.ReSharper.Psi.Files;
using JetBrains.ReSharper.Psi.Tree;
using JetBrains.Util;
using JetBrains.Util.DataStructures;

namespace JetBrains.ReSharper.Plugins.Godot.Tscn.Psi.DeclaredElements
{
public abstract class TscnDeclaredElementBase : ITscnDeclaredElement
{
private readonly IPsiSourceFile mySourceFile;

protected TscnDeclaredElementBase(string shortName, IPsiSourceFile sourceFile, int treeOffset)
{
mySourceFile = sourceFile;
TreeOffset = treeOffset;
ShortName = shortName;
}

protected int TreeOffset { get; }

public IPsiServices GetPsiServices()
{
return mySourceFile.GetPsiServices();
}

public IList<IDeclaration> GetDeclarations()
{
// TODO: This is almost certainly not what we want, taken from ShaderLab
if (!(mySourceFile.GetPrimaryPsiFile() is ITscnFile psi))
return EmptyList<IDeclaration>.InstanceList;

var node = psi.FindNodeAt(TreeTextRange.FromLength(new TreeOffset(TreeOffset), 1));
while (node != null && !(node is IDeclaration))
node = node.Parent;
if (node == null)
return EmptyList<IDeclaration>.Instance;

return new[] {(IDeclaration) node};
}

public IList<IDeclaration> GetDeclarationsIn(IPsiSourceFile sourceFile)
{
if (mySourceFile == sourceFile)
return GetDeclarations();
return EmptyList<IDeclaration>.Instance;
}

public abstract DeclaredElementType GetElementType();

public XmlNode GetXMLDoc(bool inherit) => null;

public XmlNode GetXMLDescriptionSummary(bool inherit) => null;

public bool IsValid() => true;

public bool IsSynthetic() => false;

public HybridCollection<IPsiSourceFile> GetSourceFiles()
{
return new HybridCollection<IPsiSourceFile>(mySourceFile);
}

public bool HasDeclarationsIn(IPsiSourceFile sourceFile)
{
return mySourceFile == sourceFile;
}

public string ShortName { get; }

public bool CaseSensitiveName => true;

// ReSharper disable once AssignNullToNotNullAttribute
public PsiLanguageType PresentationLanguage => TscnLanguage.Instance;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using System;
using System.Text;
using JetBrains.ReSharper.Psi;
using JetBrains.ReSharper.Psi.Resolve;
using JetBrains.UI.RichText;
using JetBrains.Util;

namespace JetBrains.ReSharper.Plugins.Godot.Tscn.Psi.DeclaredElements
{
[PsiSharedComponent]
public class TscnDeclaredElementPresenter : IDeclaredElementPresenter
{
// The implementation of this presenter comes from ShaderLab Support in the Unity plugin.

public static TscnDeclaredElementPresenter Instance => PsiShared.GetComponent<TscnDeclaredElementPresenter>();

public RichText Format(DeclaredElementPresenterStyle style, IDeclaredElement element, ISubstitution substitution,
out DeclaredElementPresenterMarking marking)
{
marking = new DeclaredElementPresenterMarking();
if (!(element is TscnDeclaredElementBase))
return null;

var result = new StringBuilder();

if (style.ShowEntityKind != EntityKindForm.NONE)
{
var entityKind = GetEntityKind(element);
if (entityKind != string.Empty)
{
if (style.ShowEntityKind == EntityKindForm.NORMAL_IN_BRACKETS)
entityKind = "(" + entityKind + ")";
marking.EntityKindRange = AppendString(result, entityKind);
result.Append(" ");
}
}

if (style.ShowNameInQuotes)
result.Append("\'");

if (style.ShowName != NameStyle.NONE)
{
marking.NameRange = AppendString(result, element.ShortName);
result.Append(" ");
}

if (style.ShowNameInQuotes)
{
TrimString(result);
result.Append("\'");
}

if (style.ShowConstantValue)
{
}

TrimString(result);
return result.ToString();
}

public string Format(ParameterKind parameterKind) => string.Empty;

public string Format(AccessRights accessRights) => string.Empty;


string GetEntityKind(IDeclaredElement declaredElement)
{
var elementType = declaredElement.GetElementType() as TscnDeclaredElementType;
if (elementType != null)
return elementType.PresentableName.ToLower();

return string.Empty;
}

private static void TrimString(StringBuilder sb)
{
while (sb.Length > 0 && sb[sb.Length - 1] == ' ')
sb.Remove(sb.Length - 1, 1);
}

private static TextRange AppendString(StringBuilder sb, string substr)
{
var s = sb.Length;
sb.Append(substr);
return substr.Length == 0 ? TextRange.InvalidRange : new TextRange(s, sb.Length);
}

}
}
27 changes: 27 additions & 0 deletions resharper/src/Tscn/Psi/DeclaredElements/TscnDeclaredElementType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using JetBrains.Annotations;
using JetBrains.ReSharper.Psi;
using JetBrains.UI.Icons;

namespace JetBrains.ReSharper.Plugins.Godot.Tscn.Psi.DeclaredElements
{
public class TscnDeclaredElementType : DeclaredElementType
{
// TODO: Icon
public static readonly TscnDeclaredElementType Node = new TscnDeclaredElementType("SceneNode", null);

private readonly IconId myIconId;

protected TscnDeclaredElementType([NotNull] string name, IconId iconId) : base(name)
{
PresentableName = name;
myIconId = iconId;
}

public override IconId GetImage() => myIconId;

public override bool IsPresentable(PsiLanguageType language) => language.Is<TscnLanguage>();

public override string PresentableName { get; }
protected override IDeclaredElementPresenter DefaultPresenter => TscnDeclaredElementPresenter.Instance;
}
}
30 changes: 30 additions & 0 deletions resharper/src/Tscn/Psi/Parsing/Chars.lex
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
%include PsiTasks/Unicode.lex

NULL_CHAR=\u0000

TAB=\u0009
LF=\u000A
VERTICAL_TAB=\u000B
FF=\u000C
CR=\u000D
NEL=\u0085
UNICODE_CC_WHITESPACE_CHARS={TAB}{VERTICAL_TAB}
UNICODE_CC_SEPARATOR_CHARS={LF}{FF}{CR}{NEXT_LINE}


ZERO_WIDTH_SP=\u200B
ZERO_WIDTH_NBSP=\uFEFF
OTHER_CF_WHITESPACE=\u180E
UNICODE_CF_WHITESPACE_CHARS={ZERO_WIDTH_SP}{ZERO_WIDTH_NBSP}{OTHER_CF_WHITESPACE}


LINE_SEPARATOR=\u2028
UNICODE_ZL_CHARS={LINE_SEPARATOR}

PARAGRAPH_SEPARATOR=\u2029
UNICODE_ZP_CHARS={PARAGRAPH_SEPARATOR}

SP=\u0020
NBSP=\u00A0
OTHER_SP=\u1680\u2000-\u200A\u202F\u205F\u3000
UNICODE_ZS_CHARS={SP}{NBSP}{OTHER_SP}
9 changes: 9 additions & 0 deletions resharper/src/Tscn/Psi/Parsing/ITscnParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using JetBrains.ReSharper.Psi.Parsing;

namespace JetBrains.ReSharper.Plugins.Godot.Tscn.Psi.Parsing
{
public interface ITscnParser : IParser
{

}
}
32 changes: 32 additions & 0 deletions resharper/src/Tscn/Psi/Parsing/ParserMessages.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using JetBrains.Util;

// ReSharper disable InconsistentNaming

namespace JetBrains.ReSharper.Plugins.Godot.Tscn.Psi.Parsing
{
public static class ParserMessages
{
public const string IDS_UNEXPECTED_TOKEN = "Unexpected token";
public const string IDS_EXPECTED_SYMBOL = "{0} expected";
public const string IDS_EXPECTED_SYMBOLS = "{0} or {1} expected";
public const string IDS_TSCN_FILE = "tscn file";
public const string IDS_VARIANT_LITERAL = "variant literal";
public const string IDS_VARIANT_VALUE = "variant value";
public const string IDS_RESOURCE_DESCRIPTOR = "resource file descriptor";
public const string IDS_SCENE_DESCRIPTOR = "scene file descriptor";

public static string GetString(string id) => id;

public static string GetUnexpectedTokenMessage() => IDS_UNEXPECTED_TOKEN;

public static string GetExpectedMessage(string tokenRepr)
{
return string.Format(GetString(IDS_EXPECTED_SYMBOL), tokenRepr).Capitalize();
}

public static string GetExpectedMessage(string firstExpectedSymbol, string secondExpectedSymbol)
{
return string.Format(GetString(IDS_EXPECTED_SYMBOLS), firstExpectedSymbol, secondExpectedSymbol).Capitalize();
}
}
}
Loading