Skip to content

Commit

Permalink
Added enum support in MiniYAML files
Browse files Browse the repository at this point in the history
This adds Hover/GoTo/Completion support for enums in Rules, Weapons and SpriteSequence files.
  • Loading branch information
penev92 committed Oct 23, 2022
1 parent cd7ffe0 commit 06f2bd1
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,19 @@ protected override IEnumerable<CompletionItem> HandleRulesValue(CursorTarget cur
return sequences.Select(x => x.ToCompletionItem());
}

// Try to check if this is an enum type field.
var enumInfo = symbolCache[cursorTarget.ModId].CodeSymbols.EnumInfos.FirstOrDefault(x => x.Key == fieldInfo.InternalType);
if (enumInfo != null)
{
return enumInfo.FirstOrDefault().Values.Select(x => new CompletionItem
{
Label = x,
Kind = CompletionItemKind.EnumMember,
Detail = "Enum type value",
Documentation = $"{enumInfo.Key}.{x}"
});
}

return Enumerable.Empty<CompletionItem>();
}

Expand Down Expand Up @@ -401,24 +414,24 @@ protected override IEnumerable<CompletionItem> HandleWeaponValue(CursorTarget cu
case 2:
{
ClassFieldInfo fieldInfo = default;
var fieldInfos = Array.Empty<ClassFieldInfo>();
var classFieldInfos = Array.Empty<ClassFieldInfo>();
var parentNode = cursorTarget.TargetNode.ParentNode;
if (parentNode.Key == "Projectile")
{
var projectileInfo = symbolCache[modId].CodeSymbols.WeaponInfo.ProjectileInfos.FirstOrDefault(x => x.Name == cursorTarget.TargetNode.ParentNode.Value);
var projectileInfo = weaponInfo.ProjectileInfos.FirstOrDefault(x => x.Name == parentNode.Value);
if (projectileInfo.Name != null)
{
fieldInfo = projectileInfo.PropertyInfos.FirstOrDefault(x => x.Name == cursorTarget.TargetNode.Key);
fieldInfos = projectileInfo.PropertyInfos;
classFieldInfos = projectileInfo.PropertyInfos;
}
}
else if (parentNode.Key == "Warhead" || parentNode.Key.StartsWith("Warhead@"))
{
var warheadInfo = symbolCache[modId].CodeSymbols.WeaponInfo.WarheadInfos.FirstOrDefault(x => x.Name == cursorTarget.TargetNode.ParentNode.Value);
var warheadInfo = weaponInfo.WarheadInfos.FirstOrDefault(x => x.Name == parentNode.Value);
if (warheadInfo.Name != null)
{
fieldInfo = warheadInfo.PropertyInfos.FirstOrDefault(x => x.Name == cursorTarget.TargetNode.Key);
fieldInfos = warheadInfo.PropertyInfos;
classFieldInfos = warheadInfo.PropertyInfos;
}
}

Expand All @@ -441,7 +454,7 @@ protected override IEnumerable<CompletionItem> HandleWeaponValue(CursorTarget cu

// Pretend there is such a thing as a "SequenceImageReferenceAttribute" until we add it in OpenRA one day.
// NOTE: This will improve if/when we add the attribute.
if (fieldInfos.Any(x => x.OtherAttributes.Any(y => y.Name == "SequenceReference"
if (classFieldInfos.Any(x => x.OtherAttributes.Any(y => y.Name == "SequenceReference"
&& (y.Value.Contains(',') ? y.Value.Substring(0, y.Value.IndexOf(',')) == fieldInfo.Name : y.Value == fieldInfo.Name))))
{
return spriteSequenceImageNames;
Expand All @@ -455,6 +468,19 @@ protected override IEnumerable<CompletionItem> HandleWeaponValue(CursorTarget cu
return sequences.Select(x => x.ToCompletionItem());
}

// Try to check if this is an enum type field.
var enumInfo = symbolCache[cursorTarget.ModId].CodeSymbols.EnumInfos.FirstOrDefault(x => x.Key == fieldInfo.InternalType);
if (enumInfo != null)
{
return enumInfo.FirstOrDefault().Values.Select(x => new CompletionItem
{
Label = x,
Kind = CompletionItemKind.EnumMember,
Detail = "Enum type value",
Documentation = $"{enumInfo.Key}.{x}"
});
}

return Enumerable.Empty<CompletionItem>();
}

Expand Down Expand Up @@ -544,6 +570,32 @@ IEnumerable<CompletionItem> HandleSpriteSequenceProperty()

protected override IEnumerable<CompletionItem> HandleSpriteSequenceFileValue(CursorTarget cursorTarget)
{
IEnumerable<CompletionItem> HandleSpriteSequenceProperty()
{
var spriteSequenceFormat = symbolCache[cursorTarget.ModId].ModManifest.SpriteSequenceFormat.Type;
var spriteSequenceType = symbolCache[cursorTarget.ModId].CodeSymbols.SpriteSequenceInfos[spriteSequenceFormat].First();

var fieldInfo = spriteSequenceType.PropertyInfos.FirstOrDefault(x => x.Name == cursorTarget.TargetNode.Key);
if (fieldInfo.Name != null)
{
// Try to check if this is an enum type field.
var enumInfo = symbolCache[cursorTarget.ModId].CodeSymbols.EnumInfos
.FirstOrDefault(x => x.Key == fieldInfo.InternalType);
if (enumInfo != null)
{
return enumInfo.FirstOrDefault().Values.Select(x => new CompletionItem
{
Label = x,
Kind = CompletionItemKind.EnumMember,
Detail = "Enum type value",
Documentation = $"{enumInfo.Key}.{x}"
});
}
}

return Enumerable.Empty<CompletionItem>();
}

switch (cursorTarget.TargetNodeIndentation)
{
case 1:
Expand All @@ -565,6 +617,17 @@ protected override IEnumerable<CompletionItem> HandleSpriteSequenceFileValue(Cur
return Enumerable.Empty<CompletionItem>();
}

case 2:
return HandleSpriteSequenceProperty();

case 4:
{
if (cursorTarget.TargetNode.ParentNode.ParentNode.Key == "Combine")
return HandleSpriteSequenceProperty();

return Enumerable.Empty<CompletionItem>();
}

default:
return Enumerable.Empty<CompletionItem>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,14 @@ protected override IEnumerable<Location> HandleRulesValue(CursorTarget cursorTar
.Where(x => x.Name == cursorTarget.TargetString)
.Select(x => x.Location.ToLspLocation(x.Name.Length));
}

// Try to check if this is an enum type field.
var enumInfo = symbolCache[cursorTarget.ModId].CodeSymbols.EnumInfos
.FirstOrDefault(x => x.Key == fieldInfo.InternalType);
if (enumInfo != null)
{
return new[] { enumInfo.First().Location.ToLspLocation(enumInfo.Key.Length) };
}
}
}

Expand Down Expand Up @@ -373,6 +381,14 @@ protected override IEnumerable<Location> HandleWeaponValue(CursorTarget cursorTa
.Select(x => x.Location.ToLspLocation(x.Name.Length));
}

// Try to check if this is an enum type field.
var enumInfo = symbolCache[cursorTarget.ModId].CodeSymbols.EnumInfos
.FirstOrDefault(x => x.Key == fieldInfo.InternalType);
if (enumInfo != null)
{
return new[] { enumInfo.First().Location.ToLspLocation(enumInfo.Key.Length) };
}

return Enumerable.Empty<Location>();
}

Expand Down Expand Up @@ -500,6 +516,26 @@ IEnumerable<Location> HandleSpriteSequenceProperty()

protected override IEnumerable<Location> HandleSpriteSequenceFileValue(CursorTarget cursorTarget)
{
IEnumerable<Location> HandleSpriteSequenceProperty()
{
var spriteSequenceFormat = symbolCache[cursorTarget.ModId].ModManifest.SpriteSequenceFormat.Type;
var spriteSequenceType = symbolCache[cursorTarget.ModId].CodeSymbols.SpriteSequenceInfos[spriteSequenceFormat].First();

var fieldInfo = spriteSequenceType.PropertyInfos.FirstOrDefault(x => x.Name == cursorTarget.TargetNode.Key);
if (fieldInfo.Name != null)
{
// Try to check if this is an enum type field.
var enumInfo = symbolCache[cursorTarget.ModId].CodeSymbols.EnumInfos
.FirstOrDefault(x => x.Key == fieldInfo.InternalType);
if (enumInfo != null)
{
return new[] { enumInfo.First().Location.ToLspLocation(enumInfo.Key.Length) };
}
}

return Enumerable.Empty<Location>();
}

switch (cursorTarget.TargetNodeIndentation)
{
// NOTE: Copied from HandleWeaponsFileKey.
Expand All @@ -524,6 +560,17 @@ protected override IEnumerable<Location> HandleSpriteSequenceFileValue(CursorTar
return Enumerable.Empty<Location>();
}

case 2:
return HandleSpriteSequenceProperty();

case 4:
{
if (cursorTarget.TargetNode.ParentNode.ParentNode.Key == "Combine")
return HandleSpriteSequenceProperty();

return Enumerable.Empty<Location>();
}

default:
return Enumerable.Empty<Location>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,14 @@ protected override Hover HandleRulesValue(CursorTarget cursorTarget)
var spriteSequence = image.Sequences.First(x => x.Name == cursorTarget.TargetString);
return HoverFromHoverInfo(spriteSequence.ToMarkdownInfoString(), range);
}

// Try to check if this is an enum type field.
var enumInfo = symbolCache[cursorTarget.ModId].CodeSymbols.EnumInfos.FirstOrDefault(x => x.Key == fieldInfo.InternalType);
if (enumInfo != null)
{
var content = $"```csharp\n{enumInfo.Key}.{cursorTarget.TargetString}\n```";
return HoverFromHoverInfo(content, range);
}
}

// Show explanation for world range value.
Expand Down Expand Up @@ -497,6 +505,14 @@ protected override Hover HandleWeaponValue(CursorTarget cursorTarget)
return HoverFromHoverInfo(spriteSequence.ToMarkdownInfoString(), range);
}

// Try to check if this is an enum type field.
var enumInfo = symbolCache[cursorTarget.ModId].CodeSymbols.EnumInfos.FirstOrDefault(x => x.Key == fieldInfo.InternalType);
if (enumInfo != null)
{
var content = $"```csharp\n{enumInfo.Key}.{cursorTarget.TargetString}\n```";
return HoverFromHoverInfo(content, range);
}

return null;
}

Expand Down Expand Up @@ -684,6 +700,27 @@ Hover HandleSpriteSequenceFileName()
return HoverFromHoverInfo(content, range);
}

Hover HandleSpriteSequenceProperty()
{
var spriteSequenceFormat = symbolCache[cursorTarget.ModId].ModManifest.SpriteSequenceFormat.Type;
var spriteSequenceType = symbolCache[cursorTarget.ModId].CodeSymbols.SpriteSequenceInfos[spriteSequenceFormat].First();

var fieldInfo = spriteSequenceType.PropertyInfos.FirstOrDefault(x => x.Name == cursorTarget.TargetNode.Key);
if (fieldInfo.Name != null)
{
// Try to check if this is an enum type field.
var enumInfo = symbolCache[cursorTarget.ModId].CodeSymbols.EnumInfos
.FirstOrDefault(x => x.Key == fieldInfo.InternalType);
if (enumInfo != null)
{
var content = $"```csharp\n{enumInfo.Key}.{cursorTarget.TargetString}\n```";
return HoverFromHoverInfo(content, range);
}
}

return null;
}

switch (cursorTarget.TargetNodeIndentation)
{
case 1:
Expand Down Expand Up @@ -711,6 +748,9 @@ Hover HandleSpriteSequenceFileName()
return null;
}

case 2:
return HandleSpriteSequenceProperty();

case 3:
{
if (cursorTarget.TargetNode.ParentNode.Key == "Combine")
Expand All @@ -719,6 +759,14 @@ Hover HandleSpriteSequenceFileName()
return null;
}

case 4:
{
if (cursorTarget.TargetNode.ParentNode.ParentNode.Key == "Combine")
return HandleSpriteSequenceProperty();

return null;
}

default:
return null;
}
Expand Down

0 comments on commit 06f2bd1

Please sign in to comment.