PageRenderTime 48ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/library/xslt/src/style/xm_xslt_style_element.e

http://github.com/gobo-eiffel/gobo
Specman e | 2684 lines | 2269 code | 212 blank | 203 comment | 193 complexity | 137780367780fd5b1e0649453f5fb270 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. note
  2. description:
  3. "Element nodes in an XSLT stylesheet"
  4. library: "Gobo Eiffel XSLT Library"
  5. copyright: "Copyright (c) 2004-2018, Colin Adams and others"
  6. license: "MIT License"
  7. date: "$Date: 2010/05/03 $"
  8. revision: "$Revision: #11 $"
  9. deferred class XM_XSLT_STYLE_ELEMENT
  10. inherit
  11. XM_XPATH_TREE_ELEMENT
  12. XM_XSLT_TRACE_DETAILS
  13. XM_XSLT_VALIDATION
  14. ST_STRING_ROUTINES
  15. XM_XSLT_STYLE_CONSTANTS
  16. XM_XPATH_SHARED_EXPRESSION_FACTORY
  17. export {NONE} all end
  18. XM_XPATH_SHARED_EXPRESSION_TESTER
  19. export {NONE} all end
  20. XM_XPATH_SHARED_NODE_KIND_TESTS
  21. export {NONE} all end
  22. XM_XPATH_SHARED_NO_NODE_TEST
  23. export {NONE} all end
  24. XM_XPATH_SHARED_NODE_KIND_TESTS
  25. export {NONE} all end
  26. XM_XPATH_PROMOTION_ACTIONS
  27. export {NONE} all end
  28. XM_XPATH_TYPE
  29. XM_XPATH_TOKENS
  30. export {NONE} all end
  31. XM_XPATH_EXPRESSION_CONTAINER
  32. XM_XPATH_DEBUGGING_ROUTINES
  33. export {NONE} all end
  34. feature {NONE} -- Initialization
  35. make_style_element (an_error_listener: XM_XSLT_ERROR_LISTENER; a_document: XM_XPATH_TREE_DOCUMENT; a_parent: detachable XM_XPATH_TREE_COMPOSITE_NODE;
  36. an_attribute_collection: detachable XM_XPATH_ATTRIBUTE_COLLECTION; a_namespace_list: detachable DS_ARRAYED_LIST [INTEGER];
  37. a_name_code: INTEGER; a_sequence_number: INTEGER; a_configuration: like configuration)
  38. -- Establish invariant.
  39. require
  40. error_listener_not_void: an_error_listener /= Void
  41. document_not_void: a_document /= Void
  42. configuration_not_void: a_configuration /= Void
  43. strictly_positive_sequence_number: a_sequence_number > 0
  44. do
  45. configuration := a_configuration
  46. reporting_circumstances := Report_always
  47. error_listener := an_error_listener
  48. create version.make_zero
  49. make (a_document, a_parent, an_attribute_collection, a_namespace_list, a_name_code, a_sequence_number)
  50. ensure
  51. error_listener_set: error_listener = an_error_listener
  52. configuration_set: configuration = a_configuration
  53. name_code_set: name_code = a_name_code
  54. end
  55. feature {XM_XSLT_NODE_FACTORY} -- Validation
  56. check_default_collation_name
  57. -- Check default collation_name is valid.
  58. local
  59. l_error: XM_XPATH_ERROR_VALUE
  60. do
  61. if attached local_default_collation_name as l_local_default_collation_name and then default_collation_name.is_empty then
  62. create l_error.make_from_string (STRING_.concat ("None of the following are recognized as a collation URI by this implementation: ", l_local_default_collation_name), Xpath_errors_uri, "XTSE0125", Static_error)
  63. set_last_error (l_error)
  64. end
  65. end
  66. feature -- Access
  67. construct_type: INTEGER
  68. -- Type of construct being traced
  69. do
  70. Result := fingerprint
  71. end
  72. trace_properties: DS_LIST [STRING]
  73. -- Additional trace properties
  74. local
  75. an_iterator: XM_XPATH_SEQUENCE_ITERATOR [XM_XPATH_NODE]
  76. an_attribute: XM_XPATH_TREE_ATTRIBUTE
  77. do
  78. create {DS_ARRAYED_LIST [STRING]} Result.make_default
  79. Result.set_equality_tester (string_equality_tester)
  80. from
  81. an_iterator := new_axis_iterator (Attribute_axis); an_iterator.start
  82. until
  83. an_iterator.after
  84. loop
  85. an_attribute := an_iterator.item.as_tree_node.as_tree_attribute
  86. Result.force_last (shared_name_pool.expanded_name_from_name_code (an_attribute.fingerprint))
  87. an_iterator.forth
  88. end
  89. end
  90. trace_property (an_expanded_name: STRING): STRING
  91. -- Value of trace-property
  92. do
  93. check attached attribute_value_by_name (namespace_uri_from_expanded_name (an_expanded_name), local_name_from_expanded_name (an_expanded_name)) as l_trace_property then
  94. Result := l_trace_property
  95. end
  96. end
  97. default_collation_name: STRING
  98. -- Default collation name
  99. local
  100. a_splitter: ST_SPLITTER
  101. some_collation_names: DS_LIST [STRING]
  102. a_cursor: DS_LIST_CURSOR [STRING]
  103. a_collation_name: STRING
  104. l_result: detachable STRING
  105. do
  106. if attached local_default_collation_name as l_local_default_collation_name then
  107. create a_splitter.make
  108. some_collation_names := a_splitter.split (l_local_default_collation_name)
  109. from
  110. a_cursor := some_collation_names.new_cursor; a_cursor.start
  111. until
  112. a_cursor.after
  113. loop
  114. a_collation_name := a_cursor.item
  115. check attached principal_stylesheet as l_principal_stylesheet then
  116. if l_principal_stylesheet.collation_map.has (a_collation_name) then
  117. l_result := a_collation_name
  118. a_cursor.go_after
  119. else
  120. a_cursor.forth
  121. end
  122. end
  123. variant
  124. some_collation_names.count + 1 - a_cursor.index
  125. end
  126. if l_result /= Void then
  127. Result := l_result
  128. else
  129. Result := ""
  130. end
  131. else
  132. if attached {XM_XSLT_STYLE_ELEMENT} parent as a_style_element then
  133. Result := a_style_element.default_collation_name
  134. else
  135. Result := Unicode_codepoint_collation_uri
  136. end
  137. end
  138. end
  139. configuration: XM_XSLT_CONFIGURATION
  140. -- System configuration
  141. error_listener: XM_XSLT_ERROR_LISTENER
  142. -- Error listener
  143. local_default_xpath_namespace: detachable STRING
  144. -- Default XPath namespace
  145. version: MA_DECIMAL
  146. -- Value of the applicable version attribute
  147. is_instruction: BOOLEAN
  148. -- Is `Current' an instruction?
  149. static_context: detachable XM_XSLT_EXPRESSION_CONTEXT
  150. -- Static context
  151. used_attribute_sets: detachable DS_ARRAYED_LIST [INTEGER]
  152. -- Names of attribute-sets used by `Current'
  153. is_permitted_child (a_style_element: XM_XSLT_STYLE_ELEMENT): BOOLEAN
  154. -- Is `a_style_element' a permitted child of `Current'?
  155. require
  156. not_void: a_style_element /= Void
  157. do
  158. Result := False
  159. end
  160. parameter_references (a_binding: XM_XPATH_BINDING): INTEGER
  161. -- Approximate count of references by parameters of `Current' to `a_binding'
  162. do
  163. -- pre-condition cannot be met
  164. end
  165. default_xpath_namespace: STRING
  166. -- Namespace URI of default XPath namespace
  167. local
  168. l_style_element: detachable XM_XSLT_STYLE_ELEMENT
  169. l_namespace: detachable STRING
  170. l_result: detachable STRING
  171. do
  172. from
  173. l_style_element := Current
  174. until
  175. l_result /= Void or l_style_element = Void or l_namespace /= Void
  176. loop
  177. l_namespace := l_style_element.local_default_xpath_namespace
  178. if l_namespace = Void then
  179. if attached {XM_XSLT_STYLE_ELEMENT} l_style_element.parent_node as l_style_element_parent_node then
  180. l_style_element := l_style_element_parent_node
  181. else
  182. l_style_element := Void
  183. end
  184. else
  185. l_result := l_namespace
  186. end
  187. end
  188. if l_result /= Void then
  189. Result := l_result
  190. else
  191. Result := Null_uri
  192. end
  193. end
  194. containing_slot_manager: XM_XPATH_SLOT_MANAGER
  195. -- Slot manager from containing procedure
  196. do
  197. check attached owning_procedure as l_owning_procedure then
  198. Result := l_owning_procedure.slot_manager
  199. end
  200. end
  201. containing_stylesheet: detachable XM_XSLT_STYLESHEET
  202. -- Containing stylesheet;
  203. -- N.B. This may not be the principal stylersheet, it may be
  204. -- an included or imported module.
  205. require
  206. -- commented out - see post-condition comments
  207. -- well_formed_stylesheet: True -- Can't easily check, but all nodes other than XM_XSLT_STYLESHEETs must have a parent.
  208. local
  209. l_node: detachable XM_XPATH_TREE_COMPOSITE_NODE
  210. l_finished: BOOLEAN
  211. do
  212. from
  213. l_node := Current
  214. if attached {XM_XSLT_STYLESHEET} l_node as l_stylesheet then
  215. Result := l_stylesheet
  216. end
  217. l_finished := Result /= Void
  218. until
  219. l_finished
  220. loop
  221. if l_node = Void then
  222. l_finished := True
  223. else
  224. l_node := l_node.parent
  225. if attached {XM_XSLT_STYLESHEET} l_node as l_stylesheet then
  226. Result := l_stylesheet
  227. end
  228. l_finished := Result /= Void
  229. end
  230. end
  231. ensure
  232. -- in the presence of compile errors, the next line won't necessarily be true
  233. -- but any_compile_errors calls this routine.
  234. -- containing_stylesheet_not_void: Result /= Void
  235. end
  236. principal_stylesheet: detachable XM_XSLT_STYLESHEET
  237. -- Top-level stylesheet
  238. local
  239. another_stylesheet: detachable XM_XSLT_STYLESHEET
  240. do
  241. from
  242. Result := containing_stylesheet
  243. if Result /= Void then
  244. another_stylesheet := Result.importer
  245. end
  246. until
  247. another_stylesheet = Void
  248. loop
  249. Result := another_stylesheet
  250. another_stylesheet := Result.importer
  251. end
  252. ensure
  253. -- the next line is true except in the case of well-formedness errors
  254. -- prinicpal_stylesheet_not_void: Result /= Void
  255. end
  256. stylesheet_compiler: detachable XM_XSLT_STYLESHEET_COMPILER
  257. -- Stylesheet compiler
  258. do
  259. check attached principal_stylesheet as l_principal_stylesheet then
  260. Result := l_principal_stylesheet.stylesheet_compiler
  261. end
  262. end
  263. owning_procedure: detachable XM_XSLT_PROCEDURE
  264. -- Owning Procedure definition, if this is a local variable
  265. local
  266. a_node: XM_XPATH_NODE
  267. a_next_node: detachable XM_XPATH_NODE
  268. found: BOOLEAN
  269. do
  270. from
  271. a_node := Current
  272. until
  273. found
  274. loop
  275. a_next_node := a_node.parent
  276. if attached {XM_XSLT_STYLESHEET} a_next_node as a_stylesheet then
  277. found := True
  278. if attached {XM_XSLT_STYLE_ELEMENT} a_node as a_style_element then
  279. if a_style_element.is_template then
  280. Result := a_style_element.as_template
  281. elseif a_style_element.is_xslt_variable_declaration then
  282. Result := a_style_element.as_xslt_variable_declaration
  283. elseif a_style_element.is_attribute_set then
  284. Result := a_style_element.as_attribute_set
  285. elseif a_style_element.is_xslt_function then
  286. Result := a_style_element.as_xslt_function
  287. elseif a_style_element.is_key then
  288. Result := a_style_element.as_key
  289. end
  290. end
  291. end
  292. check a_next_node /= Void then
  293. a_node := a_next_node
  294. end
  295. end
  296. end
  297. attribute_value_by_expanded_name (an_attribute_name: STRING): detachable STRING
  298. -- Value of `an_attribute_name'
  299. require
  300. valid_attribute_name: an_attribute_name /= Void
  301. and then is_valid_expanded_name (an_attribute_name)
  302. do
  303. if not shared_name_pool.is_expanded_name_allocated (an_attribute_name) then
  304. shared_name_pool.allocate_expanded_name (an_attribute_name)
  305. end
  306. Result := attribute_value (shared_name_pool.fingerprint_from_expanded_name (an_attribute_name))
  307. end
  308. precedence: INTEGER
  309. -- Import precedence of `Current'
  310. do
  311. check attached containing_stylesheet as l_containing_stylesheet then
  312. Result := l_containing_stylesheet.precedence
  313. end
  314. end
  315. uri_for_prefix (an_xml_prefix: STRING; use_default_namespace: BOOLEAN): detachable STRING
  316. -- URI for `an_xml_prefix' using the in-scope namespaces
  317. require
  318. prefix_not_void: an_xml_prefix /= Void
  319. local
  320. a_uri_code: INTEGER
  321. do
  322. if not use_default_namespace and then an_xml_prefix.count = 0 then
  323. Result := ""
  324. else
  325. a_uri_code := uri_code_for_prefix (an_xml_prefix)
  326. if a_uri_code /= -1 then
  327. Result := shared_name_pool.uri_from_uri_code (a_uri_code)
  328. end
  329. end
  330. end
  331. last_child_instruction: detachable XM_XSLT_STYLE_ELEMENT
  332. -- Last child instruction of this instruction.
  333. -- Returns `Void' if there are no child instructions,
  334. -- or if the last child is a text node.
  335. local
  336. a_child_iterator: XM_XPATH_SEQUENCE_ITERATOR [XM_XPATH_NODE]
  337. do
  338. from
  339. a_child_iterator := new_axis_iterator (Child_axis)
  340. a_child_iterator.start
  341. until
  342. a_child_iterator.after
  343. loop
  344. if attached {XM_XSLT_STYLE_ELEMENT} a_child_iterator.item as a_style_element then
  345. Result := a_style_element
  346. else
  347. Result := Void
  348. end
  349. a_child_iterator.forth
  350. end
  351. end
  352. namespace_context: XM_XSLT_NAMESPACE_CONTEXT
  353. -- Namespace context
  354. do
  355. create Result.make (namespace_codes_in_scope)
  356. end
  357. with_param_instructions (an_executable: XM_XSLT_EXECUTABLE; is_tunnel: BOOLEAN): DS_ARRAYED_LIST [XM_XSLT_COMPILED_WITH_PARAM]
  358. -- List of tunnel or non-tunnel parameters
  359. require
  360. executable_not_void: an_executable /= Void
  361. local
  362. a_parameter_count: INTEGER
  363. an_iterator: XM_XPATH_SEQUENCE_ITERATOR [XM_XPATH_NODE]
  364. do
  365. from
  366. an_iterator := new_axis_iterator (Child_axis)
  367. an_iterator.start
  368. until
  369. an_iterator.after
  370. loop
  371. if attached {XM_XSLT_WITH_PARAM} an_iterator.item as a_with_param and then a_with_param.is_tunnel_parameter = is_tunnel then
  372. a_parameter_count := a_parameter_count + 1
  373. end
  374. an_iterator.forth
  375. end
  376. create Result.make (a_parameter_count)
  377. from
  378. an_iterator := new_axis_iterator (Child_axis)
  379. an_iterator.start
  380. until
  381. an_iterator.after
  382. loop
  383. if attached {XM_XSLT_WITH_PARAM} an_iterator.item as a_with_param and then a_with_param.is_tunnel_parameter = is_tunnel then
  384. a_with_param.compile (an_executable)
  385. check
  386. with_param_instruction: attached {XM_XSLT_COMPILED_WITH_PARAM} a_with_param.last_generated_expression as a_compiled_with_param
  387. then
  388. Result.put_last (a_compiled_with_param)
  389. end
  390. end
  391. an_iterator.forth
  392. end
  393. ensure
  394. result_list_not_void: Result /= Void
  395. end
  396. sort_keys: detachable DS_ARRAYED_LIST [XM_XSLT_SORT_KEY_DEFINITION]
  397. -- List of sort keys
  398. assemble_sort_keys
  399. -- Create and assemble sort keys
  400. require
  401. no_previous_error: not any_compile_errors
  402. local
  403. l_iterator: XM_XPATH_SEQUENCE_ITERATOR [XM_XPATH_NODE]
  404. l_sort_key_count: INTEGER
  405. l_sort_keys: like sort_keys
  406. do
  407. from
  408. l_iterator := new_axis_iterator (Child_axis); l_iterator.start
  409. until
  410. l_iterator.after or any_compile_errors
  411. loop
  412. if attached {XM_XSLT_SORT} l_iterator.item as l_sort then
  413. if l_sort_key_count /= 0 and l_sort.stable_attribute_value /= Void then
  414. report_compile_error (create {XM_XPATH_ERROR_VALUE}.make_from_string ("stable attribute may appear only on the first xsl:sort element", Xpath_errors_uri, "XTSE1017", Static_error))
  415. end
  416. l_sort_key_count := l_sort_key_count + 1
  417. end
  418. l_iterator.forth
  419. end
  420. if not any_compile_errors and l_sort_key_count > 0 then
  421. from
  422. l_iterator := new_axis_iterator (Child_axis); l_iterator.start
  423. create l_sort_keys.make (l_sort_key_count)
  424. sort_keys := l_sort_keys
  425. until
  426. l_iterator.after or any_compile_errors
  427. loop
  428. if attached {XM_XSLT_SORT} l_iterator.item as l_sort then
  429. check attached l_sort.sort_key_definition as l_sort_key_definition then
  430. l_sort_keys.put_last (l_sort_key_definition)
  431. end
  432. end
  433. l_iterator.forth
  434. end
  435. else
  436. create sort_keys.make (0)
  437. end
  438. ensure
  439. sort_key_list_not_void: sort_keys /= Void
  440. end
  441. stylesheet_function (a_fingerprint, an_arity: INTEGER): detachable XM_XSLT_FUNCTION
  442. -- Xsl:function named by `a_fingerprint' with `an_arity' arguments
  443. require
  444. positive_fingerprint: a_fingerprint >= 0
  445. nearly_positive_arity: an_arity >= -1 -- -1 = any arity will do
  446. local
  447. a_root: XM_XSLT_STYLESHEET
  448. a_top_level_element_list: DS_BILINKED_LIST [XM_XSLT_STYLE_ELEMENT]
  449. a_cursor: DS_BILINKED_LIST_CURSOR [XM_XSLT_STYLE_ELEMENT]
  450. do
  451. -- We rely on the search following the order of decreasing import precedence.
  452. check attached principal_stylesheet as l_principal_stylesheet then
  453. a_root := l_principal_stylesheet
  454. end
  455. check attached a_root.top_level_elements as l_root_top_level_elements then
  456. a_top_level_element_list := l_root_top_level_elements
  457. end
  458. from
  459. a_cursor := a_top_level_element_list.new_cursor; a_cursor.finish
  460. until
  461. a_cursor.before
  462. loop
  463. if a_cursor.item.is_xslt_function and then a_cursor.item.as_xslt_function.function_fingerprint = a_fingerprint
  464. and then (an_arity = -1 or else a_cursor.item.as_xslt_function.arity = an_arity) then
  465. Result := a_cursor.item.as_xslt_function
  466. a_cursor.go_before
  467. else
  468. a_cursor.back
  469. end
  470. variant
  471. a_cursor.index
  472. end
  473. ensure
  474. function_may_not_be_available: True
  475. end
  476. is_extension_instruction_namespace (a_uri_code: INTEGER): BOOLEAN
  477. -- Is `a_uri_code' an in-scope extension instruction namespace?
  478. local
  479. a_style_element: detachable XM_XSLT_STYLE_ELEMENT
  480. do
  481. from
  482. a_style_element := Current
  483. until
  484. Result or else a_style_element = Void
  485. loop
  486. Result := a_style_element.is_defined_extension_instruction_namespace (a_uri_code)
  487. if not Result then
  488. if attached {XM_XSLT_STYLE_ELEMENT} a_style_element.parent as l_style_element then
  489. a_style_element := l_style_element
  490. else
  491. a_style_element := Void
  492. end
  493. end
  494. end
  495. end
  496. system_id_from_module_number (a_module_number: INTEGER): STRING
  497. -- System identifier
  498. do
  499. check attached principal_stylesheet as l_principal_stylesheet then
  500. Result := l_principal_stylesheet.system_id_from_module_number (a_module_number)
  501. end
  502. end
  503. feature -- Status_report
  504. any_compile_errors: BOOLEAN
  505. -- Have any compile errors been reported?
  506. local
  507. l_stylesheet: detachable like principal_stylesheet
  508. do
  509. l_stylesheet := principal_stylesheet
  510. if l_stylesheet /= Void then
  511. Result := l_stylesheet.any_compile_errors
  512. end
  513. end
  514. attributes_prepared: BOOLEAN
  515. -- Have attributes been prepared?
  516. validated: BOOLEAN
  517. -- Has `Current' been validated?
  518. post_validated: BOOLEAN
  519. -- Has `Current' been post-validated?
  520. children_validated: BOOLEAN
  521. -- Have the children of `Current' been validated?
  522. version_attribute_processed: BOOLEAN
  523. -- Has the version attribute been processed yet?
  524. reporting_circumstances: INTEGER
  525. -- Conditions under which a validation error will be reported
  526. validation_error: detachable XM_XPATH_ERROR_VALUE
  527. last_generated_name_code: INTEGER
  528. -- Last name code generated by `generate_name_code'
  529. last_generated_expression: detachable XM_XPATH_EXPRESSION
  530. -- Result of last call to `generate_expression' or `compile' or `compile_sequence_constructor'
  531. last_generated_pattern: detachable XM_XSLT_PATTERN
  532. -- Result of last call to `generate_pattern'
  533. last_generated_sequence_type: detachable XM_XPATH_SEQUENCE_TYPE
  534. -- Result of last call to `generate_sequence_type'
  535. name_code_error_value: detachable XM_XPATH_ERROR_VALUE
  536. -- Error value created by `generate_name_code'
  537. frozen is_computed_expression: BOOLEAN
  538. -- Is `Current' a computed expression?
  539. do
  540. -- `False'
  541. end
  542. is_absent_extension_element: BOOLEAN
  543. -- Is `Current' and `XM_XSLT_ABSENT_EXTENSION_ELEMENT'?
  544. do
  545. Result := False
  546. end
  547. is_user_function: BOOLEAN
  548. -- Is `Current' a compiled user function?
  549. do
  550. -- `False'
  551. end
  552. is_stylesheet_in_error: BOOLEAN
  553. -- is any element of the stylsheet tree compiled in error?
  554. local
  555. a_cursor: DS_ARRAYED_LIST_CURSOR [XM_XPATH_TREE_NODE]
  556. do
  557. if is_error then Result := True
  558. else
  559. -- recusively check all the children
  560. from
  561. a_cursor := children.new_cursor
  562. a_cursor.start
  563. until
  564. a_cursor.after
  565. loop
  566. if attached {XM_XSLT_STYLE_ELEMENT} a_cursor.item as a_style_element then
  567. if a_style_element.is_stylesheet_in_error then
  568. Result := True
  569. a_cursor.go_after
  570. end
  571. end
  572. if not a_cursor.after then a_cursor.forth end
  573. variant
  574. children.count + 1 - a_cursor.index
  575. end
  576. end
  577. end
  578. is_forwards_compatible_processing_enabled: BOOLEAN
  579. -- Is forwards-compatible mode enabled for this element?
  580. do
  581. Result := version > decimal_two
  582. end
  583. is_backwards_compatible_processing_enabled: BOOLEAN
  584. -- Is backwards-compatible mode enabled for this element?
  585. do
  586. Result := version < decimal_two
  587. end
  588. is_explaining: BOOLEAN
  589. -- Has "gexslt:explain" been coded on this or any child element?
  590. is_top_level: BOOLEAN
  591. -- Is `Current' a top-level element?
  592. do
  593. Result := attached {XM_XSLT_STYLESHEET} parent_node
  594. end
  595. is_variable_declared (a_fingerprint: INTEGER): BOOLEAN
  596. -- Does `a_fingerprint' represent an in-scope variable?
  597. require
  598. positive_fingerprint: a_fingerprint >= 0
  599. do
  600. Result := is_local_variable_declared (a_fingerprint)
  601. or else is_global_variable_declared (a_fingerprint)
  602. end
  603. is_excluded_namespace (a_uri_code: INTEGER): BOOLEAN
  604. -- Is `a_uri_code' defined as an excluded namespace on this or any ancestor element?
  605. local
  606. a_style_element: detachable XM_XSLT_STYLE_ELEMENT
  607. do
  608. if a_uri_code = Xslt_uri_code then
  609. Result := True
  610. elseif is_extension_instruction_namespace (a_uri_code) then
  611. Result := True
  612. else
  613. from
  614. a_style_element := Current
  615. until
  616. Result or else a_style_element = Void
  617. loop
  618. if a_style_element.is_defined_excluded_namespace (a_uri_code) then
  619. Result := True
  620. else
  621. if attached {XM_XSLT_STYLE_ELEMENT} a_style_element.parent as l_style_element_parent then
  622. a_style_element := l_style_element_parent
  623. else
  624. a_style_element := Void
  625. end
  626. end
  627. end
  628. end
  629. end
  630. may_contain_sequence_constructor: BOOLEAN
  631. -- Is `Current' allowed to contain a sequence constructor?
  632. do
  633. Result := False
  634. end
  635. may_contain_fallback: BOOLEAN
  636. -- Is `Current' allowed to contain an xsl:fallback?
  637. do
  638. Result := may_contain_sequence_constructor
  639. end
  640. is_apply_templates: BOOLEAN
  641. -- Is `Current' an xsl:apply-templates?
  642. do
  643. Result := False
  644. end
  645. is_param: BOOLEAN
  646. -- Is `Current' an xsl:param?
  647. do
  648. Result := False
  649. end
  650. is_stylesheet: BOOLEAN
  651. -- Is `Current' an xsl:stylesheet or xsl:transform?
  652. do
  653. Result := False
  654. end
  655. is_for_each: BOOLEAN
  656. -- Is `Current' an xsl:for-each?
  657. do
  658. Result := False
  659. end
  660. is_for_each_group: BOOLEAN
  661. -- Is `Current' an xsl:for-each-group?
  662. do
  663. Result := False
  664. end
  665. is_perform_sort: BOOLEAN
  666. -- Is `Current' an xsl:perform-sort?
  667. do
  668. Result := False
  669. end
  670. is_sort: BOOLEAN
  671. -- Is `Current' an xsl:sort?
  672. do
  673. Result := False
  674. end
  675. is_template: BOOLEAN
  676. -- Is `Current' an xsl:template?
  677. do
  678. Result := False
  679. end
  680. is_xslt_variable: BOOLEAN
  681. -- Is `Current' an xsl:variable?
  682. do
  683. Result := False
  684. end
  685. is_character_map: BOOLEAN
  686. -- Is `Current' an xsl:character-map?
  687. do
  688. Result := False
  689. end
  690. is_attribute_set: BOOLEAN
  691. -- Is `Current' an xsl:attribute-set?
  692. do
  693. Result := False
  694. end
  695. is_xslt_variable_declaration: BOOLEAN
  696. -- Is `Current' an xsl:variable or xsl:param?
  697. do
  698. Result := False
  699. end
  700. is_namespace_alias: BOOLEAN
  701. -- Is `Current' an xsl:namespace-alias?
  702. do
  703. Result := False
  704. end
  705. is_xslt_function: BOOLEAN
  706. -- Is `Current' an xsl:function?
  707. do
  708. Result := False
  709. end
  710. is_module: BOOLEAN
  711. -- Is `Current' an xsl:include/import?
  712. do
  713. Result := False
  714. end
  715. is_output: BOOLEAN
  716. -- Is `Current' an xsl:output?
  717. do
  718. Result := False
  719. end
  720. is_key: BOOLEAN
  721. -- Is `Current' an xsl:key?
  722. do
  723. Result := False
  724. end
  725. is_fallback: BOOLEAN
  726. -- Is `Current' an xsl:fallback?
  727. do
  728. Result := False
  729. end
  730. is_matching_substring: BOOLEAN
  731. -- Is `Current' an xsl:matching-substring?
  732. do
  733. Result := False
  734. end
  735. is_non_matching_substring: BOOLEAN
  736. -- Is `Current' an xsl:non-matching-substring?
  737. do
  738. Result := False
  739. end
  740. is_decimal_format: BOOLEAN
  741. -- Is `Current' an xsl:decimal_format?
  742. do
  743. Result := False
  744. end
  745. is_gexslt_document: BOOLEAN
  746. -- Is `Current' a gexslt:document?
  747. do
  748. Result := False
  749. end
  750. is_gexslt_collection: BOOLEAN
  751. -- Is `Current' a gexslt:collection?
  752. do
  753. Result := False
  754. end
  755. feature -- Status setting
  756. set_validation_error (an_error: XM_XPATH_ERROR_VALUE; a_condition: INTEGER)
  757. -- Set a validation error.
  758. require
  759. error_not_void: an_error /= Void
  760. validation_reporting: Report_always <= a_condition and then a_condition <= Report_if_instantiated
  761. do
  762. if validation_error = Void
  763. or else a_condition < reporting_circumstances then
  764. validation_error := an_error
  765. reporting_circumstances := a_condition
  766. end
  767. ensure
  768. validation_error_not_void: validation_error /= Void
  769. reporting_circumstances: reporting_circumstances <= a_condition
  770. end
  771. report_absence (an_attribute_name: STRING)
  772. -- Report absence of a compulsory attribute.
  773. require
  774. attribute_name_not_void: an_attribute_name /= Void
  775. local
  776. a_message: STRING
  777. an_error: XM_XPATH_ERROR_VALUE
  778. do
  779. a_message := STRING_.appended_string ("Element must have a %"", an_attribute_name)
  780. a_message := STRING_.appended_string (a_message, "%" attribute")
  781. create an_error.make_from_string (a_message, Xpath_errors_uri, "XTSE0010", Static_error)
  782. report_compile_error (an_error)
  783. end
  784. report_compile_error (a_error: XM_XPATH_ERROR_VALUE)
  785. -- Report a compile error.
  786. require
  787. validation_message_not_void: a_error /= Void
  788. local
  789. l_stylesheet: detachable XM_XSLT_STYLESHEET
  790. do
  791. if not system_id.is_empty and then not a_error.is_location_known then a_error.set_location (system_id, line_number) end
  792. error_listener.fatal_error (a_error)
  793. l_stylesheet := principal_stylesheet
  794. if l_stylesheet /= Void then
  795. l_stylesheet.set_compile_errors
  796. end
  797. ensure
  798. compile_errors: principal_stylesheet /= Void implies any_compile_errors
  799. end
  800. report_compile_warning (a_message: STRING)
  801. -- Report a compile warning.
  802. require
  803. validation_message_not_void: a_message /= Void
  804. do
  805. error_listener.warning (a_message, Current)
  806. end
  807. mark_tail_calls
  808. -- Mark tail-recursive calls on templates and functions.
  809. do
  810. -- do nothing
  811. end
  812. check_unknown_attribute (a_name_code: INTEGER)
  813. -- Check whether an unknown attribute is permitted.
  814. local
  815. an_error: XM_XPATH_ERROR_VALUE
  816. an_attribute_uri, an_element_uri, a_local_name, a_message: STRING
  817. an_explain_value: detachable STRING
  818. do
  819. an_attribute_uri := shared_name_pool.namespace_uri_from_name_code (a_name_code)
  820. an_element_uri := uri
  821. a_local_name := shared_name_pool.local_name_from_name_code (a_name_code)
  822. if STRING_.same_string (an_attribute_uri, Gexslt_eiffel_type_uri) and then
  823. STRING_.same_string (a_local_name, Gexslt_explain_name) then
  824. an_explain_value := attribute_value_by_expanded_name (Gexslt_explain_attribute)
  825. if an_explain_value /= Void and then STRING_.same_string (an_explain_value, "no") then
  826. is_explaining := False
  827. elseif an_explain_value /= Void and then STRING_.same_string (an_explain_value, "yes") then
  828. is_explaining := True
  829. elseif an_explain_value /= Void and then STRING_.same_string (an_explain_value, "all") then
  830. is_explaining := True
  831. end
  832. elseif not is_forwards_compatible_processing_enabled then
  833. -- Allow standard on an Extension Instruction or a user-defined Data Element.
  834. if is_instruction and then
  835. STRING_.same_string (an_attribute_uri, Xslt_uri) and then
  836. STRING_.same_string (an_element_uri, Gexslt_eiffel_type_uri) and then
  837. (
  838. STRING_.same_string (a_local_name, Use_when_attribute) or else
  839. STRING_.same_string (a_local_name, Xpath_default_namespace_attribute) or else
  840. STRING_.same_string (a_local_name, Extension_element_prefixes_attribute) or else
  841. STRING_.same_string (a_local_name, Exclude_result_prefixes_attribute) or else
  842. STRING_.same_string (a_local_name, Version_attribute) or else
  843. STRING_.same_string (a_local_name, Default_collation_attribute)
  844. ) then
  845. -- do nothing
  846. -- Allow standard attributes on an XSLT element.
  847. elseif STRING_.same_string (an_element_uri, Xslt_uri) and then
  848. STRING_.same_string (an_attribute_uri, "") and then
  849. (
  850. STRING_.same_string (a_local_name, Use_when_attribute) or else
  851. STRING_.same_string (a_local_name, Xpath_default_namespace_attribute) or else
  852. STRING_.same_string (a_local_name, Extension_element_prefixes_attribute) or else
  853. STRING_.same_string (a_local_name, Exclude_result_prefixes_attribute) or else
  854. STRING_.same_string (a_local_name, Version_attribute) or else
  855. STRING_.same_string (a_local_name, Default_collation_attribute)
  856. ) then
  857. -- do nothing
  858. elseif STRING_.same_string (an_attribute_uri, "") or else
  859. STRING_.same_string (an_attribute_uri, Xslt_uri) then
  860. a_message := STRING_.appended_string ("Attribute ", shared_name_pool.display_name_from_name_code (a_name_code))
  861. a_message := STRING_.appended_string (a_message, " is not allowed on this element")
  862. create an_error.make_from_string (a_message, Xpath_errors_uri, "XTSE0090", Static_error)
  863. report_compile_error (an_error)
  864. end
  865. end
  866. end
  867. check_top_level (an_error_code: detachable STRING)
  868. -- Check `Current' is a top-level element.
  869. local
  870. an_error: XM_XPATH_ERROR_VALUE
  871. a_code: STRING
  872. do
  873. if not is_top_level then
  874. if an_error_code = Void then
  875. a_code := "XTSE0010"
  876. else
  877. a_code := an_error_code
  878. end
  879. create an_error.make_from_string (STRING_.concat (node_name, " must only be used at top level of stylesheet"), "", a_code, Static_error)
  880. report_compile_error (an_error)
  881. end
  882. end
  883. check_empty
  884. -- Check `Current' has no children (except permitted fallbacks)
  885. local
  886. l_child_iterator: XM_XPATH_SEQUENCE_ITERATOR [XM_XPATH_NODE]
  887. l_error_found: BOOLEAN
  888. do
  889. if has_child_nodes then
  890. if may_contain_fallback then
  891. from
  892. l_child_iterator := new_axis_iterator (Child_axis)
  893. l_child_iterator.start
  894. until
  895. l_error_found or else l_child_iterator.after
  896. loop
  897. if not attached {XM_XSLT_FALLBACK} l_child_iterator.item then
  898. l_error_found := True
  899. end
  900. l_child_iterator.forth
  901. end
  902. else
  903. l_error_found := True
  904. end
  905. if l_error_found then
  906. report_compile_error (create {XM_XPATH_ERROR_VALUE}.make_from_string (STRING_.concat (node_name, " must be empty."), Xpath_errors_uri, "XTSE0260", Static_error))
  907. end
  908. end
  909. end
  910. check_empty_with_attribute (an_attribute_name, an_error_code: STRING)
  911. -- Check `Current' has no children
  912. require
  913. attribute_name_not_void: an_attribute_name /= Void
  914. error_code_not_void: an_error_code /= Void
  915. local
  916. an_error: XM_XPATH_ERROR_VALUE
  917. a_message: STRING
  918. do
  919. if has_child_nodes then
  920. a_message := STRING_.appended_string (node_name, " must be empty when the '")
  921. a_message := STRING_.appended_string (a_message, an_attribute_name)
  922. a_message := STRING_.appended_string (a_message, "' attribute is supplied.")
  923. create an_error.make_from_string (a_message, Xpath_errors_uri, an_error_code, Static_error)
  924. report_compile_error (an_error)
  925. end
  926. end
  927. check_not_empty_missing_attribute (an_attribute_name, an_error_code: STRING)
  928. -- Check `Current' has children
  929. require
  930. attribute_name_not_void: an_attribute_name /= Void
  931. error_code_not_void: an_error_code /= Void
  932. local
  933. an_error: XM_XPATH_ERROR_VALUE
  934. a_message: STRING
  935. do
  936. if not has_child_nodes then
  937. a_message := STRING_.appended_string (node_name, " must not be empty when the '")
  938. a_message := STRING_.appended_string (a_message, an_attribute_name)
  939. a_message := STRING_.appended_string (a_message, "' attribute is not supplied.")
  940. create an_error.make_from_string (a_message, Xpath_errors_uri, an_error_code, Static_error)
  941. report_compile_error (an_error)
  942. end
  943. end
  944. type_check_expression (a_replacement: DS_CELL [detachable XM_XPATH_EXPRESSION]; a_name: STRING; a_expression: XM_XPATH_EXPRESSION)
  945. -- Type-check and optimize `an expression.'.
  946. -- This is called to check each expression while the containing instruction is being validated.
  947. -- It is not just a static type-check, it also adds code
  948. -- to perform any necessary run-time type checking and/or conversion
  949. require
  950. expression_not_in_error: a_expression /= Void and then not a_expression.is_error
  951. valid_name: a_name /= Void and then a_name.count > 0
  952. a_replacement_not_void: a_replacement /= Void
  953. not_replaced: a_replacement.item = Void
  954. local
  955. l_analyzed_expression: XM_XPATH_EXPRESSION
  956. do
  957. if a_expression.is_computed_expression then
  958. -- temporary measure, until instruction is compiled:
  959. a_expression.as_computed_expression.set_parent (Current)
  960. end
  961. check attached static_context as l_static_context then
  962. a_expression.check_static_type (a_replacement, l_static_context, any_item)
  963. end
  964. check postcondition_of_check_static_type: attached a_replacement.item as l_replacement_item then
  965. l_analyzed_expression := l_replacement_item
  966. end
  967. if attached l_analyzed_expression.error_value as l_error_value then
  968. check is_error: l_analyzed_expression.is_error end
  969. if l_error_value.type /= Dynamic_error then
  970. report_compile_error (l_error_value)
  971. end
  972. else
  973. a_replacement.put (Void)
  974. l_analyzed_expression.resolve_calls_to_current_function (a_replacement)
  975. check postcondition_of_resolve_calls_to_current_function: attached a_replacement.item as l_replacement_item then
  976. l_analyzed_expression := l_replacement_item
  977. end
  978. if attached l_analyzed_expression.error_value as l_error_value and then l_error_value.type /= Dynamic_error then
  979. check is_error: l_analyzed_expression.is_error end
  980. report_compile_error (l_error_value)
  981. end
  982. end
  983. end
  984. type_check_pattern (a_name: STRING; a_pattern: XM_XSLT_PATTERN)
  985. -- Type-check `a_pattern'.
  986. -- This is called to check each pattern while the containing instruction is being validated.
  987. -- It is not just a static type-check, it also adds code
  988. -- to perform any necessary run-time type checking and/or conversion
  989. require
  990. pattern_not_void: a_pattern /= Void
  991. valid_name: a_name /= Void and then a_name.count > 0
  992. local
  993. l_uses_current, l_name_code_created: BOOLEAN
  994. l_sub_expressions: DS_ARRAYED_LIST_CURSOR [XM_XPATH_EXPRESSION]
  995. l_let_expression: XM_XPATH_LET_EXPRESSION
  996. l_range_variable: XM_XPATH_RANGE_VARIABLE_DECLARATION
  997. l_name_code, l_counter: INTEGER
  998. l_required_type: XM_XPATH_SEQUENCE_TYPE
  999. l_sequence_expression: XM_XPATH_CONTEXT_ITEM_EXPRESSION
  1000. l_offer: XM_XPATH_PROMOTION_OFFER
  1001. l_local_name_prefix, l_local_name: STRING
  1002. do
  1003. check attached static_context as l_static_context then
  1004. a_pattern.type_check (l_static_context, any_node_test)
  1005. end
  1006. if attached a_pattern.error_value as l_error_value then
  1007. check is_error: a_pattern.is_error end
  1008. -- TODO - this should be a dynamic error
  1009. report_compile_error (l_error_value)
  1010. end
  1011. if a_pattern.is_location_pattern then
  1012. from
  1013. l_sub_expressions := a_pattern.sub_expressions.new_cursor
  1014. l_sub_expressions.start
  1015. until
  1016. l_sub_expressions.after
  1017. loop
  1018. if l_sub_expressions.item.calls_function (Current_function_type_code) then
  1019. l_uses_current := True
  1020. l_sub_expressions.go_after
  1021. else
  1022. l_sub_expressions.forth
  1023. end
  1024. end
  1025. if l_uses_current then
  1026. from
  1027. l_local_name_prefix := "current_"; l_counter := 0
  1028. until
  1029. l_name_code_created
  1030. loop
  1031. l_local_name := STRING_.concat (l_local_name_prefix, l_counter.out)
  1032. if not shared_name_pool.is_name_code_allocated ("gexslt_system_usage", Gexslt_examples_uri, l_local_name) then
  1033. shared_name_pool.allocate_name ("gexslt_system_usage", Gexslt_examples_uri, l_local_name)
  1034. l_name_code_created := True
  1035. l_name_code := shared_name_pool.last_name_code
  1036. else
  1037. l_counter := l_counter + 1
  1038. end
  1039. end
  1040. create l_required_type.make_single_item
  1041. create l_range_variable.make ("gexslt_system_usage:current_function", l_name_code, l_required_type)
  1042. create l_sequence_expression.make_current
  1043. create l_let_expression.make (l_range_variable, l_sequence_expression, create {XM_XPATH_EMPTY_SEQUENCE}.make)
  1044. create l_offer.make (Replace_current, Void, l_let_expression, False, False)
  1045. a_pattern.as_location_pattern.resolve_current (l_let_expression, l_offer)
  1046. allocate_slots (l_let_expression, containing_slot_manager)
  1047. l_range_variable.fix_up_references (l_let_expression)
  1048. end
  1049. end
  1050. end
  1051. check_within_template
  1052. -- Check `Current' is within a template.
  1053. local
  1054. an_error: XM_XPATH_ERROR_VALUE
  1055. do
  1056. -- TODO: review - parents should all check their children, not vice-versa
  1057. if not attached {XM_XSLT_STYLE_ELEMENT} parent as a_style_element or else not a_style_element.may_contain_sequence_constructor then
  1058. create an_error.make_from_string (STRING_.concat (node_name, " may only be used within a sequence constructor"), Xpath_errors_uri, "XTSE0010", Static_error)
  1059. report_compile_error (an_error)
  1060. end
  1061. end
  1062. check_sort_comes_first (sort_required: BOOLEAN)
  1063. -- Check if all xsl:sort children precede all other elements
  1064. local
  1065. an_error: XM_XPATH_ERROR_VALUE
  1066. a_message: STRING
  1067. non_sort_found, sort_found: BOOLEAN
  1068. l_iterator: XM_XPATH_SEQUENCE_ITERATOR [XM_XPATH_NODE]
  1069. a_node: XM_XPATH_NODE
  1070. do
  1071. from
  1072. l_iterator := new_axis_iterator (Child_axis); l_iterator.start
  1073. until
  1074. any_compile_errors or else l_iterator.after
  1075. loop
  1076. a_node := l_iterator.item
  1077. if attached {XM_XSLT_SORT} a_node as l_sort then
  1078. if non_sort_found then
  1079. a_message := STRING_.concat ("Within ", node_name)
  1080. a_message := STRING_.appended_string (a_message, ", xsl:sort elements must come before all other elements")
  1081. create an_error.make_from_string (a_message, Xpath_errors_uri, "XTSE0010", Static_error)
  1082. report_compile_error (an_error)
  1083. end
  1084. sort_found := True
  1085. elseif a_node.node_type = Text_node then
  1086. -- with xml:space=preserve, white space nodes may still be there
  1087. if not is_all_whitespace (a_node.string_value) then
  1088. non_sort_found := True
  1089. end
  1090. else
  1091. non_sort_found := True
  1092. end
  1093. l_iterator.forth
  1094. end
  1095. if sort_required and then not sort_found then
  1096. create an_error.make_from_string (STRING_.concat (node_name, " must have at least one xsl:sort child"), Xpath_errors_uri, "XTSE0010", Static_error)
  1097. report_compile_error (an_error)
  1098. end
  1099. end
  1100. check_only_with_parameter_content
  1101. -- Check contents of `Current' is only xsl:with-param elements.
  1102. local
  1103. a_child_iterator: XM_XPATH_SEQUENCE_ITERATOR [XM_XPATH_NODE]
  1104. finished: BOOLEAN
  1105. an_error: XM_XPATH_ERROR_VALUE
  1106. do
  1107. if has_child_nodes then
  1108. from
  1109. a_child_iterator := new_axis_iterator (Child_axis)
  1110. a_child_iterator.start
  1111. until
  1112. finished or else a_child_iterator.after
  1113. loop
  1114. if not attached {XM_XSLT_WITH_PARAM} a_child_iterator.item as a_parameter then
  1115. -- may be a whitespace text node or xsl:fallback
  1116. if a_child_iterator.item.node_type = Text_node and then is_all_whitespace (a_child_iterator.item.string_value) then
  1117. -- do nothing
  1118. elseif may_contain_fallback then
  1119. if not attached {XM_XSLT_FALLBACK} a_child_iterator.item as a_fallback then
  1120. create an_error.make_from_string (STRING_.concat (node_name, " may only have xsl:with-param children"), Xpath_errors_uri, "XTSE0010", Static_error)
  1121. report_compile_error (an_error)
  1122. finished := True
  1123. end
  1124. else
  1125. create an_error.make_from_string (STRING_.concat (node_name, " may only have xsl:with-param children"), Xpath_errors_uri, "XTSE0010", Static_error)
  1126. report_compile_error (an_error)
  1127. finished := True
  1128. end
  1129. end
  1130. a_child_iterator.forth
  1131. end
  1132. end
  1133. end
  1134. feature -- Creation
  1135. new_trace_wrapper (a_child: XM_XPATH_EXPRESSION; an_executable: XM_XSLT_EXECUTABLE; some_details: XM_XSLT_TRACE_DETAILS): XM_XSLT_TRACE_WRAPPER
  1136. -- newly created trace wrapper
  1137. require
  1138. child_expresion_not_void: a_child /= Void
  1139. executable_not_void: an_executable /= Void
  1140. trace_details_not_void: some_details /= Void
  1141. do
  1142. if attached {XM_XSLT_TRACE_WRAPPER} a_child as a_trace_wrapper then
  1143. -- this can happen, for example, after optimizing a compile-time xsl:if
  1144. Result := a_trace_wrapper
  1145. else
  1146. create {XM_XSLT_TRACE_INSTRUCTION} Result.make (a_child, an_executable, some_details)
  1147. end
  1148. ensure
  1149. trace_wrapper_not_void: Result /= Void
  1150. end
  1151. generate_attribute_value_template (a_avt: STRING; a_static_context: XM_XSLT_EXPRESSION_CONTEXT)
  1152. -- Generate an attribute-valued-template.
  1153. -- The static context may be altered as a result of parsing.
  1154. require
  1155. avt_not_void: a_avt /= Void
  1156. static_context_not_void: a_static_context /= Void
  1157. local
  1158. l_avt: XM_XSLT_AVT_PARSER
  1159. l_concat_function: XM_XPATH_CONCAT
  1160. l_replacement: DS_CELL [detachable XM_XPATH_EXPRESSION]
  1161. l_last_generated_expression: like last_generated_expression
  1162. do
  1163. create l_avt.make (a_avt, a_static_context, configuration.are_all_nodes_untyped)
  1164. l_avt.parse_components (line_number)
  1165. if attached l_avt.error_value as l_error_value then
  1166. create {XM_XPATH_INVALID_VALUE} l_last_generated_expression.make (l_error_value)
  1167. elseif l_avt.components.count = 0 then
  1168. create {XM_XPATH_STRING_VALUE} l_last_generated_expression.make ("")
  1169. elseif l_avt.components.count = 1 then
  1170. create l_replacement.make (Void)
  1171. l_avt.components.item (1).simplify (l_replacement)
  1172. check postcondition_of_simplify: attached l_replacement.item as l_replacement_item then
  1173. l_last_generated_expression := l_replacement_item
  1174. end
  1175. else
  1176. create l_concat_function.make
  1177. l_concat_function.set_arguments (l_avt.components)
  1178. create l_replacement.make (Void)
  1179. l_concat_function.simplify (l_replacement)
  1180. check postcondition_of_simplify: attached l_replacement.item as l_replacement_item then
  1181. l_last_generated_expression := l_replacement_item
  1182. end
  1183. end
  1184. last_generated_expression := l_last_generated_expression
  1185. if attached l_last_generated_expression.error_value as l_error_value then
  1186. check is_error: l_last_generated_expression.is_error end
  1187. report_compile_error (l_error_value)
  1188. end
  1189. ensure
  1190. attribute_value_template_not_void: last_generated_expression /= Void
  1191. end
  1192. generate_name_code (a_qname: STRING)
  1193. -- Generate a name code and register it in the name pool.
  1194. -- `Current' is used as the context for namespace resolution.
  1195. -- The default namespace is not used.
  1196. require
  1197. valid_qname: a_qname /= Void and then is_qname (a_qname)
  1198. local
  1199. l_parser: XM_XPATH_QNAME_PARSER
  1200. l_uri: detachable STRING
  1201. l_message: STRING
  1202. l_uri_code: INTEGER
  1203. do
  1204. last_generated_name_code := -1
  1205. create l_parser.make (a_qname)
  1206. if not l_parser.is_prefix_present then
  1207. check attached l_parser.local_name as l_local_name then
  1208. if shared_name_pool.is_name_code_allocated_using_uri_code ("", l_uri_code, l_local_name) then
  1209. last_generated_name_code := shared_name_pool.name_code ("", shared_name_pool.uri_from_uri_code (l_uri_code), l_local_name)
  1210. else
  1211. if not shared_name_pool.is_name_pool_full_using_uri_code (l_uri_code, l_local_name) then
  1212. shared_name_pool.allocate_name_using_uri_code ("", l_uri_code, l_local_name)
  1213. last_generated_name_code := shared_name_pool.last_name_code
  1214. else
  1215. create name_code_error_value.make_from_string (STRING_.concat ("Name pool has no room to allocate ", a_qname), Gexslt_eiffel_type_uri, "NAME_POOL", Static_error)
  1216. last_generated_name_code := -1
  1217. end
  1218. end
  1219. end
  1220. else
  1221. check is_prefix_present: attached l_parser.optional_prefix as l_optional_prefix then
  1222. l_uri := uri_for_prefix (l_optional_prefix, False)
  1223. if l_uri = Void then
  1224. l_message := STRING_.concat ("Namespace prefix ", l_optional_prefix)
  1225. l_message := STRING_.appended_string (l_message, " does not have an in-scope binding")
  1226. create name_code_error_value.make_from_string (l_message, Xpath_errors_uri, "XTSE0280", Static_error)
  1227. elseif is_reserved_namespace (l_uri) then
  1228. l_message := STRING_.concat ("Namespace prefix ", l_optional_prefix)
  1229. l_message := STRING_.appended_string (l_message, " refers to a reserved namespace")
  1230. create name_code_error_value.make_from_string (l_message, Xpath_errors_uri, "XTSE0080", Static_error)
  1231. last_generated_name_code := -1
  1232. else
  1233. check attached l_parser.local_name as l_local_name then
  1234. if shared_name_pool.is_name_code_allocated (l_optional_prefix, l_uri, l_local_name) then
  1235. last_generated_name_code := shared_name_pool.name_code (l_optional_prefix, l_uri, l_local_name)
  1236. else
  1237. if not shared_name_pool.is_name_pool_full (l_uri, l_local_name) then
  1238. shared_name_pool.allocate_name (l_optional_prefix, l_uri, l_local_name)
  1239. last_generated_name_code := shared_name_pool.last_name_code
  1240. else
  1241. l_message := STRING_.concat ("Name pool has no room to allocate ", l_uri)
  1242. l_message := STRING_.appended_string (l_message, "#")
  1243. l_message := STRING_.appended_string (l_message, l_local_name)
  1244. create name_code_error_value.make_from_string (l_message, Gexslt_eiffel_type_uri, "NAME_POOL", Static_error)
  1245. last_generated_name_code := -1
  1246. end
  1247. end
  1248. end
  1249. end
  1250. end
  1251. end
  1252. ensure
  1253. possible_error: last_generated_name_code = -1 implies name_code_error_value /= Void
  1254. end
  1255. generate_expression (a_expression: STRING)
  1256. -- Create an expression.
  1257. require
  1258. expression_text_not_void: a_expression /= Void
  1259. static_context_not_void: static_context /= Void
  1260. local
  1261. l_deferred_error: XM_XSLT_DEFERRED_ERROR
  1262. l_module_number: INTEGER
  1263. l_last_generated_expression: like last_generated_expression
  1264. do
  1265. check precondition_static_context_not_void: attached static_context as l_static_context then
  1266. expression_factory.make_expression (a_expression, l_static_context, 1, Eof_token, line_number, system_id)
  1267. end
  1268. if expression_factory.is_parse_error then
  1269. check attached expression_factory.parsed_error_value as l_parsed_error_value then
  1270. create l_deferred_error.make (l_parsed_error_value, "Xpath dynamic error")
  1271. end
  1272. check attached principal_stylesheet as l_principal_stylesheet then
  1273. if l_principal_stylesheet.is_module_registered (system_id) then
  1274. l_module_number := l_principal_stylesheet.module_number (system_id)
  1275. else
  1276. l_module_number := 0
  1277. end
  1278. end
  1279. l_deferred_error.set_source_location (l_module_number, line_number)
  1280. last_generated_expression := l_deferred_error
  1281. l_deferred_error.set_parent (Current)
  1282. else
  1283. l_last_generated_expression := expression_factory.parsed_expression
  1284. last_generated_expression := l_last_generated_expression
  1285. if l_last_generated_expression.is_computed_expression then
  1286. check attached principal_stylesheet as l_principal_stylesheet then
  1287. if l_principal_stylesheet.is_module_registered (system_id) then
  1288. l_module_number := l_principal_stylesheet.module_number (system_id)
  1289. else
  1290. l_module_number := 0
  1291. end
  1292. end
  1293. l_last_generated_expression.as_computed_expression.set_source_location (l_module_number, line_number)
  1294. end
  1295. end
  1296. ensure
  1297. generated_expression: last_generated_expression /= Void
  1298. end
  1299. generate_pattern (a_pattern: STRING)
  1300. -- Create a pattern.
  1301. require
  1302. pattern_text_not_void: a_pattern /= Void
  1303. static_context_not_void: static_context /= Void
  1304. local
  1305. l_pattern_parser: XM_XSLT_PATTERN_PARSER
  1306. l_error: XM_XPATH_ERROR_VALUE
  1307. l_code: STRING
  1308. do
  1309. check precondition_static_context_not_void: attached static_context as l_static_context then
  1310. create l_pattern_parser.make_pattern
  1311. l_pattern_parser.parse_pattern (a_pattern, l_static_context, line_number)
  1312. if not l_pattern_parser.is_parse_error then
  1313. last_generated_pattern := l_pattern_parser.last_parsed_pattern.simplified_pattern
  1314. else
  1315. check attached l_pattern_parser.first_parse_error_code as l_first_parse_error_code then
  1316. if l_first_parse_error_code.substring_index ("XTSE", 1) > 0 then
  1317. l_code := l_first_parse_error_code
  1318. else
  1319. l_code := "XTSE0340"
  1320. end
  1321. end
  1322. create l_error.make_from_string (l_pattern_parser.first_parse_error, Xpath_errors_uri, l_code, Static_error)
  1323. report_compile_error (l_error)
  1324. create {XM_XSLT_NO_NODE_TEST} last_generated_pattern.make
  1325. end
  1326. end
  1327. ensure
  1328. generated_pattern: last_generated_pattern /= Void
  1329. end
  1330. generate_sequence_type (a_sequence_type: STRING)
  1331. -- Create a sequence type.
  1332. require
  1333. sequence_type_not_void: a_sequence_type /= Void
  1334. local
  1335. a_pattern_parser: XM_XSLT_PATTERN_PARSER
  1336. an_error: XM_XPATH_ERROR_VALUE
  1337. l_static_context: like static_context
  1338. do
  1339. l_static_context := static_context
  1340. if l_static_context = Void then
  1341. create l_static_context.make (Current, configuration)
  1342. static_context := l_static_context
  1343. end
  1344. create a_pattern_parser.make_pattern
  1345. a_pattern_parser.parse_sequence_type (a_sequence_type, l_static_context, line_number)
  1346. if a_pattern_parser.is_parse_error then
  1347. create an_error.make_from_string (a_pattern_parser.first_parse_error, Xpath_errors_uri, "XTSE0340", Static_error)
  1348. report_compile_error (an_error)
  1349. create last_generated_sequence_type.make_any_sequence
  1350. else
  1351. last_generated_sequence_type := a_pattern_parser.last_parsed_sequence
  1352. end
  1353. ensure
  1354. generated_sequence_type: last_generated_sequence_type /= Void
  1355. end
  1356. feature -- Element change
  1357. bind_variable (a_fingerprint: INTEGER)
  1358. -- Bind variable to it's declaration.
  1359. require
  1360. variable_declared: is_variable_declared (a_fingerprint)
  1361. do
  1362. if is_local_variable_declared (a_fingerprint) then
  1363. bind_local_variable (a_fingerprint)
  1364. else
  1365. check
  1366. attached principal_stylesheet as l_principal_stylesheet
  1367. attached static_context as l_static_context
  1368. then
  1369. l_principal_stylesheet.bind_global_variable (a_fingerprint, l_static_context)
  1370. end
  1371. end
  1372. ensure
  1373. variable_bound: attached static_context as l_static_context and then l_static_context.last_bound_variable /= Void
  1374. end
  1375. fixup_references
  1376. -- Fix up references from XPath expressions.
  1377. local
  1378. a_child_iterator: XM_XPATH_SEQUENCE_ITERATOR [XM_XPATH_NODE]
  1379. do
  1380. from
  1381. a_child_iterator := new_axis_iterator (Child_axis)
  1382. a_child_iterator.start
  1383. until
  1384. a_child_iterator.after
  1385. loop
  1386. if attached {XM_XSLT_STYLE_ELEMENT} a_child_iterator.item as a_style_element then
  1387. a_style_element.fixup_references
  1388. end
  1389. a_child_iterator.forth
  1390. end
  1391. end
  1392. style_element_allocate_slots (a_expression: XM_XPATH_EXPRESSION; a_slot_manager: XM_XPATH_SLOT_MANAGER)
  1393. -- Allocate slots in the stack frame for local variables contained in `an_expression'.
  1394. -- This version can be called by XM_XSLT_TEMPLATE, even though it redefines `al…

Large files files are truncated, but you can click here to view the full file