1 19 20 package org.netbeans.editor.ext; 21 22 import java.util.Arrays ; 23 import java.util.ArrayList ; 24 import org.netbeans.editor.Syntax; 25 26 45 46 public class MultiSyntax extends Syntax { 47 48 51 private SyntaxInfo slaveSyntaxChain; 52 53 54 private SyntaxInfo slaveSyntaxChainEnd; 55 56 57 protected void registerSyntax(Syntax slaveSyntax) { 58 slaveSyntaxChainEnd = new SyntaxInfo(slaveSyntax, slaveSyntaxChainEnd); 59 if (slaveSyntaxChain == null) { 60 slaveSyntaxChain = slaveSyntaxChainEnd; 61 } 62 } 63 64 65 public void storeState(StateInfo stateInfo) { 66 super.storeState(stateInfo); 67 ((MultiStateInfo)stateInfo).store(this); 68 } 69 70 public void loadInitState() { 71 super.loadInitState(); 72 SyntaxInfo syntaxItem = slaveSyntaxChain; 73 while (syntaxItem != null) { 74 syntaxItem.syntax.loadInitState(); 75 syntaxItem = syntaxItem.next; 76 } 77 } 78 79 public void load(StateInfo stateInfo, char buffer[], int offset, int len, 80 boolean lastBuffer, int stopPosition) { 81 ((MultiStateInfo)stateInfo).load(this, buffer, offset, len, lastBuffer, stopPosition); 82 super.load(stateInfo, buffer, offset, len, lastBuffer, stopPosition); 83 } 84 85 public StateInfo createStateInfo() { 86 return new MultiStateInfo(); 87 } 88 89 95 public int compareState(StateInfo stateInfo) { 96 int diff = super.compareState(stateInfo); 97 if (diff == EQUAL_STATE) { 98 diff = ((MultiStateInfo)stateInfo).compare(this); 99 } 100 return diff; 101 } 102 103 104 108 public static class MultiStateInfo extends BaseStateInfo { 109 110 private ChainItem stateInfoChain; 111 112 116 void load(MultiSyntax masterSyntax, char[] buffer, int offset, int len, 117 boolean lastBuffer, int stopPosition) { 118 SyntaxInfo syntaxItem = masterSyntax.slaveSyntaxChain; 119 while (syntaxItem != null) { 120 StateInfo loadInfo = null; 121 int masterOffsetDelta = 0; 122 Syntax s = syntaxItem.syntax; 123 if (syntaxItem.active) { 124 Class sc = s.getClass(); 125 ChainItem item = stateInfoChain; 126 while (item != null) { 127 if (item.syntaxClass == sc && item.valid) { 128 loadInfo = item.stateInfo; 129 masterOffsetDelta = item.masterOffsetDelta; 130 break; 131 } 132 item = item.prev; 133 } 134 } 135 s.load(loadInfo, buffer, offset + masterOffsetDelta, 136 len - masterOffsetDelta, lastBuffer, stopPosition); 137 syntaxItem = syntaxItem.next; 138 } 139 } 140 141 void store(MultiSyntax masterSyntax) { 142 ChainItem item = stateInfoChain; 144 while (item != null) { 145 item.valid = false; 146 item = item.prev; 147 } 148 149 SyntaxInfo syntaxItem = masterSyntax.slaveSyntaxChain; 151 while (syntaxItem != null) { 152 if (syntaxItem.active) { 153 Syntax s = syntaxItem.syntax; 154 Class sc = s.getClass(); 155 item = stateInfoChain; 156 while (item != null) { 157 if (item.syntaxClass == sc) { break; 159 } 160 item = item.prev; 161 } 162 if (item == null) { item = stateInfoChain = new ChainItem(s.createStateInfo(), 164 sc, stateInfoChain); 165 } 166 s.storeState(item.stateInfo); 168 item.masterOffsetDelta = s.getOffset() - masterSyntax.getOffset(); 169 item.valid = true; 170 } 171 syntaxItem = syntaxItem.next; 172 } 173 } 174 175 int compare(MultiSyntax masterSyntax) { 176 int ret = Syntax.EQUAL_STATE; 177 ChainItem item = stateInfoChain; 179 while (item != null && ret == Syntax.EQUAL_STATE) { 180 if (item.valid) { 181 Class sc = item.syntaxClass; 182 SyntaxInfo syntaxItem = masterSyntax.slaveSyntaxChain; 183 while (syntaxItem != null) { 184 if (syntaxItem.syntax.getClass() == sc) { 185 if (syntaxItem.active) { 186 ret = syntaxItem.syntax.compareState(item.stateInfo); 187 } else { ret = Syntax.DIFFERENT_STATE; 189 } 190 break; 191 } 192 syntaxItem = syntaxItem.next; 193 } 194 } 195 item = item.prev; 196 } 197 return ret; 198 } 199 200 static class ChainItem { 201 202 205 boolean valid; 206 207 208 StateInfo stateInfo; 209 210 213 int masterOffsetDelta; 214 215 216 Class syntaxClass; 217 218 219 220 ChainItem prev; 221 222 ChainItem(StateInfo stateInfo, Class syntaxClass, ChainItem prev) { 223 this.stateInfo = stateInfo; 224 this.syntaxClass = syntaxClass; 225 this.prev = prev; 226 } 227 228 } 229 230 } 231 232 233 234 static class SyntaxInfo { 235 236 SyntaxInfo(Syntax syntax, SyntaxInfo prevChainEnd) { 237 this.syntax = syntax; 238 239 if (prevChainEnd != null) { 240 prev = prevChainEnd; 241 prevChainEnd.next = this; 242 } 243 } 244 245 246 Syntax syntax; 247 248 251 boolean active; 252 253 254 SyntaxInfo next; 255 256 257 SyntaxInfo prev; 258 259 } 260 261 } 262 | Popular Tags |