diff --git a/NuGetTest/Hast.NuGet.Console/Hast.NuGet.Console.csproj b/NuGetTest/Hast.NuGet.Console/Hast.NuGet.Console.csproj index f4c49234..221916f9 100644 --- a/NuGetTest/Hast.NuGet.Console/Hast.NuGet.Console.csproj +++ b/NuGetTest/Hast.NuGet.Console/Hast.NuGet.Console.csproj @@ -8,8 +8,8 @@ - - + + diff --git a/src/Hastlayer/Hast.Transformer.Vhdl/Verifiers/HardwareEntryPointsVerifier.cs b/src/Hastlayer/Hast.Transformer.Vhdl/Verifiers/HardwareEntryPointsVerifier.cs index ba563347..78cc28d8 100644 --- a/src/Hastlayer/Hast.Transformer.Vhdl/Verifiers/HardwareEntryPointsVerifier.cs +++ b/src/Hastlayer/Hast.Transformer.Vhdl/Verifiers/HardwareEntryPointsVerifier.cs @@ -36,7 +36,9 @@ private void VerifyHardwareEntryPoints(SyntaxTree syntaxTree, ITypeDeclarationLo { var unsupportedMembers = type .Members - .Where(member => member is FieldDeclaration || member is PropertyDeclaration || member.GetFullName().IsConstructorName()); + .Where(member => + (member is FieldDeclaration or PropertyDeclaration && !member.HasModifier(Modifiers.Const)) || + member.GetFullName().IsConstructorName()); if (unsupportedMembers.Any()) { throw new NotSupportedException( diff --git a/src/Hastlayer/Hast.Transformer/Models/IArraySizeHolder.cs b/src/Hastlayer/Hast.Transformer/Models/IArraySizeHolder.cs index 93422200..90cfc447 100644 --- a/src/Hastlayer/Hast.Transformer/Models/IArraySizeHolder.cs +++ b/src/Hastlayer/Hast.Transformer/Models/IArraySizeHolder.cs @@ -49,10 +49,10 @@ public static IArraySize GetSizeOrThrow(this IArraySizeHolder arraySizeHolder, A if (size == null) { throw new NotSupportedException( - "The length of the array holder " + arrayHolder.GetFullName() + - " couldn't be statically determined. Only arrays with dimensions defined at compile-time are " + - "supported. If the array size is actually static just Hastlayer can't figure it out for some " + - "reason then you can configure it manually via TransformerConfiguration."); + "The length of the array holder \"" + arrayHolder.GetFullName() + "\" couldn't be statically " + + "determined. Only arrays with dimensions defined at compile-time are supported. If the array size is " + + "actually static just Hastlayer can't figure it out for some reason then you can configure it " + + "manually via TransformerConfiguration by using the quoted full name."); } return size; diff --git a/src/Hastlayer/Hast.Transformer/Services/ConstantValuesSubstitution/ConstantValuesMarkingVisitor.cs b/src/Hastlayer/Hast.Transformer/Services/ConstantValuesSubstitution/ConstantValuesMarkingVisitor.cs index 4f303fe1..10ac37f4 100644 --- a/src/Hastlayer/Hast.Transformer/Services/ConstantValuesSubstitution/ConstantValuesMarkingVisitor.cs +++ b/src/Hastlayer/Hast.Transformer/Services/ConstantValuesSubstitution/ConstantValuesMarkingVisitor.cs @@ -215,6 +215,16 @@ private void PassLengthOfArrayHolderToParent(AstNode arrayHolder, int arrayLengt { AssignmentHandler = assignmentExpression => { + // Only assignments where an array is assigned to another member/variable matters, not just any + // assignment where arrayHolder is on the right (excluding cases where e.g. the right side is a + // method call with an array as an argument). + if (assignmentExpression.Right != arrayHolder && + assignmentExpression.Right is InvocationExpression invocationExpression && + invocationExpression.Target != arrayHolder) + { + return; + } + if (assignmentExpression.Left is MemberReferenceExpression memberReferenceExpression) { _arraySizeHolder.SetSize( diff --git a/src/Hastlayer/Hast.Transformer/Services/ConstantValuesSubstitution/ConstantValuesSubstitutingVisitor.cs b/src/Hastlayer/Hast.Transformer/Services/ConstantValuesSubstitution/ConstantValuesSubstitutingVisitor.cs index 03ead263..c3776ccd 100644 --- a/src/Hastlayer/Hast.Transformer/Services/ConstantValuesSubstitution/ConstantValuesSubstitutingVisitor.cs +++ b/src/Hastlayer/Hast.Transformer/Services/ConstantValuesSubstitution/ConstantValuesSubstitutingVisitor.cs @@ -256,9 +256,10 @@ protected override void VisitChildren(AstNode node) } } - // Is this a const? Then we can just substitute it directly. + // Is this a const expression? Then we can just substitute it directly. var resolveResult = node.GetResolveResult(); - if (resolveResult?.IsCompileTimeConstant == true && + if (node is Expression && + resolveResult?.IsCompileTimeConstant == true && resolveResult.ConstantValue != null && node is not PrimitiveExpression) { diff --git a/src/Samples/Hast.Samples.SampleAssembly/Hast.Samples.SampleAssembly.csproj b/src/Samples/Hast.Samples.SampleAssembly/Hast.Samples.SampleAssembly.csproj index e6d70928..2455902f 100644 --- a/src/Samples/Hast.Samples.SampleAssembly/Hast.Samples.SampleAssembly.csproj +++ b/src/Samples/Hast.Samples.SampleAssembly/Hast.Samples.SampleAssembly.csproj @@ -12,8 +12,8 @@ - - + + diff --git a/test/Hast.Transformer.Vhdl.Tests/VerificationTests/StaticTestInputAssembliesVerificationTests.cs b/test/Hast.Transformer.Vhdl.Tests/VerificationTests/StaticTestInputAssembliesVerificationTests.cs index 152671c1..59e6934b 100644 --- a/test/Hast.Transformer.Vhdl.Tests/VerificationTests/StaticTestInputAssembliesVerificationTests.cs +++ b/test/Hast.Transformer.Vhdl.Tests/VerificationTests/StaticTestInputAssembliesVerificationTests.cs @@ -30,7 +30,12 @@ public Task StaticTestInputAssemblyMatchesApproved() => new[] { typeof(ArrayUsingCases).Assembly }, configuration => { - configuration.TransformerConfiguration().UseSimpleMemory = false; + var transformerConfiguration = configuration.TransformerConfiguration(); + transformerConfiguration.UseSimpleMemory = false; + // This shouldn't be necessary: https://github.com/Lombiq/Hastlayer-SDK/issues/112. + transformerConfiguration.ArrayLengths.Add( + "System.Int32 Hast.TestInputs.Static.ArrayUsingCases+<>c::b__1_0(System.Object).arrayObject", + ArrayUsingCases.TaskArrayLength); configuration .TransformerConfiguration() diff --git a/test/Hast.Transformer.Vhdl.Tests/VerificationTests/VerificationSources/StaticTestInputAssembliesVerificationTests.StaticTestInputAssemblyMatchesApproved.approved.vhdl b/test/Hast.Transformer.Vhdl.Tests/VerificationTests/VerificationSources/StaticTestInputAssembliesVerificationTests.StaticTestInputAssemblyMatchesApproved.approved.vhdl index 5c7c2e10..81a06fb8 100644 --- a/test/Hast.Transformer.Vhdl.Tests/VerificationTests/VerificationSources/StaticTestInputAssembliesVerificationTests.StaticTestInputAssemblyMatchesApproved.approved.vhdl +++ b/test/Hast.Transformer.Vhdl.Tests/VerificationTests/VerificationSources/StaticTestInputAssembliesVerificationTests.StaticTestInputAssemblyMatchesApproved.approved.vhdl @@ -1,4 +1,5 @@ -- Generated by Hastlayer (hastlayer.com) at for the following hardware entry points: +-- * System.Void Hast.TestInputs.Static.ArrayUsingCases::PassArrayToTask() -- * System.Void Hast.TestInputs.Static.ArrayUsingCases::PassArrayToConstructor() -- * System.Void Hast.TestInputs.Static.ArrayUsingCases::PassArrayFromMethod() -- * System.Void Hast.TestInputs.Static.ConstantsUsingCases::ConstantValuedVariables(System.Int32) @@ -117,9 +118,9 @@ architecture Imp of Hast_IP is -- * The InternalInvocationProxy processes dispatch invocations between state machines. -- Custom inter-dependent type declarations start + type \unsigned8_Array\ is array (integer range <>) of unsigned(7 downto 0); type \signed32_Array\ is array (integer range <>) of signed(31 downto 0); type \unsigned32_Array\ is array (integer range <>) of unsigned(31 downto 0); - type \unsigned8_Array\ is array (integer range <>) of unsigned(7 downto 0); type \boolean_Array\ is array (integer range <>) of boolean; type \Hast.TestInputs.Static.ArrayUsingCases+ArrayHolder\ is record \IsNull\: boolean; @@ -167,6 +168,36 @@ architecture Imp of Hast_IP is -- System.Void Hast.TestInputs.Static.ArrayUsingCases+ArrayHolder::.ctor(System.Int32[]).0 declarations end + -- System.Int32 Hast.TestInputs.Static.ArrayUsingCases+<>c::b__1_0(System.Object).0 declarations start + -- State machine states: + type \ArrayUsingCases+<>c::b__1_0(Object).0._States\ is ( + \ArrayUsingCases+<>c::b__1_0(Object).0._State_0\, + \ArrayUsingCases+<>c::b__1_0(Object).0._State_1\, + \ArrayUsingCases+<>c::b__1_0(Object).0._State_2\); + -- Signals: + Signal \ArrayUsingCases+<>c::b__1_0(Object).0._Finished\: boolean := false; + Signal \ArrayUsingCases+<>c::b__1_0(Object).0.return\: signed(31 downto 0) := to_signed(0, 32); + Signal \ArrayUsingCases+<>c::b__1_0(Object).0.arrayObject.parameter.Out\: \signed32_Array\(0 to 9) := (others => to_signed(0, 32)); + Signal \ArrayUsingCases+<>c::b__1_0(Object).0._Started\: boolean := false; + Signal \ArrayUsingCases+<>c::b__1_0(Object).0.arrayObject.parameter.In\: \signed32_Array\(0 to 9) := (others => to_signed(0, 32)); + -- System.Int32 Hast.TestInputs.Static.ArrayUsingCases+<>c::b__1_0(System.Object).0 declarations end + + + -- System.Void Hast.TestInputs.Static.ArrayUsingCases::PassArrayToTask().0 declarations start + -- State machine states: + type \ArrayUsingCases::PassArrayToTask().0._States\ is ( + \ArrayUsingCases::PassArrayToTask().0._State_0\, + \ArrayUsingCases::PassArrayToTask().0._State_1\, + \ArrayUsingCases::PassArrayToTask().0._State_2\); + -- Signals: + Signal \ArrayUsingCases::PassArrayToTask().0._Finished\: boolean := false; + Signal \ArrayUsingCases::PassArrayToTask().0.ArrayUsingCases+<>c::b__1_0(Object).arrayObject.parameter.Out.0\: \signed32_Array\(0 to 9) := (others => to_signed(0, 32)); + Signal \ArrayUsingCases::PassArrayToTask().0.ArrayUsingCases+<>c::b__1_0(Object)._Started.0\: boolean := false; + Signal \ArrayUsingCases::PassArrayToTask().0._Started\: boolean := false; + Signal \ArrayUsingCases::PassArrayToTask().0.ArrayUsingCases+<>c::b__1_0(Object).arrayObject.parameter.In.0\: \signed32_Array\(0 to 9) := (others => to_signed(0, 32)); + -- System.Void Hast.TestInputs.Static.ArrayUsingCases::PassArrayToTask().0 declarations end + + -- System.Void Hast.TestInputs.Static.ArrayUsingCases::PassArrayToConstructor().0 declarations start -- State machine states: type \ArrayUsingCases::PassArrayToConstructor().0._States\ is ( @@ -786,6 +817,7 @@ architecture Imp of Hast_IP is -- System.Void Hast::ExternalInvocationProxy() declarations start -- Signals: Signal \FinishedInternal\: boolean := false; + Signal \Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayToTask()._Started.0\: boolean := false; Signal \Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayToConstructor()._Started.0\: boolean := false; Signal \Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayFromMethod()._Started.0\: boolean := false; Signal \Hast::ExternalInvocationProxy().ConstantsUsingCases::ConstantValuedVariables(Int32)._Started.0\: boolean := false; @@ -800,6 +832,7 @@ architecture Imp of Hast_IP is Signal \Hast::ExternalInvocationProxy().ParallelCases::WhenAllWhenAnyAwaitedTasks(UInt32)._Started.0\: boolean := false; Signal \Hast::ExternalInvocationProxy().ParallelCases::ObjectUsingTasks(UInt32)._Started.0\: boolean := false; Signal \Hast::ExternalInvocationProxy().UnaryCases::IncrementDecrement(Int32)._Started.0\: boolean := false; + Signal \Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayToTask()._Finished.0\: boolean := false; Signal \Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayToConstructor()._Finished.0\: boolean := false; Signal \Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayFromMethod()._Finished.0\: boolean := false; Signal \Hast::ExternalInvocationProxy().ConstantsUsingCases::ConstantValuedVariables(Int32)._Finished.0\: boolean := false; @@ -878,6 +911,123 @@ begin -- System.Void Hast.TestInputs.Static.ArrayUsingCases+ArrayHolder::.ctor(System.Int32[]).0 state machine end + -- System.Int32 Hast.TestInputs.Static.ArrayUsingCases+<>c::b__1_0(System.Object).0 state machine start + \ArrayUsingCases+<>c::b__1_0(Object).0._StateMachine\: process (\Clock\) + Variable \ArrayUsingCases+<>c::b__1_0(Object).0._State\: \ArrayUsingCases+<>c::b__1_0(Object).0._States\ := \ArrayUsingCases+<>c::b__1_0(Object).0._State_0\; + Variable \ArrayUsingCases+<>c::b__1_0(Object).0.arrayObject\: \signed32_Array\(0 to 9) := (others => to_signed(0, 32)); + begin + if (rising_edge(\Clock\)) then + if (\Reset\ = '1') then + -- Synchronous reset + \ArrayUsingCases+<>c::b__1_0(Object).0._Finished\ <= false; + \ArrayUsingCases+<>c::b__1_0(Object).0.return\ <= to_signed(0, 32); + \ArrayUsingCases+<>c::b__1_0(Object).0.arrayObject.parameter.Out\ <= (others => to_signed(0, 32)); + \ArrayUsingCases+<>c::b__1_0(Object).0._State\ := \ArrayUsingCases+<>c::b__1_0(Object).0._State_0\; + \ArrayUsingCases+<>c::b__1_0(Object).0.arrayObject\ := (others => to_signed(0, 32)); + else + case \ArrayUsingCases+<>c::b__1_0(Object).0._State\ is + when \ArrayUsingCases+<>c::b__1_0(Object).0._State_0\ => + -- Start state + -- Waiting for the start signal. + if (\ArrayUsingCases+<>c::b__1_0(Object).0._Started\ = true) then + \ArrayUsingCases+<>c::b__1_0(Object).0._State\ := \ArrayUsingCases+<>c::b__1_0(Object).0._State_2\; + end if; + -- Clock cycles needed to complete this state (approximation): 0 + when \ArrayUsingCases+<>c::b__1_0(Object).0._State_1\ => + -- Final state + -- Signaling finished until Started is pulled back to false, then returning to the start state. + if (\ArrayUsingCases+<>c::b__1_0(Object).0._Started\ = true) then + \ArrayUsingCases+<>c::b__1_0(Object).0._Finished\ <= true; + else + \ArrayUsingCases+<>c::b__1_0(Object).0._Finished\ <= false; + \ArrayUsingCases+<>c::b__1_0(Object).0._State\ := \ArrayUsingCases+<>c::b__1_0(Object).0._State_0\; + end if; + -- Writing back out-flowing parameters so any changes made in this state machine will be reflected in the invoking one too. + \ArrayUsingCases+<>c::b__1_0(Object).0.arrayObject.parameter.Out\ <= \ArrayUsingCases+<>c::b__1_0(Object).0.arrayObject\; + -- Clock cycles needed to complete this state (approximation): 0 + when \ArrayUsingCases+<>c::b__1_0(Object).0._State_2\ => + \ArrayUsingCases+<>c::b__1_0(Object).0.arrayObject\ := \ArrayUsingCases+<>c::b__1_0(Object).0.arrayObject.parameter.In\; + -- The following section was transformed from the .NET statement below: + -- arrayObject [0] = 123; + -- + \ArrayUsingCases+<>c::b__1_0(Object).0.arrayObject\(to_integer(to_signed(0, 32))) := to_signed(123, 32); + -- The following section was transformed from the .NET statement below: + -- return arrayObject [0]; + -- + \ArrayUsingCases+<>c::b__1_0(Object).0.return\ <= \ArrayUsingCases+<>c::b__1_0(Object).0.arrayObject\(to_integer(to_signed(0, 32))); + \ArrayUsingCases+<>c::b__1_0(Object).0._State\ := \ArrayUsingCases+<>c::b__1_0(Object).0._State_1\; + -- Clock cycles needed to complete this state (approximation): 0 + end case; + end if; + end if; + end process; + -- System.Int32 Hast.TestInputs.Static.ArrayUsingCases+<>c::b__1_0(System.Object).0 state machine end + + + -- System.Void Hast.TestInputs.Static.ArrayUsingCases::PassArrayToTask().0 state machine start + \ArrayUsingCases::PassArrayToTask().0._StateMachine\: process (\Clock\) + Variable \ArrayUsingCases::PassArrayToTask().0._State\: \ArrayUsingCases::PassArrayToTask().0._States\ := \ArrayUsingCases::PassArrayToTask().0._State_0\; + Variable \ArrayUsingCases::PassArrayToTask().0.state\: \signed32_Array\(0 to 9) := (others => to_signed(0, 32)); + Variable \ArrayUsingCases::PassArrayToTask().0.array\: \signed32_Array\(0 to 14) := (others => to_signed(0, 32)); + begin + if (rising_edge(\Clock\)) then + if (\Reset\ = '1') then + -- Synchronous reset + \ArrayUsingCases::PassArrayToTask().0._Finished\ <= false; + \ArrayUsingCases::PassArrayToTask().0.ArrayUsingCases+<>c::b__1_0(Object).arrayObject.parameter.Out.0\ <= (others => to_signed(0, 32)); + \ArrayUsingCases::PassArrayToTask().0.ArrayUsingCases+<>c::b__1_0(Object)._Started.0\ <= false; + \ArrayUsingCases::PassArrayToTask().0._State\ := \ArrayUsingCases::PassArrayToTask().0._State_0\; + \ArrayUsingCases::PassArrayToTask().0.state\ := (others => to_signed(0, 32)); + \ArrayUsingCases::PassArrayToTask().0.array\ := (others => to_signed(0, 32)); + else + case \ArrayUsingCases::PassArrayToTask().0._State\ is + when \ArrayUsingCases::PassArrayToTask().0._State_0\ => + -- Start state + -- Waiting for the start signal. + if (\ArrayUsingCases::PassArrayToTask().0._Started\ = true) then + \ArrayUsingCases::PassArrayToTask().0._State\ := \ArrayUsingCases::PassArrayToTask().0._State_2\; + end if; + -- Clock cycles needed to complete this state (approximation): 0 + when \ArrayUsingCases::PassArrayToTask().0._State_1\ => + -- Final state + -- Signaling finished until Started is pulled back to false, then returning to the start state. + if (\ArrayUsingCases::PassArrayToTask().0._Started\ = true) then + \ArrayUsingCases::PassArrayToTask().0._Finished\ <= true; + else + \ArrayUsingCases::PassArrayToTask().0._Finished\ <= false; + \ArrayUsingCases::PassArrayToTask().0._State\ := \ArrayUsingCases::PassArrayToTask().0._State_0\; + end if; + -- Clock cycles needed to complete this state (approximation): 0 + when \ArrayUsingCases::PassArrayToTask().0._State_2\ => + -- The following section was transformed from the .NET statement below: + -- int[] state; + -- + -- The following section was transformed from the .NET statement below: + -- state = new int[10]; + -- + \ArrayUsingCases::PassArrayToTask().0.state\ := (others => to_signed(0, 32)); + -- The following section was transformed from the .NET statement below: + -- Task[] array; + -- + -- The following section was transformed from the .NET statement below: + -- array = new Task[15]; + -- + \ArrayUsingCases::PassArrayToTask().0.array\ := (others => to_signed(0, 32)); + -- The following section was transformed from the .NET statement below: + -- array [0] = Task.Factory.StartNew (<>c.<>9__1_0 ?? (<>c.<>9__1_0 = <>c.<>9.b__1_0), state); + -- + -- Starting state machine invocation for the following method: System.Int32 Hast.TestInputs.Static.ArrayUsingCases+<>c::b__1_0(System.Object) + \ArrayUsingCases::PassArrayToTask().0.ArrayUsingCases+<>c::b__1_0(Object).arrayObject.parameter.Out.0\ <= \ArrayUsingCases::PassArrayToTask().0.state\; + \ArrayUsingCases::PassArrayToTask().0.ArrayUsingCases+<>c::b__1_0(Object)._Started.0\ <= true; + \ArrayUsingCases::PassArrayToTask().0._State\ := \ArrayUsingCases::PassArrayToTask().0._State_1\; + -- Clock cycles needed to complete this state (approximation): 0 + end case; + end if; + end if; + end process; + -- System.Void Hast.TestInputs.Static.ArrayUsingCases::PassArrayToTask().0 state machine end + + -- System.Void Hast.TestInputs.Static.ArrayUsingCases::PassArrayToConstructor().0 state machine start \ArrayUsingCases::PassArrayToConstructor().0._StateMachine\: process (\Clock\) Variable \ArrayUsingCases::PassArrayToConstructor().0._State\: \ArrayUsingCases::PassArrayToConstructor().0._States\ := \ArrayUsingCases::PassArrayToConstructor().0._State_0\; @@ -4197,6 +4347,7 @@ begin if (\Reset\ = '1') then -- Synchronous reset \FinishedInternal\ <= false; + \Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayToTask()._Started.0\ <= false; \Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayToConstructor()._Started.0\ <= false; \Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayFromMethod()._Started.0\ <= false; \Hast::ExternalInvocationProxy().ConstantsUsingCases::ConstantValuedVariables(Int32)._Started.0\ <= false; @@ -4216,97 +4367,104 @@ begin -- Starting the state machine corresponding to the given member ID. case \MemberId\ is when 0 => + if (\Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayToTask()._Started.0\ = false) then + \Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayToTask()._Started.0\ <= true; + elsif (\Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayToTask()._Started.0\ = \Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayToTask()._Finished.0\) then + \Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayToTask()._Started.0\ <= false; + \FinishedInternal\ <= true; + end if; + when 1 => if (\Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayToConstructor()._Started.0\ = false) then \Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayToConstructor()._Started.0\ <= true; elsif (\Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayToConstructor()._Started.0\ = \Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayToConstructor()._Finished.0\) then \Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayToConstructor()._Started.0\ <= false; \FinishedInternal\ <= true; end if; - when 1 => + when 2 => if (\Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayFromMethod()._Started.0\ = false) then \Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayFromMethod()._Started.0\ <= true; elsif (\Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayFromMethod()._Started.0\ = \Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayFromMethod()._Finished.0\) then \Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayFromMethod()._Started.0\ <= false; \FinishedInternal\ <= true; end if; - when 2 => + when 3 => if (\Hast::ExternalInvocationProxy().ConstantsUsingCases::ConstantValuedVariables(Int32)._Started.0\ = false) then \Hast::ExternalInvocationProxy().ConstantsUsingCases::ConstantValuedVariables(Int32)._Started.0\ <= true; elsif (\Hast::ExternalInvocationProxy().ConstantsUsingCases::ConstantValuedVariables(Int32)._Started.0\ = \Hast::ExternalInvocationProxy().ConstantsUsingCases::ConstantValuedVariables(Int32)._Finished.0\) then \Hast::ExternalInvocationProxy().ConstantsUsingCases::ConstantValuedVariables(Int32)._Started.0\ <= false; \FinishedInternal\ <= true; end if; - when 3 => + when 4 => if (\Hast::ExternalInvocationProxy().ConstantsUsingCases::ConstantPassingToMethod(Int32)._Started.0\ = false) then \Hast::ExternalInvocationProxy().ConstantsUsingCases::ConstantPassingToMethod(Int32)._Started.0\ <= true; elsif (\Hast::ExternalInvocationProxy().ConstantsUsingCases::ConstantPassingToMethod(Int32)._Started.0\ = \Hast::ExternalInvocationProxy().ConstantsUsingCases::ConstantPassingToMethod(Int32)._Finished.0\) then \Hast::ExternalInvocationProxy().ConstantsUsingCases::ConstantPassingToMethod(Int32)._Started.0\ <= false; \FinishedInternal\ <= true; end if; - when 4 => + when 5 => if (\Hast::ExternalInvocationProxy().ConstantsUsingCases::ConstantPassingToObject()._Started.0\ = false) then \Hast::ExternalInvocationProxy().ConstantsUsingCases::ConstantPassingToObject()._Started.0\ <= true; elsif (\Hast::ExternalInvocationProxy().ConstantsUsingCases::ConstantPassingToObject()._Started.0\ = \Hast::ExternalInvocationProxy().ConstantsUsingCases::ConstantPassingToObject()._Finished.0\) then \Hast::ExternalInvocationProxy().ConstantsUsingCases::ConstantPassingToObject()._Started.0\ <= false; \FinishedInternal\ <= true; end if; - when 5 => + when 6 => if (\Hast::ExternalInvocationProxy().LoopCases::BreakInLoop(Int32)._Started.0\ = false) then \Hast::ExternalInvocationProxy().LoopCases::BreakInLoop(Int32)._Started.0\ <= true; elsif (\Hast::ExternalInvocationProxy().LoopCases::BreakInLoop(Int32)._Started.0\ = \Hast::ExternalInvocationProxy().LoopCases::BreakInLoop(Int32)._Finished.0\) then \Hast::ExternalInvocationProxy().LoopCases::BreakInLoop(Int32)._Started.0\ <= false; \FinishedInternal\ <= true; end if; - when 6 => + when 7 => if (\Hast::ExternalInvocationProxy().LoopCases::BreakInLoopInLoop(Int32)._Started.0\ = false) then \Hast::ExternalInvocationProxy().LoopCases::BreakInLoopInLoop(Int32)._Started.0\ <= true; elsif (\Hast::ExternalInvocationProxy().LoopCases::BreakInLoopInLoop(Int32)._Started.0\ = \Hast::ExternalInvocationProxy().LoopCases::BreakInLoopInLoop(Int32)._Finished.0\) then \Hast::ExternalInvocationProxy().LoopCases::BreakInLoopInLoop(Int32)._Started.0\ <= false; \FinishedInternal\ <= true; end if; - when 7 => + when 8 => if (\Hast::ExternalInvocationProxy().ObjectUsingCases::NullUsage()._Started.0\ = false) then \Hast::ExternalInvocationProxy().ObjectUsingCases::NullUsage()._Started.0\ <= true; elsif (\Hast::ExternalInvocationProxy().ObjectUsingCases::NullUsage()._Started.0\ = \Hast::ExternalInvocationProxy().ObjectUsingCases::NullUsage()._Finished.0\) then \Hast::ExternalInvocationProxy().ObjectUsingCases::NullUsage()._Started.0\ <= false; \FinishedInternal\ <= true; end if; - when 8 => + when 9 => if (\Hast::ExternalInvocationProxy().ObjectUsingCases::VoidReturn(Int32)._Started.0\ = false) then \Hast::ExternalInvocationProxy().ObjectUsingCases::VoidReturn(Int32)._Started.0\ <= true; elsif (\Hast::ExternalInvocationProxy().ObjectUsingCases::VoidReturn(Int32)._Started.0\ = \Hast::ExternalInvocationProxy().ObjectUsingCases::VoidReturn(Int32)._Finished.0\) then \Hast::ExternalInvocationProxy().ObjectUsingCases::VoidReturn(Int32)._Started.0\ <= false; \FinishedInternal\ <= true; end if; - when 9 => + when 10 => if (\Hast::ExternalInvocationProxy().ObjectUsingCases::ReferenceAssignment(Int32)._Started.0\ = false) then \Hast::ExternalInvocationProxy().ObjectUsingCases::ReferenceAssignment(Int32)._Started.0\ <= true; elsif (\Hast::ExternalInvocationProxy().ObjectUsingCases::ReferenceAssignment(Int32)._Started.0\ = \Hast::ExternalInvocationProxy().ObjectUsingCases::ReferenceAssignment(Int32)._Finished.0\) then \Hast::ExternalInvocationProxy().ObjectUsingCases::ReferenceAssignment(Int32)._Started.0\ <= false; \FinishedInternal\ <= true; end if; - when 10 => + when 11 => if (\Hast::ExternalInvocationProxy().OptionaParametersCases::OmittedOptionalParameters(Int32)._Started.0\ = false) then \Hast::ExternalInvocationProxy().OptionaParametersCases::OmittedOptionalParameters(Int32)._Started.0\ <= true; elsif (\Hast::ExternalInvocationProxy().OptionaParametersCases::OmittedOptionalParameters(Int32)._Started.0\ = \Hast::ExternalInvocationProxy().OptionaParametersCases::OmittedOptionalParameters(Int32)._Finished.0\) then \Hast::ExternalInvocationProxy().OptionaParametersCases::OmittedOptionalParameters(Int32)._Started.0\ <= false; \FinishedInternal\ <= true; end if; - when 11 => + when 12 => if (\Hast::ExternalInvocationProxy().ParallelCases::WhenAllWhenAnyAwaitedTasks(UInt32)._Started.0\ = false) then \Hast::ExternalInvocationProxy().ParallelCases::WhenAllWhenAnyAwaitedTasks(UInt32)._Started.0\ <= true; elsif (\Hast::ExternalInvocationProxy().ParallelCases::WhenAllWhenAnyAwaitedTasks(UInt32)._Started.0\ = \Hast::ExternalInvocationProxy().ParallelCases::WhenAllWhenAnyAwaitedTasks(UInt32)._Finished.0\) then \Hast::ExternalInvocationProxy().ParallelCases::WhenAllWhenAnyAwaitedTasks(UInt32)._Started.0\ <= false; \FinishedInternal\ <= true; end if; - when 12 => + when 13 => if (\Hast::ExternalInvocationProxy().ParallelCases::ObjectUsingTasks(UInt32)._Started.0\ = false) then \Hast::ExternalInvocationProxy().ParallelCases::ObjectUsingTasks(UInt32)._Started.0\ <= true; elsif (\Hast::ExternalInvocationProxy().ParallelCases::ObjectUsingTasks(UInt32)._Started.0\ = \Hast::ExternalInvocationProxy().ParallelCases::ObjectUsingTasks(UInt32)._Finished.0\) then \Hast::ExternalInvocationProxy().ParallelCases::ObjectUsingTasks(UInt32)._Started.0\ <= false; \FinishedInternal\ <= true; end if; - when 13 => + when 14 => if (\Hast::ExternalInvocationProxy().UnaryCases::IncrementDecrement(Int32)._Started.0\ = false) then \Hast::ExternalInvocationProxy().UnaryCases::IncrementDecrement(Int32)._Started.0\ <= true; elsif (\Hast::ExternalInvocationProxy().UnaryCases::IncrementDecrement(Int32)._Started.0\ = \Hast::ExternalInvocationProxy().UnaryCases::IncrementDecrement(Int32)._Finished.0\) then @@ -4328,6 +4486,16 @@ begin -- System.Void Hast::ExternalInvocationProxy() end + -- System.Void Hast::InternalInvocationProxy().System.Int32 Hast.TestInputs.Static.ArrayUsingCases+<>c::b__1_0(System.Object) start + -- Signal connections for System.Void Hast.TestInputs.Static.ArrayUsingCases::PassArrayToTask().0 (#0): + \ArrayUsingCases+<>c::b__1_0(Object).0._Started\ <= \ArrayUsingCases::PassArrayToTask().0.ArrayUsingCases+<>c::b__1_0(Object)._Started.0\; + \ArrayUsingCases+<>c::b__1_0(Object).0.arrayObject.parameter.In\ <= \ArrayUsingCases::PassArrayToTask().0.ArrayUsingCases+<>c::b__1_0(Object).arrayObject.parameter.Out.0\; + \ArrayUsingCases::PassArrayToTask().0.ArrayUsingCases+<>c::b__1_0(Object)._Finished.0\ <= \ArrayUsingCases+<>c::b__1_0(Object).0._Finished\; + \ArrayUsingCases::PassArrayToTask().0.ArrayUsingCases+<>c::b__1_0(Object).return.0\ <= \ArrayUsingCases+<>c::b__1_0(Object).0.return\; + \ArrayUsingCases::PassArrayToTask().0.ArrayUsingCases+<>c::b__1_0(Object).arrayObject.parameter.In.0\ <= \ArrayUsingCases+<>c::b__1_0(Object).0.arrayObject.parameter.Out\; + -- System.Void Hast::InternalInvocationProxy().System.Int32 Hast.TestInputs.Static.ArrayUsingCases+<>c::b__1_0(System.Object) end + + -- System.Void Hast::InternalInvocationProxy().System.Void Hast.TestInputs.Static.ArrayUsingCases+ArrayHolder::.ctor(System.Int32[]) start -- Signal connections for System.Void Hast.TestInputs.Static.ArrayUsingCases::PassArrayToConstructor().0 (#0): \ArrayUsingCases+ArrayHolder::.ctor(Int32[]).0._Started\ <= \ArrayUsingCases::PassArrayToConstructor().0.ArrayUsingCases+ArrayHolder::.ctor(Int32[])._Started.0\; @@ -4565,6 +4733,13 @@ begin -- System.Void Hast::InternalInvocationProxy().System.Boolean Hast.TestInputs.Static.ParallelCases+<>c__DisplayClass1_0::b__0(System.Object) end + -- System.Void Hast::InternalInvocationProxy().System.Void Hast.TestInputs.Static.ArrayUsingCases::PassArrayToTask() start + -- Signal connections for System.Void Hast::ExternalInvocationProxy() (#0): + \ArrayUsingCases::PassArrayToTask().0._Started\ <= \Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayToTask()._Started.0\; + \Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayToTask()._Finished.0\ <= \ArrayUsingCases::PassArrayToTask().0._Finished\; + -- System.Void Hast::InternalInvocationProxy().System.Void Hast.TestInputs.Static.ArrayUsingCases::PassArrayToTask() end + + -- System.Void Hast::InternalInvocationProxy().System.Void Hast.TestInputs.Static.ArrayUsingCases::PassArrayToConstructor() start -- Signal connections for System.Void Hast::ExternalInvocationProxy() (#0): \ArrayUsingCases::PassArrayToConstructor().0._Started\ <= \Hast::ExternalInvocationProxy().ArrayUsingCases::PassArrayToConstructor()._Started.0\; diff --git a/test/TestInputAssemblies/Hast.TestInputs.Static/ArrayUsingCases.cs b/test/TestInputAssemblies/Hast.TestInputs.Static/ArrayUsingCases.cs index 2f3952ab..095a9421 100644 --- a/test/TestInputAssemblies/Hast.TestInputs.Static/ArrayUsingCases.cs +++ b/test/TestInputAssemblies/Hast.TestInputs.Static/ArrayUsingCases.cs @@ -1,7 +1,26 @@ +using System.Threading.Tasks; + namespace Hast.TestInputs.Static; public class ArrayUsingCases { + public const int TaskArrayLength = 10; + + public void PassArrayToTask() + { + var array = new int[TaskArrayLength]; + var tasks = new Task[15]; + + tasks[0] = Task.Factory.StartNew( + arrayObject => + { + var localArray = (int[])arrayObject; + localArray[0] = 123; + return localArray[0]; + }, + array); + } + public void PassArrayToConstructor() { var array = new int[5]; diff --git a/test/TestInputAssemblies/Hast.TestInputs.Static/GlobalSuppressions.cs b/test/TestInputAssemblies/Hast.TestInputs.Static/GlobalSuppressions.cs index 534de752..80ec9e8e 100644 --- a/test/TestInputAssemblies/Hast.TestInputs.Static/GlobalSuppressions.cs +++ b/test/TestInputAssemblies/Hast.TestInputs.Static/GlobalSuppressions.cs @@ -35,3 +35,11 @@ "S3353:Unchanged local variables should be \"const\"", Justification = ThatsThePoint, Scope = "module")] +[assembly: SuppressMessage( + "Reliability", + "CA2008:Do not create tasks without passing a TaskScheduler", + Justification = "Can't do it without passing CancellationToken which is not supported.")] +[assembly: SuppressMessage( + "Usage", + "VSTHRD105:Avoid method overloads that assume TaskScheduler.Current", + Justification = "Can't do it without passing CancellationToken which is not supported.")] diff --git a/test/TestInputAssemblies/Hast.TestInputs.Static/ParallelCases.cs b/test/TestInputAssemblies/Hast.TestInputs.Static/ParallelCases.cs index 50fbec5c..31d7940b 100644 --- a/test/TestInputAssemblies/Hast.TestInputs.Static/ParallelCases.cs +++ b/test/TestInputAssemblies/Hast.TestInputs.Static/ParallelCases.cs @@ -10,9 +10,6 @@ public void WhenAllWhenAnyAwaitedTasks(uint input) for (uint i = 0; i < 3; i++) { - // Can't do it without passing CancellationToken which is not supported. -#pragma warning disable CA2008 // Do not create tasks without passing a TaskScheduler -#pragma warning disable VSTHRD105 // Avoid method overloads that assume TaskScheduler.Current tasks[i] = Task.Factory.StartNew( indexObject => { @@ -21,8 +18,6 @@ public void WhenAllWhenAnyAwaitedTasks(uint input) return index % 2 == 0; }, i); -#pragma warning restore VSTHRD105 // Avoid method overloads that assume TaskScheduler.Current -#pragma warning restore CA2008 // Do not create tasks without passing a TaskScheduler } // These two after each other don't make sense, but the test result will be still usable just for static @@ -37,9 +32,6 @@ public void ObjectUsingTasks(uint input) for (uint i = 0; i < 3; i++) { - // Can't do it without passing CancellationToken which is not supported. -#pragma warning disable CA2008 // Do not create tasks without passing a TaskScheduler -#pragma warning disable VSTHRD105 // Avoid method overloads that assume TaskScheduler.Current tasks[i] = Task.Factory.StartNew( indexObject => { @@ -48,8 +40,6 @@ public void ObjectUsingTasks(uint input) return new Calculator { Number = index }.IsEven(); }, i); -#pragma warning restore VSTHRD105 // Avoid method overloads that assume TaskScheduler.Current -#pragma warning restore CA2008 // Do not create tasks without passing a TaskScheduler } Task.WhenAll(tasks).Wait();