150 (this /: msgs)((state, msg) => |
150 (this /: msgs)((state, msg) => |
151 { |
151 { |
152 def bad(): Unit = System.err.println("Ignored report message: " + msg) |
152 def bad(): Unit = System.err.println("Ignored report message: " + msg) |
153 |
153 |
154 msg match { |
154 msg match { |
155 case XML.Elem(Markup(name, atts @ Position.Reported(id, file_name, raw_range)), args) |
155 case XML.Elem(Markup(name, |
|
156 atts @ Position.Reported(id, file_name, symbol_range)), args) |
156 if id == command.id || id == alt_id => |
157 if id == command.id || id == alt_id => |
157 command.chunks.get(file_name) match { |
158 command.chunks.get(file_name) match { |
158 case Some(chunk) => |
159 case Some(chunk) => |
159 chunk.incorporate(raw_range) match { |
160 chunk.incorporate(symbol_range) match { |
160 case Some(range) => |
161 case Some(range) => |
161 val props = Position.purge(atts) |
162 val props = Position.purge(atts) |
162 val info = Text.Info(range, XML.Elem(Markup(name, props), args)) |
163 val info = Text.Info(range, XML.Elem(Markup(name, props), args)) |
163 state.add_markup(false, file_name, info) |
164 state.add_markup(false, file_name, info) |
164 case None => bad(); state |
165 case None => bad(); state |
214 abstract class Chunk |
215 abstract class Chunk |
215 { |
216 { |
216 def file_name: String |
217 def file_name: String |
217 def length: Int |
218 def length: Int |
218 def range: Text.Range |
219 def range: Text.Range |
219 def decode(raw_range: Text.Range): Text.Range |
220 def decode(symbol_range: Symbol.Range): Text.Range |
220 |
221 |
221 def incorporate(raw_range: Text.Range): Option[Text.Range] = |
222 def incorporate(symbol_range: Symbol.Range): Option[Text.Range] = |
222 { |
223 { |
223 def inc(r: Text.Range): Option[Text.Range] = |
224 def inc(r: Symbol.Range): Option[Text.Range] = |
224 range.try_restrict(decode(r)) match { |
225 range.try_restrict(decode(r)) match { |
225 case Some(r1) if !r1.is_singularity => Some(r1) |
226 case Some(r1) if !r1.is_singularity => Some(r1) |
226 case _ => None |
227 case _ => None |
227 } |
228 } |
228 inc(raw_range) orElse inc(raw_range - 1) |
229 inc(symbol_range) orElse inc(symbol_range - 1) |
229 } |
230 } |
230 } |
231 } |
231 |
232 |
232 class File(val file_name: String, text: CharSequence) extends Chunk |
233 class File(val file_name: String, text: CharSequence) extends Chunk |
233 { |
234 { |
234 val length = text.length |
235 val length = text.length |
235 val range = Text.Range(0, length) |
236 val range = Text.Range(0, length) |
236 private val symbol_index = Symbol.Index(text) |
237 private val symbol_index = Symbol.Index(text) |
237 def decode(raw_range: Text.Range): Text.Range = symbol_index.decode(raw_range) |
238 def decode(symbol_range: Symbol.Range): Text.Range = symbol_index.decode(symbol_range) |
238 |
239 |
239 override def toString: String = "Command.File(" + file_name + ")" |
240 override def toString: String = "Command.File(" + file_name + ")" |
240 } |
241 } |
241 |
242 |
242 |
243 |
372 Text.Range(0, (length /: span.reverse.iterator.takeWhile(_.is_improper))(_ - _.source.length)) |
373 Text.Range(0, (length /: span.reverse.iterator.takeWhile(_.is_improper))(_ - _.source.length)) |
373 |
374 |
374 def source(range: Text.Range): String = source.substring(range.start, range.stop) |
375 def source(range: Text.Range): String = source.substring(range.start, range.stop) |
375 |
376 |
376 private lazy val symbol_index = Symbol.Index(source) |
377 private lazy val symbol_index = Symbol.Index(source) |
377 def decode(raw_offset: Text.Offset): Text.Offset = symbol_index.decode(raw_offset) |
378 def decode(symbol_offset: Symbol.Offset): Text.Offset = symbol_index.decode(symbol_offset) |
378 def decode(raw_range: Text.Range): Text.Range = symbol_index.decode(raw_range) |
379 def decode(symbol_range: Symbol.Range): Text.Range = symbol_index.decode(symbol_range) |
379 |
380 |
380 |
381 |
381 /* accumulated results */ |
382 /* accumulated results */ |
382 |
383 |
383 val init_state: Command.State = |
384 val init_state: Command.State = |