1 package net.sourceforge.pmd.lang.vm.ast; 2 3 import org.apache.commons.lang3.text.StrBuilder; 4 5 /* 6 * Licensed to the Apache Software Foundation (ASF) under one 7 * or more contributor license agreements. See the NOTICE file 8 * distributed with this work for additional information 9 * regarding copyright ownership. The ASF licenses this file 10 * to you under the Apache License, Version 2.0 (the 11 * "License"); you may not use this file except in compliance 12 * with the License. You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, 17 * software distributed under the License is distributed on an 18 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 19 * KIND, either express or implied. See the License for the 20 * specific language governing permissions and limitations 21 * under the License. 22 */ 23 24 25 /** 26 * Utilities for dealing with the AST node structure. 27 * 28 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> 29 * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a> 30 * @version $Id: NodeUtils.java 687386 2008-08-20 16:57:07Z nbubna $ 31 */ 32 public class NodeUtils { 33 34 /** 35 * Collect all the <SPECIAL_TOKEN>s that are carried along with a token. Special tokens do not participate in 36 * parsing but can still trigger certain lexical actions. In some cases you may want to retrieve these special 37 * tokens, this is simply a way to extract them. 38 * 39 * @param t the Token 40 * @return StrBuilder with the special tokens. 41 */ 42 private static StrBuilder getSpecialText(final Token t) { 43 final StrBuilder sb = new StrBuilder(); 44 45 Token tmpToken = t.specialToken; 46 47 while (tmpToken.specialToken != null) { 48 tmpToken = tmpToken.specialToken; 49 } 50 51 while (tmpToken != null) { 52 final String st = tmpToken.image; 53 54 for (int i = 0; i < st.length(); i++) { 55 final char c = st.charAt(i); 56 57 if (c == '#' || c == '$') { 58 sb.append(c); 59 } 60 61 /* 62 * more dreaded MORE hack :) 63 * 64 * looking for ("\\")*"$" sequences 65 */ 66 67 if (c == '\\') { 68 boolean ok = true; 69 boolean term = false; 70 71 int j = i; 72 for (ok = true; ok && j < st.length(); j++) { 73 final char cc = st.charAt(j); 74 75 if (cc == '\\') { 76 /* 77 * if we see a \, keep going 78 */ 79 continue; 80 } 81 else if (cc == '$') { 82 /* 83 * a $ ends it correctly 84 */ 85 term = true; 86 ok = false; 87 } 88 else { 89 /* 90 * nah... 91 */ 92 ok = false; 93 } 94 } 95 96 if (term) { 97 final String foo = st.substring(i, j); 98 sb.append(foo); 99 i = j; 100 } 101 } 102 } 103 104 tmpToken = tmpToken.next; 105 } 106 return sb; 107 } 108 109 /** 110 * complete node literal 111 * 112 * @param t 113 * @return A node literal. 114 */ 115 public static String tokenLiteral(final Token t) { 116 // Look at kind of token and return "" when it's a multiline comment 117 if (t.kind == VmParserConstants.MULTI_LINE_COMMENT) { 118 return ""; 119 } 120 else if (t.specialToken == null || t.specialToken.image.startsWith("##")) { 121 return t.image; 122 } 123 else { 124 final StrBuilder special = getSpecialText(t); 125 if (special.length() > 0) { 126 return special.append(t.image).toString(); 127 } 128 return t.image; 129 } 130 } 131 132 }