{"id":9706,"date":"2020-04-26T17:57:52","date_gmt":"2020-04-26T15:57:52","guid":{"rendered":"https:\/\/www.salvis.com\/blog\/?p=9706"},"modified":"2023-11-12T13:51:18","modified_gmt":"2023-11-12T12:51:18","slug":"syntax-highlighting-with-sql-developer","status":"publish","type":"post","link":"https:\/\/www.salvis.com\/blog\/2020\/04\/26\/syntax-highlighting-with-sql-developer\/","title":{"rendered":"Syntax Highlighting With SQL Developer"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p>A customer asked me if it is possible to show unused identifiers in SQL Developer. Since there is no PL\/SQL compile warning for that, you might be tempted to say no. But you can always use <a href=\"https:\/\/github.com\/Trivadis\/plsql-cop-sqldev\">PL\/SQL Cop<\/a> for static code analysis. Guideline <a href=\"https:\/\/trivadis.github.io\/plsql-and-sql-coding-guidelines\/v3.6\/4-language-usage\/1-general\/g-1030\/\">G-1030<\/a> deals with variables and constants and guideline <a href=\"https:\/\/trivadis.github.io\/plsql-and-sql-coding-guidelines\/v3.6\/4-language-usage\/7-stored-objects\/1-general\/g-7140\/\">G-7140<\/a> with procedures and functions. However, in this case, it&#8217;s also possible to achieve the same result by tweaking SQL Developer&#8217;s preferences for PL\/SQL Syntax Colors.<\/p>\n\n\n\n<p>In this blog post, I explain how custom syntax highlighting works in SQL Developer. I use a simple example first and then show how to highlight unused identifiers in SQL Developer.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What Is Syntax Highlighting?<\/h2>\n\n\n\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/Syntax_highlighting\">Wikipedia<\/a> defines syntax highlighting as follows<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Syntax highlighting is a feature of text editors that are used for programming, scripting, or markup languages, such as HTML. The feature <span class=\"highlight highlight-\" style=\"background-color:Lemonchiffon;color:black;\">displays text<\/span>\n, especially source code, <span class=\"highlight highlight-\" style=\"background-color:Lemonchiffon;color:black;\">in different colors and fonts according to the category of terms.<\/span>\n(&#8230;)<\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">How Does Syntax Highlighting Work?<\/h2>\n\n\n\n<p>The next figure illustrates the highlighting process in SQL Developer. The similarities to the <a href=\"https:\/\/www.salvis.com\/blog\/2020\/04\/13\/formatting-code-with-sql-developer\/\">formatting process<\/a> are no accident.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/overview-syntax-highlighting-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"670\" height=\"504\" src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/overview-syntax-highlighting-1.png\" alt=\"\" class=\"wp-image-9677\" srcset=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/overview-syntax-highlighting-1.png 670w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/overview-syntax-highlighting-1-300x225.png 300w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/overview-syntax-highlighting-1-194x146.png 194w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/overview-syntax-highlighting-1-50x38.png 50w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/overview-syntax-highlighting-1-100x75.png 100w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/overview-syntax-highlighting-1-1x1.png 1w\" sizes=\"auto, (max-width:767px) 480px, 670px\" \/><\/a><\/figure>\n\n\n\n<p>I will explain each step and component in the next chapters.<\/p>\n\n\n\n<p>Please note that these are conceptual components, the actual implementation might look different.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1. Parser<\/h3>\n\n\n\n<p>This step is identical to formatting process. The parser reads the unformatted plain SQL or PL\/SQL input and generates a parse-tree. The parse-tree is a hierarchical representation of the significant tokens of the input. In other words, there is neither whitespace nor comments in a parse-tree.<\/p>\n\n\n\n<p>Each node in the parse-tree includes the start and end position within the plain SQL input.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2. Custom Styler<\/h3>\n\n\n\n<p>The custom styler needs the parse-tree and the Arbori program as input.<\/p>\n\n\n\n<p>Arbori is a query language for parse-trees. See my <a href=\"https:\/\/www.salvis.com\/blog\/2020\/04\/13\/formatting-code-with-sql-developer\/\">previous post<\/a> to learn more about it. The Arbori program is configured in the SQL Developer&#8217;s preferences under <code>Code Editor<\/code> -&gt; <code>PL\/SQL Syntax Colors<\/code> -&gt; <code>PL\/SQL Custom Syntax Rules<\/code>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">2.1. The Results<\/h4>\n\n\n\n<p>The custom styler basically only runs the Arbori program. It is responsible for producing two results:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>All custom style names (dotted line to Styles)<\/strong><br \/>to be shown in the preferences under <code>Code Editor<\/code> -> <code>PL\/SQL Syntax Colors<\/code>. Allows the user to configure the foreground and background colours as well as the font style (normal, bold, italic). SQL Developer discovers styles during startup. For changes (new or renamed styles) to take effect you need to restart SQL Developer.<\/li>\n\n\n\n<li><strong>A list of node-style pairs (solid line to Node Style)<\/strong><br \/>to be rendered according to the configured style properties (foreground color, background color and font style).<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">2.2. The Default Arbori Program<\/h4>\n\n\n\n<p>SQL Developer 19.4.0 provides the following default (I removed all multiline comments):<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"PlSqlColTabAlases:                          -- \n   [node) c_alias                           -- Search all the nodes in the parse tree which are column aliases\n | [node) identifier                        -- Or nodes with identifier payload,  \n        &amp; [node-1) query_table_expression   -- which younger siblings are labeled with table names\n-&gt;                                          -- The semantic action symbol (to trigger syntax highlighting).\n;                                           -- End of the rule\n\nPlSqlLogger:\n    [pkg) name\n  &amp; (?pkg = 'DBMS_OUTPUT' | ?pkg = 'APEX_DEBUG' |\n     ?pkg = 'LOG'         | ?pkg = 'logger'     -- pattern match is case insensitive\n  )   \n  &amp; (pkg^ = node | pkg^^ = node)\n  &amp; [node) procedure_call\n-&gt;\n;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line cbp-line-highlight\"><span style=\"color: #C8C8C8\">PlSqlColTabAlases<\/span><span style=\"color: #D4D4D4\">:                          -- <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   [<\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">c_alias<\/span><span style=\"color: #D4D4D4\">                           -- <\/span><span style=\"color: #9CDCFE\">Search<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">all<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">the<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">nodes<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">the<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">parse<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">tree<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">which<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">are<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">column<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">aliases<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"> | [<\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">identifier<\/span><span style=\"color: #D4D4D4\">                        -- <\/span><span style=\"color: #9CDCFE\">Or<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">nodes<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">with<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">identifier<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">payload<\/span><span style=\"color: #D4D4D4\">,  <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        &amp; [<\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">query_table_expression<\/span><span style=\"color: #D4D4D4\">   -- <\/span><span style=\"color: #9CDCFE\">which<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">younger<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">siblings<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">are<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">labeled<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">with<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">table<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">names<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">-&gt;                                          -- <\/span><span style=\"color: #9CDCFE\">The<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">semantic<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">action<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">symbol<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">to<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">trigger<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">syntax<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">highlighting<\/span><span style=\"color: #D4D4D4\">).<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">;                                           -- <\/span><span style=\"color: #9CDCFE\">End<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">of<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">the<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">rule<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #9CDCFE\">PlSqlLogger<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    [<\/span><span style=\"color: #9CDCFE\">pkg<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">name<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  &amp; (?<\/span><span style=\"color: #9CDCFE\">pkg<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&#39;DBMS_OUTPUT&#39;<\/span><span style=\"color: #D4D4D4\"> | ?<\/span><span style=\"color: #9CDCFE\">pkg<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&#39;APEX_DEBUG&#39;<\/span><span style=\"color: #D4D4D4\"> |<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">     ?<\/span><span style=\"color: #9CDCFE\">pkg<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&#39;LOG&#39;<\/span><span style=\"color: #D4D4D4\">         | ?<\/span><span style=\"color: #9CDCFE\">pkg<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&#39;logger&#39;<\/span><span style=\"color: #D4D4D4\">     -- <\/span><span style=\"color: #9CDCFE\">pattern<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">match<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">is<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">case<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">insensitive<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  )   <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  &amp; (<\/span><span style=\"color: #9CDCFE\">pkg<\/span><span style=\"color: #D4D4D4\">^ = <\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\"> | <\/span><span style=\"color: #9CDCFE\">pkg<\/span><span style=\"color: #D4D4D4\">^^ = <\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  &amp; [<\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">procedure_call<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>The query names defined on line 1 (<code>PlsqlColTabAlases<\/code>) and line 8 (<code>PlSqlLogger<\/code>) define the style name used in the preference dialog under <code>Code Editor<\/code> -&gt; <code>PL\/SQL Syntax Colors<\/code>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">2.3. Configuring Styles<\/h4>\n\n\n\n<p>This screenshot shows how the <code>PlSqlLogger<\/code> style is configured.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/preferences-pslql-syntax-colors.png\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"600\" src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/preferences-pslql-syntax-colors.png\" alt=\"\" class=\"wp-image-9681\" srcset=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/preferences-pslql-syntax-colors.png 800w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/preferences-pslql-syntax-colors-300x225.png 300w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/preferences-pslql-syntax-colors-768x576.png 768w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/preferences-pslql-syntax-colors-195x146.png 195w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/preferences-pslql-syntax-colors-50x38.png 50w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/preferences-pslql-syntax-colors-100x75.png 100w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/preferences-pslql-syntax-colors-1x1.png 1w\" sizes=\"auto, (max-width:767px) 480px, (max-width:800px) 100vw, 800px\" \/><\/a><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\">2.4 JavaScript Callback Functions<\/h4>\n\n\n\n<p>The default Arbori program uses predefined Java callback functions in the <code>CustomSyntaxStyle<\/code> class.<\/p>\n\n\n\n<p>Since SQL Developer 19.2.0 you can use embedded JavaScript callback functions. As a result Java callback functions are not necessary anymore.<\/p>\n\n\n\n<p>Here&#8217;s an example how to change <code>PlSqlLogger<\/code> query to use a JavaScript callback function:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"PlSqlLogger:\n    [pkg) name\n  &amp; (?pkg = 'DBMS_OUTPUT' | ?pkg = 'APEX_DEBUG' |\n     ?pkg = 'LOG'         | ?pkg = 'logger'     -- pattern match is case insensitive\n  )   \n  &amp; (pkg^ = node | pkg^^ = node)\n  &amp; [node) procedure_call\n-&gt; {\n  var node = tuple.get(&quot;node&quot;);\n  struct.addStyle(target, node, &quot;PlSqlLogger&quot;);\n}\n;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C8C8C8\">PlSqlLogger<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    [<\/span><span style=\"color: #9CDCFE\">pkg<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">name<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  &amp; (?<\/span><span style=\"color: #9CDCFE\">pkg<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&#39;DBMS_OUTPUT&#39;<\/span><span style=\"color: #D4D4D4\"> | ?<\/span><span style=\"color: #9CDCFE\">pkg<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&#39;APEX_DEBUG&#39;<\/span><span style=\"color: #D4D4D4\"> |<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">     ?<\/span><span style=\"color: #9CDCFE\">pkg<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&#39;LOG&#39;<\/span><span style=\"color: #D4D4D4\">         | ?<\/span><span style=\"color: #9CDCFE\">pkg<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&#39;logger&#39;<\/span><span style=\"color: #D4D4D4\">     -- <\/span><span style=\"color: #9CDCFE\">pattern<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">match<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">is<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">case<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">insensitive<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  )   <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  &amp; (<\/span><span style=\"color: #9CDCFE\">pkg<\/span><span style=\"color: #D4D4D4\">^ = <\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\"> | <\/span><span style=\"color: #9CDCFE\">pkg<\/span><span style=\"color: #D4D4D4\">^^ = <\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  &amp; [<\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">procedure_call<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">-&gt; {<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">  var <\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">tuple<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">get<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;node&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">  struct.addStyle(<\/span><span style=\"color: #9CDCFE\">target<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;PlSqlLogger&quot;<\/span><span style=\"color: #9CDCFE\">);<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #9CDCFE\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Important is line 10. It shows how to add a style for a node in the parse-tree.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">2.5 JavaScript Global Variables<\/h4>\n\n\n\n<p>The following variables are provided. You should know them when writing JavaScript callback functions.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>target<\/code>\n<ul class=\"wp-block-list\">\n<li>instance of <code>oracle.dbtools.parser.Parsed<\/code>, that&#8217;s the complete parse-tree. The following properties and methods are helpful:\n<ul class=\"wp-block-list\">\n<li>src or getSrc() &#8211; list of <code>orace.dbtools.parser.LexerToken<\/code>. Indexed by node number.<\/li>\n\n\n\n<li>root or getRoot() &#8211; the root node.<\/li>\n\n\n\n<li>input or getInput() &#8211; the source text.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><code>tuple<\/code>\n<ul class=\"wp-block-list\">\n<li>instance of <code>HashMap&lt;String, oracle.dbtools.parser.ParseNode><\/code>. It contains an Arbori query result row. The structure is indexed by the query node names. E.g. for the previous <code>PlSqlLogger<\/code> query you can access <code>pkg<\/code>, <code>node<\/code>, <code>pkg^<\/code>, <code>pkg^^<\/code> via the <code>get<\/code> method of <code>HashMap<\/code>. Basically, these are the result columns shown when you execute a query in the Arbori editor.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><code>struct<\/code>\n<ul class=\"wp-block-list\">\n<li>instance of <code>oracle.dbtools.raptor.plsql.language.CustomSyntaxStyle<\/code>, that&#8217;s the custom styler. You need only this method:\n<ul class=\"wp-block-list\">\n<li><code>addStyle(Parsed target, ParseNode node, String styleName)<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">2.6 Important Classes<\/h4>\n\n\n\n<p>Two classes are really important. I&#8217;ve listed them with some properties and methods that you might need:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>ParseNode<\/code>\n<ul class=\"wp-block-list\">\n<li><code>from<\/code> &#8211; start position of the node in the parse-tree.<\/li>\n\n\n\n<li><code>to<\/code>&nbsp;&#8211; end position of the node&nbsp; (half-open interval, this means the last including position is <code>to-1<\/code>).<\/li>\n\n\n\n<li><code>parent<\/code> &#8211; parent node.<\/li>\n\n\n\n<li><code>descendants()<\/code> &#8211; list of all child nodes (including their children, recursively).<\/li>\n\n\n\n<li><code>intermediates(int from, int to)<\/code> &#8211; list of all nodes in the half-open interval.<\/li>\n\n\n\n<li><code>toString()<\/code> &#8211; string representation of the node including all symbols.<\/li>\n\n\n\n<li><code>printTree()<\/code> &#8211; prints a nicely formatted parse-tree on the console. This textual format is used in the <a href=\"https:\/\/vadimtropashko.files.wordpress.com\/2019\/11\/arbori.pdf\">Arbori<\/a> documentation.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><code>LexerToken<\/code>\n<ul class=\"wp-block-list\">\n<li><code>content<\/code> &#8211; the token represented as string.<\/li>\n\n\n\n<li><code>begin<\/code> &#8211; start position in characters of the token in the input string.<\/li>\n\n\n\n<li><code>end<\/code> &#8211; end position in characters of the token in the input string (half-open interval).<\/li>\n\n\n\n<li><code>type<\/code> &#8211; type of the token.<\/li>\n\n\n\n<li><code>toString()<\/code> &#8211; string representation of the token.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">2.7 Overriding Queries for Internal Styles<\/h4>\n\n\n\n<p>The custom styler is not designed to override queries for built-in styles such as <code>PL\/SQL String<\/code>.<\/p>\n\n\n\n<p>However, you can define additional styles. Custom styles are applied at the very end of the process. As a result, you can override previously applied styles.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3. Renderer<\/h3>\n\n\n\n<p>The renderer is attached to the PL\/SQL editor. It runs in the background and needs access to the plain text, the parse tree, the list of node-style pairs and the settings (foreground color, background color, font style) for each style.<\/p>\n\n\n\n<p>Now, the renderer can loop through the internal and custom list of node-style pairs and apply the requested style to all tokens within the node. The result is a nicely highlighted document.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Example 1 &#8211; Extending <code>PlSqlLogger<\/code><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Setup<\/h3>\n\n\n\n<p>I use the default configuration of SQL Developer 19.4.0 including the standard Arbori program.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Default Highlighting Result<\/h3>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-default-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"436\" height=\"100\" src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-default-1.png\" alt=\"\" class=\"wp-image-9695\" srcset=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-default-1.png 436w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-default-1-300x69.png 300w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-default-1-260x60.png 260w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-default-1-50x11.png 50w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-default-1-150x34.png 150w\" sizes=\"auto, (max-width:767px) 436px, 436px\" \/><\/a><\/figure>\n\n\n\n<p>The result looks good. Wait, no, the line two should be displayed in grayish color, as defined for the <code>PlSqlLogger<\/code> style.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Expected Highlighting Result<\/h3>\n\n\n\n<p>That&#8217;s what we expect:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-expected.png\"><img loading=\"lazy\" decoding=\"async\" width=\"445\" height=\"105\" src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-expected.png\" alt=\"\" class=\"wp-image-9704\" srcset=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-expected.png 445w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-expected-300x71.png 300w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-expected-260x61.png 260w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-expected-50x12.png 50w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-expected-150x35.png 150w\" sizes=\"auto, (max-width:767px) 445px, 445px\" \/><\/a><\/figure>\n\n\n\n<p>In fact, it works as expected if I omit the <code>sys<\/code> prefix. However, it is good practice to use it. Why? See the <a href=\"https:\/\/trivadis.github.io\/plsql-and-sql-coding-guidelines\/v3.6\/4-language-usage\/7-stored-objects\/5-oracle-supplied-packages\/g-7510\/\">Trivadis PL\/SQL &amp; SQL Coding Guidelines for G-7510<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Code Outline<\/h3>\n\n\n\n<p>SQL Developer&#8217;s code outline is a representation of the full parse-tree. Disable all filters to show all nodes.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-outline-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"698\" height=\"352\" src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-outline-1.png\" alt=\"\" class=\"wp-image-9698\" srcset=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-outline-1.png 698w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-outline-1-300x151.png 300w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-outline-1-260x131.png 260w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-outline-1-50x25.png 50w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-outline-1-150x75.png 150w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-outline-1-1x1.png 1w\" sizes=\"auto, (max-width:767px) 480px, 698px\" \/><\/a><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Arbori Editor<\/h3>\n\n\n\n<p>Type&nbsp;<code>arbori<\/code> in the search field and press enter to open the Arbori editor. Copy the <code>PlSqlLogger<\/code> query from the preferences into the Arbori editor and press run.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-arbori-editor.png\"><img loading=\"lazy\" decoding=\"async\" width=\"713\" height=\"290\" src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-arbori-editor.png\" alt=\"\" class=\"wp-image-9699\" srcset=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-arbori-editor.png 713w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-arbori-editor-300x122.png 300w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-arbori-editor-260x106.png 260w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-arbori-editor-50x20.png 50w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-arbori-editor-150x61.png 150w\" sizes=\"auto, (max-width:767px) 480px, 713px\" \/><\/a><\/figure>\n\n\n\n<p>The query returns no result.<\/p>\n\n\n\n<p>Why? Because <code>[pkg)<\/code> expects a node of type <code>name<\/code>. But when you look in the outline you see that <code>DBMS_OUTPUT<\/code> is a <code>decl_id<\/code> and also an <code>identifier<\/code>. But it is not a <code>name<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Fix Arbori Program<\/h3>\n\n\n\n<p>Here&#8217;s the fix:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"PlSqlLogger:\n    [pkg) identifier\n  &amp; (?pkg = 'DBMS_OUTPUT' | ?pkg = 'APEX_DEBUG' |\n     ?pkg = 'LOG'         | ?pkg = 'logger'     -- pattern match is case insensitive\n  )   \n  &amp; (pkg^ = node | pkg^^ = node | (pkg^^^ = node &amp; ?pkg-1-1 = 'SYS'))\n  &amp; [node) procedure_call\n-&gt;\n;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C8C8C8\">PlSqlLogger<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    [<\/span><span style=\"color: #9CDCFE\">pkg<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">identifier<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  &amp; (?<\/span><span style=\"color: #9CDCFE\">pkg<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&#39;DBMS_OUTPUT&#39;<\/span><span style=\"color: #D4D4D4\"> | ?<\/span><span style=\"color: #9CDCFE\">pkg<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&#39;APEX_DEBUG&#39;<\/span><span style=\"color: #D4D4D4\"> |<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">     ?<\/span><span style=\"color: #9CDCFE\">pkg<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&#39;LOG&#39;<\/span><span style=\"color: #D4D4D4\">         | ?<\/span><span style=\"color: #9CDCFE\">pkg<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&#39;logger&#39;<\/span><span style=\"color: #D4D4D4\">     -- <\/span><span style=\"color: #9CDCFE\">pattern<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">match<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">is<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">case<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">insensitive<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  )   <\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">  &amp; (<\/span><span style=\"color: #9CDCFE\">pkg<\/span><span style=\"color: #D4D4D4\">^ = <\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\"> | <\/span><span style=\"color: #9CDCFE\">pkg<\/span><span style=\"color: #D4D4D4\">^^ = <\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\"> | (<\/span><span style=\"color: #9CDCFE\">pkg<\/span><span style=\"color: #D4D4D4\">^^^ = <\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\"> &amp; ?<\/span><span style=\"color: #9CDCFE\">pkg<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #CE9178\">&#39;SYS&#39;<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  &amp; [<\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">procedure_call<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>On line 2 I expect an <code>identifier<\/code> for <code>[pkg)<\/code>.<\/p>\n\n\n\n<p>And on line 6 I added the or condition <code>(pkg^^^ = node &amp; ?pkg-1-1 = 'SYS')<\/code>. This means that the grand-grandparent of the node named <code>pkg<\/code>\u00a0must be the same as the node named <code>node<\/code>. <code>node<\/code> must be of type <code>procedure_call<\/code> (see line 7). Furthermore, I said that the name of the previous-previous node of <code>pkg<\/code> must be <code>SYS<\/code>. That&#8217;s it.<\/p>\n\n\n\n<p>Now you can copy &amp; paste this change into the Arbori editor to test it. Afterwards, you can copy the change to the Arbori program in the preferences to apply the change.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-apply-changes.png\"><img loading=\"lazy\" decoding=\"async\" width=\"902\" height=\"600\" src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-apply-changes.png\" alt=\"\" class=\"wp-image-9703\" srcset=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-apply-changes.png 902w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-apply-changes-300x200.png 300w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-apply-changes-768x511.png 768w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-apply-changes-219x146.png 219w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-apply-changes-50x33.png 50w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-apply-changes-113x75.png 113w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-1-apply-changes-1x1.png 1w\" sizes=\"auto, (max-width:767px) 480px, (max-width:902px) 100vw, 902px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Example 2 &#8211; New <code>UnusedIdentifier<\/code><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Setup<\/h3>\n\n\n\n<p>I use the default configuration of SQL Developer 19.4.0 including the changes made in the previous example.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Default Highlighting Result<\/h3>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-default.png\"><img loading=\"lazy\" decoding=\"async\" width=\"572\" height=\"301\" src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-default.png\" alt=\"\" class=\"wp-image-9709\" srcset=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-default.png 572w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-default-300x158.png 300w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-default-260x137.png 260w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-default-50x26.png 50w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-default-143x75.png 143w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-default-1x1.png 1w\" sizes=\"auto, (max-width:767px) 480px, 572px\" \/><\/a><\/figure>\n\n\n\n<p>The result looks good. However, SQL Developer does not provide information about unused variables, constants, functions and procedures. The right solution would be to use the mechanism as for SQL injection detection. But that&#8217;s not (yet) possible.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Expected Highlighting Result<\/h3>\n\n\n\n<p>Therefore I&#8217;d like to highlight the unused variables and procedures like this:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-expected.png\"><img loading=\"lazy\" decoding=\"async\" width=\"568\" height=\"305\" src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-expected.png\" alt=\"\" class=\"wp-image-9710\" srcset=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-expected.png 568w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-expected-300x161.png 300w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-expected-260x140.png 260w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-expected-50x27.png 50w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-expected-140x75.png 140w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-expected-1x1.png 1w\" sizes=\"auto, (max-width:767px) 480px, 568px\" \/><\/a><\/figure>\n\n\n\n<p>The comments in the code example explain the highlighting result.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Register Style (Requires Restart)<\/h3>\n\n\n\n<p>This Arbori query finds all PL\/SQL blocks to be examined:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"UnusedIdentifier:\n  [node) seq_of_stmts &amp; [node-1) 'BEGIN' &amp; ([node+1) exception_handlers_opt | [node+1) 'END')\n;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C8C8C8\">UnusedIdentifier<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  [<\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">seq_of_stmts<\/span><span style=\"color: #D4D4D4\"> &amp; [<\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #CE9178\">&#39;BEGIN&#39;<\/span><span style=\"color: #D4D4D4\"> &amp; ([<\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\">+<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">exception_handlers_opt<\/span><span style=\"color: #D4D4D4\"> | [<\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\">+<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #CE9178\">&#39;END&#39;<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Add it to the Arbori program in the preference dialog as shown here:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-register.png\"><img loading=\"lazy\" decoding=\"async\" width=\"902\" height=\"600\" src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-register.png\" alt=\"\" class=\"wp-image-9712\" srcset=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-register.png 902w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-register-300x200.png 300w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-register-768x511.png 768w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-register-219x146.png 219w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-register-50x33.png 50w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-register-113x75.png 113w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-register-1x1.png 1w\" sizes=\"auto, (max-width:767px) 480px, (max-width:902px) 100vw, 902px\" \/><\/a><\/figure>\n\n\n\n<p>Press <code>OK<\/code> and restart SQL Developer.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Configure Style<\/h3>\n\n\n\n<p>After restarting SQL Developer the new style <code>UnusedIdentifier<\/code> is shown in the preferences:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-configure.png\"><img loading=\"lazy\" decoding=\"async\" width=\"902\" height=\"600\" src=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-configure.png\" alt=\"\" class=\"wp-image-9713\" srcset=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-configure.png 902w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-configure-300x200.png 300w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-configure-768x511.png 768w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-configure-219x146.png 219w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-configure-50x33.png 50w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-configure-113x75.png 113w, https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/example-2-configure-1x1.png 1w\" sizes=\"auto, (max-width:767px) 480px, (max-width:902px) 100vw, 902px\" \/><\/a><\/figure>\n\n\n\n<p>Configure the font style and the foreground and background colors the way you like it.<\/p>\n\n\n\n<p>Now we need to tell SQL Developer where to apply this style.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Arbori Program<\/h3>\n\n\n\n<p>This program does all the magic. Please note that the query is the same as before. I&#8217;ve just added the JavaScript callback function. In fact, it&#8217;s more a JavaScript program now.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"UnusedIdentifier:\n  [node) seq_of_stmts &amp; [node-1) 'BEGIN' &amp; ([node+1) exception_handlers_opt | [node+1) 'END')\n  -&gt; {\n    var countParentSymbol = function(inParentNode, inChildNode, symbol) {\n      var count = 0;\n      var parents = inParentNode.intermediates(inChildNode.from, inChildNode.to);\n      for (j=0; j<parents.size(); j++) {\n        var parent = parents.get(j);\n        if (parent.toString().contains(symbol)) {\n          count++;\n        }\n      }\n      return count;\n    }\n    var populateMaps = function(inNode) {\n      if (inNode != null) {\n        var children = inNode.descendants();\n        for (i=0; i<children.size(); i++) {\n          var child = children.get(i);\n          if (child.toString().contains(&quot;decl_id&quot;)) {\n            if (countParentSymbol(inNode, child, &quot;decl_list&quot;) == 1) {\n              if (countParentSymbol(inNode, child, &quot;seq_of_stmts&quot;) == 0) {\n                var token = target.src[child.from].content.toLowerCase()\n                usageMap.put(token, 0);\n                nodeMap.put(token, child);\n              }\n            }\n          }\n        }\n      }\n    }\n    var checkStatements = function(inNode) {\n      var children = inNode.descendants();\n      for (i=0; i<children.size(); i++) {\n        var child = children.get(i);\n        if (child.toString().contains(&quot;identifier&quot;)) {\n          var token = target.src[child.from].content.toLowerCase();\n          var usages = usageMap.get(token);\n          if (usages != null) {\n            usageMap.put(token, usages + 1);\n          }\n        }\n      }\n    }\n    var checkExceptions = function(inNode) {\n      if (inNode != null) {\n        if (inNode.toString().contains(&quot;exception_handlers_opt&quot;)) {\n          checkStatements(inNode);\n        }\n      }\n    }\n    var reportUnusedIdentifiers = function() {\n      var iterator = usageMap.keySet().iterator();\n      while (iterator.hasNext()) {\n        var key = iterator.next();\n        var usages = usageMap.get(key);\n        if (usages == 0) {\n          struct.addStyle(target, nodeMap.get(key), &quot;UnusedIdentifier&quot;);\n        }\n      }\n    }\n    var usageMap = new java.util.HashMap();\n    var nodeMap = new java.util.HashMap();\n    var node = tuple.get(&quot;node&quot;);\n    populateMaps(node.parent);\n    checkStatements(node);\n    checkExceptions(tuple.get(&quot;node+1&quot;));\n    reportUnusedIdentifiers(node);\n  }\n;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C8C8C8\">UnusedIdentifier<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  [<\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">seq_of_stmts<\/span><span style=\"color: #D4D4D4\"> &amp; [<\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #CE9178\">&#39;BEGIN&#39;<\/span><span style=\"color: #D4D4D4\"> &amp; ([<\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\">+<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">exception_handlers_opt<\/span><span style=\"color: #D4D4D4\"> | [<\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\">+<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #CE9178\">&#39;END&#39;<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  -&gt; {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    var <\/span><span style=\"color: #DCDCAA\">countParentSymbol<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">inParentNode<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">inChildNode<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">symbol<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">count<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">parents<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">inParentNode<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">intermediates<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">inChildNode<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">from<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">inChildNode<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">to<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">j<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">j<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #9CDCFE\">parents<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">size<\/span><span style=\"color: #D4D4D4\">(); <\/span><span style=\"color: #9CDCFE\">j<\/span><span style=\"color: #D4D4D4\">++) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">parent<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">parents<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">get<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">j<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">parent<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">toString<\/span><span style=\"color: #D4D4D4\">().<\/span><span style=\"color: #DCDCAA\">contains<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">symbol<\/span><span style=\"color: #D4D4D4\">)) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">count<\/span><span style=\"color: #D4D4D4\">++;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">count<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    var <\/span><span style=\"color: #DCDCAA\">populateMaps<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">inNode<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">inNode<\/span><span style=\"color: #D4D4D4\"> != <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">children<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">inNode<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">descendants<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #9CDCFE\">children<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">size<\/span><span style=\"color: #D4D4D4\">(); <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">++) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">child<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">children<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">get<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">child<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">toString<\/span><span style=\"color: #D4D4D4\">().<\/span><span style=\"color: #DCDCAA\">contains<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;decl_id&quot;<\/span><span style=\"color: #D4D4D4\">)) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #DCDCAA\">countParentSymbol<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">inNode<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">child<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;decl_list&quot;<\/span><span style=\"color: #D4D4D4\">) == <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">              <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #DCDCAA\">countParentSymbol<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">inNode<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">child<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;seq_of_stmts&quot;<\/span><span style=\"color: #D4D4D4\">) == <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">token<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">target<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">src<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">child<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">from<\/span><span style=\"color: #D4D4D4\">].<\/span><span style=\"color: #9CDCFE\">content<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">toLowerCase<\/span><span style=\"color: #D4D4D4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">usageMap<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">put<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">token<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">nodeMap<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">put<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">token<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">child<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">              }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    var <\/span><span style=\"color: #DCDCAA\">checkStatements<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">inNode<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">children<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">inNode<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">descendants<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">&lt;<\/span><span style=\"color: #9CDCFE\">children<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">size<\/span><span style=\"color: #D4D4D4\">(); <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">++) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">child<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">children<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">get<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">child<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">toString<\/span><span style=\"color: #D4D4D4\">().<\/span><span style=\"color: #DCDCAA\">contains<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;identifier&quot;<\/span><span style=\"color: #D4D4D4\">)) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">token<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">target<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">src<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">child<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">from<\/span><span style=\"color: #D4D4D4\">].<\/span><span style=\"color: #9CDCFE\">content<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">toLowerCase<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">usages<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">usageMap<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">get<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">token<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">usages<\/span><span style=\"color: #D4D4D4\"> != <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">usageMap<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">put<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">token<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">usages<\/span><span style=\"color: #D4D4D4\"> + <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    var <\/span><span style=\"color: #DCDCAA\">checkExceptions<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">inNode<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">inNode<\/span><span style=\"color: #D4D4D4\"> != <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">inNode<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">toString<\/span><span style=\"color: #D4D4D4\">().<\/span><span style=\"color: #DCDCAA\">contains<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;exception_handlers_opt&quot;<\/span><span style=\"color: #D4D4D4\">)) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #DCDCAA\">checkStatements<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">inNode<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    var <\/span><span style=\"color: #DCDCAA\">reportUnusedIdentifiers<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">iterator<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">usageMap<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">keySet<\/span><span style=\"color: #D4D4D4\">().<\/span><span style=\"color: #DCDCAA\">iterator<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #C586C0\">while<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">iterator<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">hasNext<\/span><span style=\"color: #D4D4D4\">()) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">key<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">iterator<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">next<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #569CD6\">var<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">usages<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">usageMap<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">get<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">key<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">usages<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">struct<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">addStyle<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">target<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">nodeMap<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">get<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">key<\/span><span style=\"color: #D4D4D4\">), <\/span><span style=\"color: #CE9178\">&quot;UnusedIdentifier&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    var <\/span><span style=\"color: #9CDCFE\">usageMap<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">java<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">util<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">HashMap<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    var <\/span><span style=\"color: #9CDCFE\">nodeMap<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">java<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">util<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">HashMap<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    var <\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">tuple<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">get<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;node&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #DCDCAA\">populateMaps<\/span><span style=\"color: #D4D4D4\">(node.parent);<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #DCDCAA\">checkStatements<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #DCDCAA\">checkExceptions<\/span><span style=\"color: #D4D4D4\">(tuple.get(<\/span><span style=\"color: #CE9178\">&quot;node+1&quot;<\/span><span style=\"color: #D4D4D4\">));<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #DCDCAA\">reportUnusedIdentifiers<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>I&#8217;ve divided the logic into 5 local functions. I call them at the end of the program. They should be more or less self-explanatory. But surfing through a parse-tree has a certain basic complexity. You find the important call for the code styler on line 58.<\/p>\n\n\n\n<p>Now you can replace the <code>UnusedIdentifier<\/code> query in the <code>PL\/SQL Custom Syntax Rules<\/code> preferences dialog with the code above. Press <code>OK<\/code> and unused identifiers are highlighted in the PL\/SQL editor.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p>The features provided by SQL Developer for syntax highlighting are really extensive and very good. I have never seen anything like this in any other IDE. My second example is probably not a good use case for syntax highlighting. But it clearly shows that custom syntax highlighting in SQL Developer is almost limitless.<\/p>\n\n\n\n<p>Personally, I would like to see comment nodes in the parse-tree as well. This would allow us to distinguish between hints and comments, for example.<\/p>\n\n\n\n<p>Thanks, SQL Developer team. Well done!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction A customer asked me if it is possible to show unused identifiers in SQL Developer. Since there is no PL\/SQL compile warning for that, you might be tempted to say no. But you can always use PL\/SQL Cop for static code analysis. Guideline G-1030 deals with variables and constants and guideline<span class=\"excerpt-hellip\"> [\u2026]<\/span><\/p>\n","protected":false},"author":1,"featured_media":9677,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[129,86,135,13,85,87],"class_list":["post-9706","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oracle","tag-arbori","tag-code-analysis","tag-javascript","tag-plsql","tag-sql","tag-sql-developer"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Syntax Highlighting With SQL Developer - Philipp Salvisberg&#039;s Blog<\/title>\n<meta name=\"description\" content=\"In this blog post I explain how custom syntax highlighting works in SQL Developer. I show how to highlight unused identifiers in SQL Developer.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.salvis.com\/blog\/2020\/04\/26\/syntax-highlighting-with-sql-developer\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Syntax Highlighting With SQL Developer - Philipp Salvisberg&#039;s Blog\" \/>\n<meta property=\"og:description\" content=\"In this blog post I explain how custom syntax highlighting works in SQL Developer. I show how to highlight unused identifiers in SQL Developer.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.salvis.com\/blog\/2020\/04\/26\/syntax-highlighting-with-sql-developer\/\" \/>\n<meta property=\"og:site_name\" content=\"Philipp Salvisberg&#039;s Blog\" \/>\n<meta property=\"article:published_time\" content=\"2020-04-26T15:57:52+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-11-12T12:51:18+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/overview-syntax-highlighting-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"670\" \/>\n\t<meta property=\"og:image:height\" content=\"504\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Philipp Salvisberg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@phsalvisberg\" \/>\n<meta name=\"twitter:site\" content=\"@phsalvisberg\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Philipp Salvisberg\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/04\\\/26\\\/syntax-highlighting-with-sql-developer\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/04\\\/26\\\/syntax-highlighting-with-sql-developer\\\/\"},\"author\":{\"name\":\"Philipp Salvisberg\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"headline\":\"Syntax Highlighting With SQL Developer\",\"datePublished\":\"2020-04-26T15:57:52+00:00\",\"dateModified\":\"2023-11-12T12:51:18+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/04\\\/26\\\/syntax-highlighting-with-sql-developer\\\/\"},\"wordCount\":1522,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"image\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/04\\\/26\\\/syntax-highlighting-with-sql-developer\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/04\\\/overview-syntax-highlighting-1.png\",\"keywords\":[\"Arbori\",\"Code Analysis\",\"JavaScript\",\"PL\\\/SQL\",\"SQL\",\"SQL Developer\"],\"articleSection\":[\"Oracle\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/04\\\/26\\\/syntax-highlighting-with-sql-developer\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/04\\\/26\\\/syntax-highlighting-with-sql-developer\\\/\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/04\\\/26\\\/syntax-highlighting-with-sql-developer\\\/\",\"name\":\"Syntax Highlighting With SQL Developer - Philipp Salvisberg&#039;s Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/04\\\/26\\\/syntax-highlighting-with-sql-developer\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/04\\\/26\\\/syntax-highlighting-with-sql-developer\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/04\\\/overview-syntax-highlighting-1.png\",\"datePublished\":\"2020-04-26T15:57:52+00:00\",\"dateModified\":\"2023-11-12T12:51:18+00:00\",\"description\":\"In this blog post I explain how custom syntax highlighting works in SQL Developer. I show how to highlight unused identifiers in SQL Developer.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/04\\\/26\\\/syntax-highlighting-with-sql-developer\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/04\\\/26\\\/syntax-highlighting-with-sql-developer\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/04\\\/26\\\/syntax-highlighting-with-sql-developer\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/04\\\/overview-syntax-highlighting-1.png\",\"contentUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/04\\\/overview-syntax-highlighting-1.png\",\"width\":670,\"height\":504},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/2020\\\/04\\\/26\\\/syntax-highlighting-with-sql-developer\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Syntax Highlighting With SQL Developer\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/\",\"name\":\"Philipp Salvisberg&#039;s Blog\",\"description\":\"Database-centric development\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/#\\\/schema\\\/person\\\/34352245c48678b1a5a05d4bc1339515\",\"name\":\"Philipp Salvisberg\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"url\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"contentUrl\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\",\"width\":400,\"height\":400,\"caption\":\"Philipp Salvisberg\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.salvis.com\\\/blog\\\/wp-content\\\/uploads\\\/2010\\\/11\\\/phs_trivadis4.jpg\"},\"sameAs\":[\"http:\\\/\\\/www.salvis.com\\\/\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Syntax Highlighting With SQL Developer - Philipp Salvisberg&#039;s Blog","description":"In this blog post I explain how custom syntax highlighting works in SQL Developer. I show how to highlight unused identifiers in SQL Developer.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.salvis.com\/blog\/2020\/04\/26\/syntax-highlighting-with-sql-developer\/","og_locale":"en_US","og_type":"article","og_title":"Syntax Highlighting With SQL Developer - Philipp Salvisberg&#039;s Blog","og_description":"In this blog post I explain how custom syntax highlighting works in SQL Developer. I show how to highlight unused identifiers in SQL Developer.","og_url":"https:\/\/www.salvis.com\/blog\/2020\/04\/26\/syntax-highlighting-with-sql-developer\/","og_site_name":"Philipp Salvisberg&#039;s Blog","article_published_time":"2020-04-26T15:57:52+00:00","article_modified_time":"2023-11-12T12:51:18+00:00","og_image":[{"width":670,"height":504,"url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/overview-syntax-highlighting-1.png","type":"image\/png"}],"author":"Philipp Salvisberg","twitter_card":"summary_large_image","twitter_creator":"@phsalvisberg","twitter_site":"@phsalvisberg","twitter_misc":{"Written by":"Philipp Salvisberg","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.salvis.com\/blog\/2020\/04\/26\/syntax-highlighting-with-sql-developer\/#article","isPartOf":{"@id":"https:\/\/www.salvis.com\/blog\/2020\/04\/26\/syntax-highlighting-with-sql-developer\/"},"author":{"name":"Philipp Salvisberg","@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"headline":"Syntax Highlighting With SQL Developer","datePublished":"2020-04-26T15:57:52+00:00","dateModified":"2023-11-12T12:51:18+00:00","mainEntityOfPage":{"@id":"https:\/\/www.salvis.com\/blog\/2020\/04\/26\/syntax-highlighting-with-sql-developer\/"},"wordCount":1522,"commentCount":1,"publisher":{"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"image":{"@id":"https:\/\/www.salvis.com\/blog\/2020\/04\/26\/syntax-highlighting-with-sql-developer\/#primaryimage"},"thumbnailUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/overview-syntax-highlighting-1.png","keywords":["Arbori","Code Analysis","JavaScript","PL\/SQL","SQL","SQL Developer"],"articleSection":["Oracle"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.salvis.com\/blog\/2020\/04\/26\/syntax-highlighting-with-sql-developer\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.salvis.com\/blog\/2020\/04\/26\/syntax-highlighting-with-sql-developer\/","url":"https:\/\/www.salvis.com\/blog\/2020\/04\/26\/syntax-highlighting-with-sql-developer\/","name":"Syntax Highlighting With SQL Developer - Philipp Salvisberg&#039;s Blog","isPartOf":{"@id":"https:\/\/www.salvis.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.salvis.com\/blog\/2020\/04\/26\/syntax-highlighting-with-sql-developer\/#primaryimage"},"image":{"@id":"https:\/\/www.salvis.com\/blog\/2020\/04\/26\/syntax-highlighting-with-sql-developer\/#primaryimage"},"thumbnailUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/overview-syntax-highlighting-1.png","datePublished":"2020-04-26T15:57:52+00:00","dateModified":"2023-11-12T12:51:18+00:00","description":"In this blog post I explain how custom syntax highlighting works in SQL Developer. I show how to highlight unused identifiers in SQL Developer.","breadcrumb":{"@id":"https:\/\/www.salvis.com\/blog\/2020\/04\/26\/syntax-highlighting-with-sql-developer\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.salvis.com\/blog\/2020\/04\/26\/syntax-highlighting-with-sql-developer\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.salvis.com\/blog\/2020\/04\/26\/syntax-highlighting-with-sql-developer\/#primaryimage","url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/overview-syntax-highlighting-1.png","contentUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2020\/04\/overview-syntax-highlighting-1.png","width":670,"height":504},{"@type":"BreadcrumbList","@id":"https:\/\/www.salvis.com\/blog\/2020\/04\/26\/syntax-highlighting-with-sql-developer\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.salvis.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Syntax Highlighting With SQL Developer"}]},{"@type":"WebSite","@id":"https:\/\/www.salvis.com\/blog\/#website","url":"https:\/\/www.salvis.com\/blog\/","name":"Philipp Salvisberg&#039;s Blog","description":"Database-centric development","publisher":{"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.salvis.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.salvis.com\/blog\/#\/schema\/person\/34352245c48678b1a5a05d4bc1339515","name":"Philipp Salvisberg","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","url":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","contentUrl":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg","width":400,"height":400,"caption":"Philipp Salvisberg"},"logo":{"@id":"https:\/\/www.salvis.com\/blog\/wp-content\/uploads\/2010\/11\/phs_trivadis4.jpg"},"sameAs":["http:\/\/www.salvis.com\/"]}]}},"_links":{"self":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/9706","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/comments?post=9706"}],"version-history":[{"count":22,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/9706\/revisions"}],"predecessor-version":[{"id":12670,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/posts\/9706\/revisions\/12670"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/media\/9677"}],"wp:attachment":[{"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/media?parent=9706"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/categories?post=9706"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.salvis.com\/blog\/wp-json\/wp\/v2\/tags?post=9706"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}