1 module tooling.SortRange;
2 
3 import std.algorithm, std.array, std.file, std.stdio, std.exception, std.conv;
4 
5 import tooling.Scanner;
6 import tooling.TreeRange;
7 import tooling.Tokenizer;
8 import tooling.TokenRange;
9 
10 auto sortFunctionsRange(Token[] tokens)
11 {
12   struct Result
13   {
14 	this(Token[] tokens)
15 	{
16 	  tokenRange_ = tokens.namespaceTokenRange;
17 	}
18 
19 	bool empty() { return tokenRange_.empty; }
20 	Token front()
21 	{
22 	  if (!functionTokens_.empty)
23 	  {
24 		return functionTokens_.front;
25 	  }
26 	  else
27 	  {
28 		return tokenRange_.front.token_;
29 	  }
30 	}
31 	Result save() { return this; }
32 	void popFront()
33 	{
34 	  if (!functionTokens_.empty)
35 	  {
36 		functionTokens_.popFront();
37 	  }
38 	  else
39 	  {
40 		tokenRange_.popFront();
41 		if (!tokenRange_.empty)
42 		{
43 		  auto t = tokenRange_.front;
44 		  if (t.entity_)
45 		  {
46 			if (isNamespace(t.entity_))
47 			{
48 			  if (t.token_.value == "{")
49 			  {
50 				entityStack_.length += 1;
51 			  }
52 			  else if (t.token_.value == "}")
53 			  {
54 				auto names = entityStack_
55 				  .back
56 				  .keys
57 				  .array
58 				  .sort
59 				  .map!(name => entityStack_.back[name].tokens_);
60 				if (!names.empty)
61 				{
62 				  functionTokens_ = names.reduce!((tokens, t) => tokens ~ t);
63 				}
64 				entityStack_.popBack;
65 			  }
66 			}
67 			else if (isFunction(t.entity_))
68 			{
69 			  if (t.entity_.name !in entityStack_.back)
70 			  {
71 				entityStack_.back[t.entity_.name] = t.entity_;
72 			  }
73 			  popFront;
74 			}
75 		  }
76 		}
77 	  }
78 	}
79 
80 	TokenRangeResult tokenRange_;
81 	Token[] functionTokens_;
82 	Entity[string][] entityStack_;
83   }
84 
85   return Result(tokens);
86 }