annotate Implab.ServiceHost/Unity/TypeReferenceParser.cs @ 272:9d1cca834b05 v3

preview version of Unity xml configuration
author cin
date Thu, 26 Apr 2018 03:14:54 +0300
parents ff581cff7003
children 963b17c275be
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
267
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
1 using System;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
2 using System.Collections.Generic;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
3 using System.Text.RegularExpressions;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
4
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
5 namespace Implab.ServiceHost.Unity {
268
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
6 internal class TypeReferenceParser {
267
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
7 enum TokenType {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
8 None,
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
9
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
10 Word,
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
11
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
12 Dot,
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
13
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
14 Comma,
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
15
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
16 OpenList,
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
17
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
18 CloseList,
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
19
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
20 Eof
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
21 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
22
269
ff581cff7003 Working on Unity container xml configuration
cin
parents: 268
diff changeset
23 readonly Regex _tokens = new Regex(@"([\w\+]+)|\s*([\.{},])\s*");
267
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
24
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
25 TokenType m_token;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
26
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
27 string m_tokenValue;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
28
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
29 int m_pos;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
30
268
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
31 int m_tokenPos;
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
32
267
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
33 readonly string m_text;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
34
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
35 TokenType Token { get { return m_token; } }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
36
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
37 string TokenValue { get { return m_tokenValue; } }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
38
268
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
39 int TokenPos { get { return m_tokenPos; } }
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
40
267
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
41 public TypeReferenceParser(string text) {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
42 Safe.ArgumentNotEmpty(text, nameof(text));
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
43 m_text = text;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
44 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
45
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
46 bool ReadToken() {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
47 if (m_pos >= m_text.Length) {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
48 m_token = TokenType.Eof;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
49 m_tokenValue = null;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
50 return false;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
51 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
52
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
53 var m = _tokens.Match(m_text, m_pos);
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
54
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
55 if (m.Success) {
268
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
56 m_tokenPos = m_pos;
267
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
57 m_pos += m.Length;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
58 if (m.Groups[1].Success) {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
59 m_token = TokenType.Word;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
60 m_tokenValue = m.Groups[1].Value;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
61 } else if (m.Groups[2].Success) {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
62 m_tokenValue = null;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
63 switch (m.Groups[2].Value) {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
64 case "{":
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
65 m_token = TokenType.OpenList;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
66 break;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
67 case "}":
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
68 m_token = TokenType.CloseList;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
69 break;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
70 case ".":
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
71 m_token = TokenType.Dot;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
72 break;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
73 case ",":
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
74 m_token = TokenType.Comma;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
75 break;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
76 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
77 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
78 return true;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
79 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
80 throw new FormatException($"Failed to parse '{m_text}' at pos {m_pos}");
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
81 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
82
268
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
83 public TypeReference Parse() {
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
84 var result = ReadTypeReference();
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
85 if (ReadToken())
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
86 ThrowUnexpectedToken();
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
87 return result;
267
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
88 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
89
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
90 string[] ReadTypeName() {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
91 var parts = new List<string>();
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
92
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
93 string current = null;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
94 bool stop = false;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
95 while ((!stop) && ReadToken()) {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
96 switch (Token) {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
97 case TokenType.Word:
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
98 if (current != null)
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
99 ThrowUnexpectedToken();
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
100 current = TokenValue;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
101 break;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
102 case TokenType.Dot:
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
103 if (current == null)
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
104 ThrowUnexpectedToken();
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
105 parts.Add(current);
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
106 current = null;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
107 break;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
108 default:
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
109 stop = true;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
110 break;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
111 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
112 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
113 if (current != null)
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
114 parts.Add(current);
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
115
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
116 if (parts.Count == 0)
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
117 return null;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
118
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
119 return parts.ToArray();
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
120 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
121
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
122 TypeReference ReadTypeReference() {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
123
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
124 var parts = ReadTypeName();
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
125 if (parts == null)
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
126 return null;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
127
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
128 var typeReference = new TypeReference {
268
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
129 Namespace = string.Join(".", parts, 0, parts.Length - 1),
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
130 TypeName = parts[parts.Length - 1]
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
131 };
267
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
132
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
133 switch (Token) {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
134 case TokenType.OpenList:
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
135 typeReference.GenericParameters = ReadTypeReferenceList();
268
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
136 if (Token != TokenType.CloseList)
267
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
137 ThrowUnexpectedToken();
268
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
138 ReadToken();
267
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
139 break;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
140 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
141
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
142 return typeReference;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
143 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
144
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
145 TypeReference[] ReadTypeReferenceList() {
268
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
146 var list = new List<TypeReference>();
267
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
147
268
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
148 do {
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
149 var typeReference = ReadTypeReference();
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
150 list.Add(typeReference);
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
151 } while (Token == TokenType.Comma);
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
152
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
153 return list.ToArray();
267
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
154 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
155
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
156 void ThrowUnexpectedToken() {
268
0be8a6ae8307 Implemented typereference parser
cin
parents: 267
diff changeset
157 throw new FormatException($"Unexpected '{Token}' at pos {TokenPos}: -->{m_text.Substring(TokenPos, Math.Min(m_text.Length - TokenPos, 10))}");
267
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
158 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
159
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
160 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
161 }