summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Build.Tasks/CompiledMarkupExtensions/ArrayExtension.cs
blob: 06261147cbefae840a3a17b9d58992828e41302a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System.Collections.Generic;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;
using Xamarin.Forms.Xaml;

namespace Xamarin.Forms.Build.Tasks
{
	class ArrayExtension : ICompiledMarkupExtension
	{
		public IEnumerable<Instruction> ProvideValue(IElementNode node, ModuleDefinition module, ILContext context, out TypeReference memberRef)
		{
			var typeNode = node.Properties[new XmlName("", "Type")] as IElementNode;
			var typeTypeRef = context.TypeExtensions[typeNode];
			var n = node.CollectionItems.Count;

			var instructions = new List<Instruction>();
			instructions.Add(Instruction.Create(OpCodes.Ldc_I4, n));
			instructions.Add(Instruction.Create(OpCodes.Newarr, typeTypeRef));

			memberRef = typeTypeRef.MakeArrayType();
			for (var i = 0; i < n; i++) {
				instructions.Add(Instruction.Create(OpCodes.Dup));
				instructions.Add(Instruction.Create(OpCodes.Ldc_I4, i));
				instructions.Add(Instruction.Create(OpCodes.Ldloc, context.Variables[node.CollectionItems[i] as IElementNode]));
				instructions.Add(Instruction.Create(OpCodes.Stelem_Ref));
			}
			return instructions;
		}
	}
}