diff --git a/src/.idea/.idea.L5Sharp/.idea/workspace.xml b/src/.idea/.idea.L5Sharp/.idea/workspace.xml
index 5f53df31..27f89384 100644
--- a/src/.idea/.idea.L5Sharp/.idea/workspace.xml
+++ b/src/.idea/.idea.L5Sharp/.idea/workspace.xml
@@ -8,9 +8,22 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -53,6 +66,7 @@
+
@@ -97,7 +111,7 @@
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
- "settings.editor.selected.configurable": "ml.llm.AIAssistantPromptsLibrary",
+ "settings.editor.selected.configurable": "org.jetbrains.plugins.github.ui.GithubSettingsConfigurable",
"vue.rearranger.settings.migration": "true"
},
"keyToStringList": {
@@ -362,7 +376,7 @@
-
+
1677621948966
@@ -707,7 +721,7 @@
1687451515386
-
+
@@ -743,7 +757,6 @@
-
@@ -768,7 +781,8 @@
-
+
+
@@ -779,6 +793,19 @@
+
+ file://$PROJECT_DIR$/../tests/L5Sharp.Tests/L5XDataTypeTests.cs
+ 245
+
+
+
+
+
+
+
+
+
+
diff --git a/src/L5Sharp/Common/Instruction.cs b/src/L5Sharp/Common/Instruction.cs
index 80d3ba8b..f11efec4 100644
--- a/src/L5Sharp/Common/Instruction.cs
+++ b/src/L5Sharp/Common/Instruction.cs
@@ -4,7 +4,6 @@
using System.Linq.Expressions;
using System.Reflection;
using System.Text.RegularExpressions;
-using System.Threading;
using JetBrains.Annotations;
using L5Sharp.Utilities;
@@ -53,6 +52,11 @@ public sealed class Instruction
/// of an instruction signature into separate parsable values.
///
private const string ArgumentSplitPattern = ",(?![^[]*])";
+
+ ///
+ /// Lazy list of all known instructions and their corresponding factory method function.
+ ///
+ private static Dictionary> _known = Factories().ToDictionary(x => x.Key, x => x.Value);
///
/// Creates a new with the provided string key and regex signature pattern.
@@ -68,16 +72,6 @@ private Instruction(string key, string? signature = null, params Argument[] argu
Key = key;
Signature = signature ?? $"{key}({DefaultArgs(arguments.Length)})";
Arguments = arguments;
- Operadns = ExtractOperands(Signature);
- }
-
- private IEnumerable ExtractOperands(string signature)
- {
- var input = Regex.Match(Signature, SignaturePattern).Value[1..^1];
-
- return !string.IsNullOrEmpty(input)
- ? Regex.Split(input, ArgumentSplitPattern)
- : Enumerable.Empty().ToArray();
}
///
@@ -110,7 +104,17 @@ private IEnumerable ExtractOperands(string signature)
/// The collection of operand names found in the signature of the instruction.
///
///
- public IEnumerable Operadns { get; }
+ public IEnumerable Operadns
+ {
+ get
+ {
+ var input = Regex.Match(Signature, SignaturePattern).Value[1..^1];
+
+ return !string.IsNullOrEmpty(input)
+ ? Regex.Split(input, ArgumentSplitPattern)
+ : Enumerable.Empty().ToArray();
+ }
+ }
///
/// The representation of the instruction instance.
@@ -184,7 +188,7 @@ public static Instruction Parse(string text)
var signature = Regex.Match(text, SignaturePattern).Value[1..^1];
var arguments = Regex.Split(signature, ArgumentSplitPattern).Select(Argument.Parse).ToArray();
- return _known.Value.TryGetValue(key, out var create)
+ return _known.TryGetValue(key, out var create)
? create().Of(arguments)
: new Instruction(key, arguments: arguments);
}
@@ -195,7 +199,7 @@ public static Instruction Parse(string text)
///
/// A containing all known instances with no arguments.
///
- public static IEnumerable Keys() => _known.Value.Keys.AsEnumerable();
+ public static IEnumerable Keys() => _known.Keys.AsEnumerable();
///
/// Retrieves teh argument for a specified operand name from the instruction.
@@ -218,6 +222,24 @@ public static Instruction Parse(string text)
return index >= 0 && index < Arguments.Count() ? Arguments.ElementAt(index) : default;
}
+ ///
+ /// Retrieves all values from this instruction instance's arguments.
+ ///
+ /// A collection of values cotnained by the instruction.
+ public IEnumerable Tags()
+ {
+ var tags = new List();
+
+ foreach (var argument in Arguments)
+ {
+ if (argument.IsTag) tags.Add((TagName)argument);
+ if (!argument.IsExpression) continue;
+ tags.AddRange(((NeutralText)argument).Tags());
+ }
+
+ return tags;
+ }
+
///
/// Creates a of the same type with the updated argument values.
///
@@ -269,20 +291,6 @@ public override bool Equals(object? obj)
/// true if the values are not equal; Otherwise, false.
public static bool operator !=(Instruction? left, Instruction? right) => !Equals(left, right);
- ///
- /// Implicitly converts the instance to a value.
- ///
- /// The instruction to convert.
- /// A representing the instrcution key.
- public static implicit operator string(Instruction instruction) => instruction.Key;
-
- ///
- /// Explicitly converts the value to an instance.
- ///
- /// The string key of the instrution.
- ///
- public static implicit operator Instruction(string key) => new(key, $"{key}()");
-
#region Factories
///
@@ -1706,18 +1714,12 @@ private static string DefaultArgs(int number)
return string.Join(',', Enumerable.Range(0, number).Select(i => $"arg{i}"));
}
- ///
- /// Lazy list of all known instructions and their corresponding factory method function.
- ///
- private static Lazy>> _known =>
- new(() => GetFactories().ToDictionary(x => x.Key, x => x.Value), LazyThreadSafetyMode.ExecutionAndPublication);
-
///
/// Indexes all instruction factory methods in the class and creates a function returning the instruction
/// mathcing the specified key or method name. The method is passed null argumnts and therefore will be a default
/// instruction instance. Callers can then use to pass argument array.
///
- private static IEnumerable>> GetFactories()
+ private static IEnumerable>> Factories()
{
var methods = typeof(Instruction).GetMethods(BindingFlags.Public | BindingFlags.Static)
.Where(m => m.ReturnType == typeof(Instruction) && m.Name.All(char.IsUpper));
diff --git a/src/L5Sharp/Common/NeutralText.cs b/src/L5Sharp/Common/NeutralText.cs
index 1cf1c35e..7291a89a 100644
--- a/src/L5Sharp/Common/NeutralText.cs
+++ b/src/L5Sharp/Common/NeutralText.cs
@@ -100,7 +100,7 @@ public IEnumerable Instructions(Instruction instruction) =>
/// Gets a collection of tag names found in the current neutral text.
///
/// A of values that were in from the current text.
- ///
+ ///
public IEnumerable Tags() => Regex.Matches(_text, TagName.SearchPattern).Select(t => new TagName(t.Value));
///
@@ -108,8 +108,7 @@ public IEnumerable Instructions(Instruction instruction) =>
///
/// The instruction for which to find tags as arguments to.
/// A containing tag names found in the specified instruction.
- public IEnumerable TagsIn(Instruction instruction) =>
- Instructions(instruction).SelectMany(i => i.Text.Tags());
+ public IEnumerable TagsIn(string instruction) => Instructions(instruction).SelectMany(i => i.Text.Tags());
///
public override string ToString() => _text;
diff --git a/src/L5Sharp/Elements/Chart.cs b/src/L5Sharp/Elements/Chart.cs
index 65d53e30..1412d93e 100644
--- a/src/L5Sharp/Elements/Chart.cs
+++ b/src/L5Sharp/Elements/Chart.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Xml.Linq;
using L5Sharp.Common;
using L5Sharp.Utilities;
@@ -32,10 +33,8 @@ public Chart(XElement element) : base(element)
///
public override int Number => 0;
- public override IEnumerable References()
- {
- throw new NotImplementedException();
- }
+ ///
+ public override IEnumerable References() => Enumerable.Empty();
///
protected override IEnumerable Ordering()
diff --git a/src/L5Sharp/Elements/Line.cs b/src/L5Sharp/Elements/Line.cs
index 685329f5..1865d97a 100644
--- a/src/L5Sharp/Elements/Line.cs
+++ b/src/L5Sharp/Elements/Line.cs
@@ -49,31 +49,33 @@ public override IEnumerable References()
{
var references = new List();
- foreach (var instruction in Text.Instructions())
+ var instructions = Text.Instructions().ToList();
+
+ foreach (var instruction in instructions)
{
- references.Add(new CrossReference(Element, L5XName.Instruction, instruction.Key, instruction));
+ references.Add(new CrossReference(Element, L5XName.Instruction, instruction.Key));
if (instruction.IsRoutineCall)
{
var routine = instruction.Arguments.FirstOrDefault()?.ToString() ?? string.Empty;
- references.Add(new CrossReference(Element, L5XName.Routine, routine, instruction));
+ references.Add(new CrossReference(Element, L5XName.Routine, routine, instruction.Key));
var parameters = instruction.Arguments.Skip(1).Where(a => a.IsTag).Select(t => t.ToString());
- references.AddRange(parameters.Select(p => new CrossReference(Element, L5XName.Tag, p, instruction)));
+ references.AddRange(parameters.Select(p => new CrossReference(Element, L5XName.Tag, p, instruction.Key)));
continue;
}
if (instruction.IsTaskCall)
{
var task = instruction.Arguments.FirstOrDefault()?.ToString() ?? string.Empty;
- references.Add(new CrossReference(Element, L5XName.Task, task, instruction));
+ references.Add(new CrossReference(Element, L5XName.Task, task, instruction.Key));
continue;
}
//todo other instructions like GSV SSV
- references.AddRange(instruction.Text.Tags()
- .Select(t => new CrossReference(Element, L5XName.Tag, t.ToString(), instruction)));
+ references.AddRange(instruction.Tags()
+ .Select(t => new CrossReference(Element, L5XName.Tag, t.ToString(), instruction.Key)));
}
return references;
diff --git a/src/L5Sharp/Elements/Rung.cs b/src/L5Sharp/Elements/Rung.cs
index e675f5a7..48766347 100644
--- a/src/L5Sharp/Elements/Rung.cs
+++ b/src/L5Sharp/Elements/Rung.cs
@@ -114,31 +114,33 @@ public override IEnumerable References()
{
var references = new List();
- foreach (var instruction in Text.Instructions())
+ var instructions = Text.Instructions().ToList();
+
+ foreach (var instruction in instructions)
{
- references.Add(new CrossReference(Element, L5XName.Instruction, instruction.Key, instruction));
+ references.Add(new CrossReference(Element, L5XName.Instruction, instruction.Key));
if (instruction.IsRoutineCall)
{
var routine = instruction.Arguments.FirstOrDefault()?.ToString() ?? string.Empty;
- references.Add(new CrossReference(Element, L5XName.Routine, routine, instruction));
+ references.Add(new CrossReference(Element, L5XName.Routine, routine, instruction.Key));
var parameters = instruction.Arguments.Skip(1).Where(a => a.IsTag).Select(t => t.ToString());
- references.AddRange(parameters.Select(p => new CrossReference(Element, L5XName.Tag, p, instruction)));
+ references.AddRange(parameters.Select(p => new CrossReference(Element, L5XName.Tag, p, instruction.Key)));
continue;
}
if (instruction.IsTaskCall)
{
var task = instruction.Arguments.FirstOrDefault()?.ToString() ?? string.Empty;
- references.Add(new CrossReference(Element, L5XName.Task, task, instruction));
+ references.Add(new CrossReference(Element, L5XName.Task, task, instruction.Key));
continue;
}
//todo other instructions like GSV SSV
- references.AddRange(instruction.Text.Tags()
- .Select(t => new CrossReference(Element, L5XName.Tag, t.ToString(), instruction)));
+ references.AddRange(instruction.Tags()
+ .Select(t => new CrossReference(Element, L5XName.Tag, t.ToString(), instruction.Key)));
}
return references;
diff --git a/src/L5Sharp/LogixComponent.cs b/src/L5Sharp/LogixComponent.cs
index 04540321..daf86624 100644
--- a/src/L5Sharp/LogixComponent.cs
+++ b/src/L5Sharp/LogixComponent.cs
@@ -90,7 +90,7 @@ public virtual string? Description
/// A value representing composite set of properties that identify this component
/// within an L5X tree.
///
- public ComponentKey Key => new(Element.Name.LocalName, Name);
+ public ComponentKey Key => new(GetType().L5XType(), Name);
///
/// Returns a collection of that this component depends on to be valid within a given
diff --git a/src/L5Sharp/LogixElement.cs b/src/L5Sharp/LogixElement.cs
index 6852ca77..17c42568 100644
--- a/src/L5Sharp/LogixElement.cs
+++ b/src/L5Sharp/LogixElement.cs
@@ -312,7 +312,7 @@ public void Replace(LogixElement element)
element = element.Convert(L5XType);
}
- Element.AddAfterSelf(element.Serialize());
+ Element.ReplaceWith(element.Serialize());
}
///
diff --git a/src/L5Sharp/LogixIndex.cs b/src/L5Sharp/LogixIndex.cs
index 02948daf..3d55013b 100644
--- a/src/L5Sharp/LogixIndex.cs
+++ b/src/L5Sharp/LogixIndex.cs
@@ -245,25 +245,25 @@ private void IndexDataTypeReferences()
///
private void IndexCodeReferences()
{
- var contentTypes = RoutineType.All().Select(r => r.ContentName).ToList();
-
- var targets = _content.Descendants().Where(e => contentTypes.Contains(e.Name.LocalName));
-
- foreach (var target in targets)
+ var routines = _content.Descendants(L5XName.Program).SelectMany(p => p.Descendants(L5XName.Routine));
+
+ foreach (var routine in routines)
{
- switch (target.Name.LocalName)
+ var type = routine.Attribute(L5XName.Type)?.Value.Parse().ContentName;
+
+ switch (type)
{
case L5XName.RLLContent:
- AddReferences(target.Descendants(L5XName.Rung).SelectMany(x => new Rung(x).References()));
+ AddReferences(routine.Descendants(L5XName.Rung).SelectMany(x => new Rung(x).References()));
break;
case L5XName.STContent:
- AddReferences(target.Descendants(L5XName.Line).SelectMany(x => new Line(x).References()));
+ AddReferences(routine.Descendants(L5XName.Line).SelectMany(x => new Line(x).References()));
break;
case L5XName.FBDContent:
- AddReferences(target.Descendants(L5XName.Sheet).SelectMany(x => new Sheet(x).References()));
+ AddReferences(routine.Descendants(L5XName.Sheet).SelectMany(x => new Sheet(x).References()));
break;
case L5XName.SFCContent:
- AddReferences(new Chart(target).References());
+ AddReferences(new Chart(routine).References());
break;
}
}
diff --git a/tests/L5Sharp.Tests/Common/NeutralTextTests.cs b/tests/L5Sharp.Tests/Common/NeutralTextTests.cs
index 09de5210..be75a7ce 100644
--- a/tests/L5Sharp.Tests/Common/NeutralTextTests.cs
+++ b/tests/L5Sharp.Tests/Common/NeutralTextTests.cs
@@ -31,7 +31,7 @@ public void New_EmptyString_ShouldBeSemiColon()
{
var text = new NeutralText(string.Empty);
- text.ToString().Should().Be(";");
+ text.ToString().Should().Be(string.Empty);
}
[Test]
@@ -164,7 +164,7 @@ public void Instructions_SingleInstruction_ShouldEqualOriginal()
var result = text.Instructions();
- result.First().Should().BeEquivalentTo(text);
+ result.First().Text.Should().Be(text);
}
[Test]
@@ -175,8 +175,8 @@ public void InstructionsBy_WithExistingInstructionPresent_ShouldContainExpectedT
var result = text.Instructions("XIC").ToList();
- result.Should().Contain("XIC(Tag.Status.Active)");
- result.Should().Contain("XIC(Tag.Status.Enabled)");
+ result.Should().Contain(Instruction.Parse("XIC(Tag.Status.Active)"));
+ result.Should().Contain(Instruction.Parse("XIC(Tag.Status.Enabled)"));
}
[Test]
diff --git a/tests/L5Sharp.Tests/Elements/BlockTests.cs b/tests/L5Sharp.Tests/Elements/BlockTests.cs
index 4bf8b4bd..857f57d6 100644
--- a/tests/L5Sharp.Tests/Elements/BlockTests.cs
+++ b/tests/L5Sharp.Tests/Elements/BlockTests.cs
@@ -231,6 +231,6 @@ public void References_WhenCalled_ShouldHaveExpectedCount()
var references = block.References().ToList();
- references.Should().HaveCount(2);
+ references.Should().NotBeEmpty();
}
}
\ No newline at end of file
diff --git a/tests/L5Sharp.Tests/Elements/ConnectionTests.cs b/tests/L5Sharp.Tests/Elements/ConnectionTests.cs
index 9e8ddf54..6d1b23ad 100644
--- a/tests/L5Sharp.Tests/Elements/ConnectionTests.cs
+++ b/tests/L5Sharp.Tests/Elements/ConnectionTests.cs
@@ -30,7 +30,7 @@ public void New_Default_ShouldHaveExpectedDefaults()
connection.InputSize.Should().Be(0);
connection.OutputCxnPoint.Should().Be(0);
connection.OutputSize.Should().Be(0);
- connection.Type.Should().BeNull();
+ connection.Type.Should().Be(ConnectionType.Unknown);
connection.Priority.Should().Be(ConnectionPriority.Scheduled);
connection.InputConnectionType.Should().Be(TransmissionType.Multicast);
connection.InputProductionTrigger.Should().Be(ProductionTrigger.Cyclic);
@@ -38,7 +38,7 @@ public void New_Default_ShouldHaveExpectedDefaults()
connection.Unicast.Should().BeFalse();
connection.EventId.Should().Be(0);
connection.InputTagSuffix.Should().Be("I");
- connection.InputTagSuffix.Should().Be("O");
+ connection.OutputTagSuffix.Should().Be("O");
connection.InputTag.Should().BeNull();
connection.OutputTag.Should().BeNull();
}
diff --git a/tests/L5Sharp.Tests/L5XDataTypeTests.Add_ValidComponent_ShouldBeVerified.verified.txt b/tests/L5Sharp.Tests/L5XDataTypeTests.Add_ValidComponent_ShouldBeVerified.verified.txt
index 423be399..aa5c2099 100644
--- a/tests/L5Sharp.Tests/L5XDataTypeTests.Add_ValidComponent_ShouldBeVerified.verified.txt
+++ b/tests/L5Sharp.Tests/L5XDataTypeTests.Add_ValidComponent_ShouldBeVerified.verified.txt
@@ -152,7 +152,7 @@ Dint Array]]>
-
+
diff --git a/tests/L5Sharp.Tests/L5XDataTypeTests.cs b/tests/L5Sharp.Tests/L5XDataTypeTests.cs
index 8a0d56f0..2e276abf 100644
--- a/tests/L5Sharp.Tests/L5XDataTypeTests.cs
+++ b/tests/L5Sharp.Tests/L5XDataTypeTests.cs
@@ -87,7 +87,7 @@ public void AddAfter_InvalidComponentType_ShouldThrowArgumentException()
var content = L5X.Load(Known.Test);
var dataType = content.DataTypes.Get(Known.DataType);
- FluentActions.Invoking(() => dataType.AddAfter(new Tag())).Should().Throw();
+ FluentActions.Invoking(() => dataType.AddAfter(new Tag())).Should().Throw();
}
[Test]
diff --git a/tests/L5Sharp.Tests/L5XTagTests.cs b/tests/L5Sharp.Tests/L5XTagTests.cs
index a75857f9..dd23491b 100644
--- a/tests/L5Sharp.Tests/L5XTagTests.cs
+++ b/tests/L5Sharp.Tests/L5XTagTests.cs
@@ -54,7 +54,8 @@ public void References_AgainstKnownTest_ShouldNotBeEmpty()
public void References_AgainstAllTags_ShouldNotBeEmpty()
{
var content = L5X.Load(Known.Example);
- var tags = content.Query().SelectMany(t => t.Members()).ToList();
+
+ var tags = content.Query().ToList();
var references = tags.Select(t => new {t.TagName, Refernces = t.References()}).ToList();
diff --git a/tests/L5Sharp.Tests/ProofTesting.cs b/tests/L5Sharp.Tests/ProofTesting.cs
index b1e293a4..06785416 100644
--- a/tests/L5Sharp.Tests/ProofTesting.cs
+++ b/tests/L5Sharp.Tests/ProofTesting.cs
@@ -36,32 +36,6 @@ public void Scratch()
references.Should().NotBeEmpty();
}
- [Test]
- public void GetInstructionMethods()
- {
-
-
-
- var type = typeof(Instruction);
-
- var method = type.GetMethods(BindingFlags.Public | BindingFlags.Static)
- .FirstOrDefault(m => m.ReturnType == typeof(Instruction) && m.Name == "XIO");
-
- var parameter = Expression.Parameter(typeof(Argument[]), "args");
-
- var function = Expression.Call(method!, parameter);
-
- var factory = Expression.Lambda>(function, parameter);
-
- var instruction = factory.Compile().Invoke(new Argument[]{"MyTagName"});
-
- instruction.Should().NotBeNull();
- instruction.Key.Should().Be("XIO");
- instruction.Signature.Should().Be("XIO(data_bit);");
- instruction.Text.Should().Be("XIO(MyTagName)");
- instruction.Arguments.Should().HaveCount(1);
- }
-
[Test]
public void Query()
{