PageRenderTime 30ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/AjaxMinDll/JavaScript/MatchPropertiesVisitor.cs

#
C# | 434 lines | 262 code | 73 blank | 99 comment | 40 complexity | 078cdd48cd156dd92b0017fc7820e628 MD5 | raw file
  1. // MatchPropertiesVisitor.cs
  2. //
  3. // Copyright 2010 Microsoft Corporation
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. namespace Microsoft.Ajax.Utilities
  17. {
  18. /// <summary>
  19. /// This visitor has a Match method that takes a node and an string representing an identifier list separated by periods: IDENT(.IDENT)*
  20. /// </summary>
  21. public class MatchPropertiesVisitor : IVisitor
  22. {
  23. private string[] m_parts;
  24. private bool m_isMatch;
  25. private int m_index;
  26. public MatchPropertiesVisitor()
  27. {
  28. }
  29. public bool Match(AstNode node, string identifiers)
  30. {
  31. // set the match to false
  32. m_isMatch = false;
  33. // identifiers cannot be null or blank and must match: IDENT(.IDENT)*
  34. // since for JS there has to be at least a global object, the dot must be AFTER the first character.
  35. if (node != null && !string.IsNullOrEmpty(identifiers))
  36. {
  37. // get all the parts
  38. var parts = identifiers.Split('.');
  39. // each part must be a valid JavaScript identifier. Assume everything is valid
  40. // unless at least one is invalid -- then forget it
  41. var isValid = true;
  42. foreach (var part in parts)
  43. {
  44. if (!JSScanner.IsValidIdentifier(part))
  45. {
  46. isValid = false;
  47. break;
  48. }
  49. }
  50. // must be valid to continue
  51. if (isValid)
  52. {
  53. // save the parts and start the index on the last one, since we'll be walking backwards
  54. m_parts = parts;
  55. m_index = parts.Length - 1;
  56. node.Accept(this);
  57. }
  58. }
  59. return m_isMatch;
  60. }
  61. public void Visit(CallNode node)
  62. {
  63. // only interested if the index is greater than zero, since the zero-index
  64. // needs to be a lookup. Also needs to be a brackets-call, and there needs to
  65. // be a single argument.
  66. if (node != null
  67. && m_index > 0
  68. && node.InBrackets
  69. && node.Arguments != null
  70. && node.Arguments.Count == 1)
  71. {
  72. // better be a constant wrapper, too
  73. var constantWrapper = node.Arguments[0] as ConstantWrapper;
  74. if (constantWrapper != null && constantWrapper.PrimitiveType == PrimitiveType.String)
  75. {
  76. // check the value of the constant wrapper against the current part
  77. if (string.CompareOrdinal(constantWrapper.Value.ToString(), m_parts[m_index--]) == 0)
  78. {
  79. // match! recurse the function after decrementing the index
  80. node.Function.Accept(this);
  81. }
  82. }
  83. }
  84. }
  85. public void Visit(Member node)
  86. {
  87. // only interested if the index is greater than zero, since the zero-index
  88. // needs to be a lookup.
  89. if (node != null && m_index > 0)
  90. {
  91. // check the Name property against the current part
  92. if (string.CompareOrdinal(node.Name, m_parts[m_index--]) == 0)
  93. {
  94. // match! recurse the root after decrementing the index
  95. node.Root.Accept(this);
  96. }
  97. }
  98. }
  99. public void Visit(Lookup node)
  100. {
  101. // we are only a match if we are looking for the first part
  102. if (node != null && m_index == 0)
  103. {
  104. // see if the name matches; and if there is a field, it should be a global
  105. if (string.CompareOrdinal(node.Name, m_parts[0]) == 0
  106. && (node.VariableField == null || node.VariableField.FieldType == FieldType.UndefinedGlobal
  107. || node.VariableField.FieldType == FieldType.Global))
  108. {
  109. // match!
  110. m_isMatch = true;
  111. }
  112. }
  113. }
  114. public virtual void Visit(GroupingOperator node)
  115. {
  116. if (node != null && node.Operand != null)
  117. {
  118. // just totally ignore any parentheses
  119. node.Operand.Accept(this);
  120. }
  121. }
  122. #region IVisitor Members
  123. public void Visit(ArrayLiteral node)
  124. {
  125. // not applicable; terminate
  126. }
  127. public void Visit(AspNetBlockNode node)
  128. {
  129. // not applicable; terminate
  130. }
  131. public void Visit(AstNodeList node)
  132. {
  133. // not applicable; terminate
  134. }
  135. public void Visit(BinaryOperator node)
  136. {
  137. // not applicable; terminate
  138. }
  139. public void Visit(BindingIdentifier node)
  140. {
  141. // not applicable; terminate
  142. }
  143. public void Visit(Block node)
  144. {
  145. // not applicable; terminate
  146. }
  147. public void Visit(Break node)
  148. {
  149. // not applicable; terminate
  150. }
  151. public void Visit(ClassNode node)
  152. {
  153. // not applicable; terminate
  154. }
  155. public void Visit(ComprehensionNode node)
  156. {
  157. // not applicable; terminate
  158. }
  159. public void Visit(ComprehensionForClause node)
  160. {
  161. // not applicable; terminate
  162. }
  163. public void Visit(ComprehensionIfClause node)
  164. {
  165. // not applicable; terminate
  166. }
  167. public void Visit(ConditionalCompilationComment node)
  168. {
  169. // not applicable; terminate
  170. }
  171. public void Visit(ConditionalCompilationElse node)
  172. {
  173. // not applicable; terminate
  174. }
  175. public void Visit(ConditionalCompilationElseIf node)
  176. {
  177. // not applicable; terminate
  178. }
  179. public void Visit(ConditionalCompilationEnd node)
  180. {
  181. // not applicable; terminate
  182. }
  183. public void Visit(ConditionalCompilationIf node)
  184. {
  185. // not applicable; terminate
  186. }
  187. public void Visit(ConditionalCompilationOn node)
  188. {
  189. // not applicable; terminate
  190. }
  191. public void Visit(ConditionalCompilationSet node)
  192. {
  193. // not applicable; terminate
  194. }
  195. public void Visit(Conditional node)
  196. {
  197. // not applicable; terminate
  198. }
  199. public void Visit(ConstantWrapper node)
  200. {
  201. // not applicable; terminate
  202. }
  203. public void Visit(ConstantWrapperPP node)
  204. {
  205. // not applicable; terminate
  206. }
  207. public void Visit(ConstStatement node)
  208. {
  209. // not applicable; terminate
  210. }
  211. public void Visit(ContinueNode node)
  212. {
  213. // not applicable; terminate
  214. }
  215. public void Visit(CustomNode node)
  216. {
  217. // not applicable; terminate
  218. }
  219. public void Visit(DebuggerNode node)
  220. {
  221. // not applicable; terminate
  222. }
  223. public void Visit(DirectivePrologue node)
  224. {
  225. // not applicable; terminate
  226. }
  227. public void Visit(DoWhile node)
  228. {
  229. // not applicable; terminate
  230. }
  231. public void Visit(EmptyStatement node)
  232. {
  233. // not applicable; terminate
  234. }
  235. public void Visit(ExportNode node)
  236. {
  237. // not applicable; terminate
  238. }
  239. public void Visit(ForIn node)
  240. {
  241. // not applicable; terminate
  242. }
  243. public void Visit(ForNode node)
  244. {
  245. // not applicable; terminate
  246. }
  247. public void Visit(FunctionObject node)
  248. {
  249. // not applicable; terminate
  250. }
  251. public void Visit(GetterSetter node)
  252. {
  253. // not applicable; terminate
  254. }
  255. public void Visit(IfNode node)
  256. {
  257. // not applicable; terminate
  258. }
  259. public void Visit(ImportantComment node)
  260. {
  261. // not applicable; terminate
  262. }
  263. public void Visit(ImportExportSpecifier node)
  264. {
  265. // not applicable; terminate
  266. }
  267. public void Visit(ImportNode node)
  268. {
  269. // not applicable; terminate
  270. }
  271. public void Visit(InitializerNode node)
  272. {
  273. // not applicable; terminate
  274. }
  275. public void Visit(LabeledStatement node)
  276. {
  277. // not applicable; terminate
  278. }
  279. public void Visit(LexicalDeclaration node)
  280. {
  281. // not applicable; terminate
  282. }
  283. public void Visit(ModuleDeclaration node)
  284. {
  285. // not applicable; terminate
  286. }
  287. public void Visit(ObjectLiteral node)
  288. {
  289. // not applicable; terminate
  290. }
  291. public void Visit(ObjectLiteralField node)
  292. {
  293. // not applicable; terminate
  294. }
  295. public void Visit(ObjectLiteralProperty node)
  296. {
  297. // not applicable; terminate
  298. }
  299. public void Visit(ParameterDeclaration node)
  300. {
  301. // not applicable; terminate
  302. }
  303. public void Visit(RegExpLiteral node)
  304. {
  305. // not applicable; terminate
  306. }
  307. public void Visit(ReturnNode node)
  308. {
  309. // not applicable; terminate
  310. }
  311. public void Visit(Switch node)
  312. {
  313. // not applicable; terminate
  314. }
  315. public void Visit(SwitchCase node)
  316. {
  317. // not applicable; terminate
  318. }
  319. public void Visit(TemplateLiteral node)
  320. {
  321. // not applicable; terminate
  322. }
  323. public void Visit(TemplateLiteralExpression node)
  324. {
  325. // not applicable; terminate
  326. }
  327. public void Visit(ThisLiteral node)
  328. {
  329. // not applicable; terminate
  330. }
  331. public void Visit(ThrowNode node)
  332. {
  333. // not applicable; terminate
  334. }
  335. public void Visit(TryNode node)
  336. {
  337. // not applicable; terminate
  338. }
  339. public void Visit(UnaryOperator node)
  340. {
  341. // not applicable; terminate
  342. }
  343. public void Visit(Var node)
  344. {
  345. // not applicable; terminate
  346. }
  347. public void Visit(VariableDeclaration node)
  348. {
  349. // not applicable; terminate
  350. }
  351. public void Visit(WhileNode node)
  352. {
  353. // not applicable; terminate
  354. }
  355. public void Visit(WithNode node)
  356. {
  357. // not applicable; terminate
  358. }
  359. #endregion
  360. }
  361. }