annotate Implab.ServiceHost/Unity/TypeReferenceParser.cs @ 267:6b3e5c48131b v3

Working on Unity xml configuration
author cin
date Fri, 20 Apr 2018 19:05:12 +0300
parents
children 0be8a6ae8307
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 {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
6 public class TypeReferenceParser {
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
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
23 readonly Regex _tokens = new Regex(@"(\w+)|\s*([\.{},])\s*");
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
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
31 readonly string m_text;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
32
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
33 TokenType Token { get { return m_token; } }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
34
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
35 string TokenValue { get { return m_tokenValue; } }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
36
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
37 public TypeReferenceParser(string text) {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
38 Safe.ArgumentNotEmpty(text, nameof(text));
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
39 m_text = text;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
40 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
41
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
42 bool ReadToken() {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
43 if (m_pos >= m_text.Length) {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
44 m_token = TokenType.Eof;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
45 m_tokenValue = null;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
46 return false;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
47 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
48
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
49 var m = _tokens.Match(m_text, m_pos);
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
50
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
51 if (m.Success) {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
52 m_pos += m.Length;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
53 if (m.Groups[1].Success) {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
54 m_token = TokenType.Word;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
55 m_tokenValue = m.Groups[1].Value;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
56 } else if (m.Groups[2].Success) {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
57 m_tokenValue = null;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
58 switch (m.Groups[2].Value) {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
59 case "{":
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
60 m_token = TokenType.OpenList;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
61 break;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
62 case "}":
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
63 m_token = TokenType.CloseList;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
64 break;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
65 case ".":
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
66 m_token = TokenType.Dot;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
67 break;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
68 case ",":
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
69 m_token = TokenType.Comma;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
70 break;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
71 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
72 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
73 return true;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
74 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
75 throw new FormatException($"Failed to parse '{m_text}' at pos {m_pos}");
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 public TypeRerefence Pase() {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
79
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
80 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
81
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
82 string[] ReadTypeName() {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
83 var parts = new List<string>();
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
84
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
85 string current = null;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
86 bool stop = false;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
87 while ((!stop) && ReadToken()) {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
88 switch (Token) {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
89 case TokenType.Word:
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
90 if (current != null)
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
91 ThrowUnexpectedToken();
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
92 current = TokenValue;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
93 break;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
94 case TokenType.Dot:
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
95 if (current == null)
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
96 ThrowUnexpectedToken();
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
97 parts.Add(current);
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
98 current = null;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
99 break;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
100 default:
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
101 stop = true;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
102 break;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
103 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
104 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
105 if (current != null)
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
106 parts.Add(current);
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
107
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
108 if (parts.Count == 0)
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
109 return null;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
110
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
111 return parts.ToArray();
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
112 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
113
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
114 TypeReference ReadTypeReference() {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
115
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
116 var parts = ReadTypeName();
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
117 if (parts == null)
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
118 return null;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
119
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
120 var typeReference = new TypeReference {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
121 Namespace = string.Join(",", parts, 0, parts.Length - 1),
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
122 TypeName = parts[parts.Length - 1]
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
123 };
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
124
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
125 switch (Token) {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
126 case TokenType.Eof:
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
127 break;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
128 case TokenType.OpenList:
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
129 typeReference.GenericParameters = ReadTypeReferenceList();
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
130 if(Token != TokenType.CloseList)
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
131 ThrowUnexpectedToken();
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
132 break;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
133 default:
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
134 ThrowUnexpectedToken();
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
135 break;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
136 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
137
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
138 return typeReference;
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
139 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
140
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
141 TypeReference[] ReadTypeReferenceList() {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
142 throw new NotImplementedException();
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 void ReadDot() {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
146 if (!ReadToken() || Token != TokenType.Dot)
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
147 ThrowUnexpectedToken();
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
148 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
149
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
150 void ThrowUnexpectedToken() {
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
151 throw new FormatException($"Unexpected '{Token}' at {m_pos}");
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
152 }
6b3e5c48131b Working on Unity xml configuration
cin
parents:
diff changeset
153
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 }