src/Pure/Thy/thy_syntax.scala
changeset 56208 06cc31dff138
parent 55785 3086f57e48e9
child 56314 9a513737a0b2
equal deleted inserted replaced
56207:52d5067ca06a 56208:06cc31dff138
   255         }
   255         }
   256       case None => Nil
   256       case None => Nil
   257     }
   257     }
   258 
   258 
   259   def resolve_files(
   259   def resolve_files(
   260       thy_load: Thy_Load,
   260       resources: Resources,
   261       syntax: Outer_Syntax,
   261       syntax: Outer_Syntax,
   262       node_name: Document.Node.Name,
   262       node_name: Document.Node.Name,
   263       span: List[Token],
   263       span: List[Token],
   264       doc_blobs: Document.Blobs)
   264       doc_blobs: Document.Blobs)
   265     : List[Command.Blob] =
   265     : List[Command.Blob] =
   266   {
   266   {
   267     span_files(syntax, span).map(file_name =>
   267     span_files(syntax, span).map(file_name =>
   268       Exn.capture {
   268       Exn.capture {
   269         val name =
   269         val name =
   270           Document.Node.Name(thy_load.append(node_name.master_dir, Path.explode(file_name)))
   270           Document.Node.Name(resources.append(node_name.master_dir, Path.explode(file_name)))
   271         val blob = doc_blobs.get(name).map(blob => ((blob.bytes.sha1_digest, blob.file)))
   271         val blob = doc_blobs.get(name).map(blob => ((blob.bytes.sha1_digest, blob.file)))
   272         (name, blob)
   272         (name, blob)
   273       })
   273       })
   274   }
   274   }
   275 
   275 
   287       case _ => (cmds, blobs_spans)
   287       case _ => (cmds, blobs_spans)
   288     }
   288     }
   289   }
   289   }
   290 
   290 
   291   private def reparse_spans(
   291   private def reparse_spans(
   292     thy_load: Thy_Load,
   292     resources: Resources,
   293     syntax: Outer_Syntax,
   293     syntax: Outer_Syntax,
   294     doc_blobs: Document.Blobs,
   294     doc_blobs: Document.Blobs,
   295     name: Document.Node.Name,
   295     name: Document.Node.Name,
   296     commands: Linear_Set[Command],
   296     commands: Linear_Set[Command],
   297     first: Command, last: Command): Linear_Set[Command] =
   297     first: Command, last: Command): Linear_Set[Command] =
   298   {
   298   {
   299     val cmds0 = commands.iterator(first, last).toList
   299     val cmds0 = commands.iterator(first, last).toList
   300     val blobs_spans0 =
   300     val blobs_spans0 =
   301       parse_spans(syntax.scan(cmds0.iterator.map(_.source).mkString)).
   301       parse_spans(syntax.scan(cmds0.iterator.map(_.source).mkString)).
   302         map(span => (resolve_files(thy_load, syntax, name, span, doc_blobs), span))
   302         map(span => (resolve_files(resources, syntax, name, span, doc_blobs), span))
   303 
   303 
   304     val (cmds1, blobs_spans1) = chop_common(cmds0, blobs_spans0)
   304     val (cmds1, blobs_spans1) = chop_common(cmds0, blobs_spans0)
   305 
   305 
   306     val (rev_cmds2, rev_blobs_spans2) = chop_common(cmds1.reverse, blobs_spans1.reverse)
   306     val (rev_cmds2, rev_blobs_spans2) = chop_common(cmds1.reverse, blobs_spans1.reverse)
   307     val cmds2 = rev_cmds2.reverse
   307     val cmds2 = rev_cmds2.reverse
   322 
   322 
   323   /* recover command spans after edits */
   323   /* recover command spans after edits */
   324 
   324 
   325   // FIXME somewhat slow
   325   // FIXME somewhat slow
   326   private def recover_spans(
   326   private def recover_spans(
   327     thy_load: Thy_Load,
   327     resources: Resources,
   328     syntax: Outer_Syntax,
   328     syntax: Outer_Syntax,
   329     doc_blobs: Document.Blobs,
   329     doc_blobs: Document.Blobs,
   330     name: Document.Node.Name,
   330     name: Document.Node.Name,
   331     perspective: Command.Perspective,
   331     perspective: Command.Perspective,
   332     commands: Linear_Set[Command]): Linear_Set[Command] =
   332     commands: Linear_Set[Command]): Linear_Set[Command] =
   340     @tailrec def recover(cmds: Linear_Set[Command]): Linear_Set[Command] =
   340     @tailrec def recover(cmds: Linear_Set[Command]): Linear_Set[Command] =
   341       cmds.find(_.is_unparsed) match {
   341       cmds.find(_.is_unparsed) match {
   342         case Some(first_unparsed) =>
   342         case Some(first_unparsed) =>
   343           val first = next_invisible_command(cmds.reverse, first_unparsed)
   343           val first = next_invisible_command(cmds.reverse, first_unparsed)
   344           val last = next_invisible_command(cmds, first_unparsed)
   344           val last = next_invisible_command(cmds, first_unparsed)
   345           recover(reparse_spans(thy_load, syntax, doc_blobs, name, cmds, first, last))
   345           recover(reparse_spans(resources, syntax, doc_blobs, name, cmds, first, last))
   346         case None => cmds
   346         case None => cmds
   347       }
   347       }
   348     recover(commands)
   348     recover(commands)
   349   }
   349   }
   350 
   350 
   351 
   351 
   352   /* consolidate unfinished spans */
   352   /* consolidate unfinished spans */
   353 
   353 
   354   private def consolidate_spans(
   354   private def consolidate_spans(
   355     thy_load: Thy_Load,
   355     resources: Resources,
   356     syntax: Outer_Syntax,
   356     syntax: Outer_Syntax,
   357     doc_blobs: Document.Blobs,
   357     doc_blobs: Document.Blobs,
   358     reparse_limit: Int,
   358     reparse_limit: Int,
   359     name: Document.Node.Name,
   359     name: Document.Node.Name,
   360     perspective: Command.Perspective,
   360     perspective: Command.Perspective,
   372               var i = 0
   372               var i = 0
   373               while (i < reparse_limit && it.hasNext) {
   373               while (i < reparse_limit && it.hasNext) {
   374                 last = it.next
   374                 last = it.next
   375                 i += last.length
   375                 i += last.length
   376               }
   376               }
   377               reparse_spans(thy_load, syntax, doc_blobs, name, commands, first_unfinished, last)
   377               reparse_spans(resources, syntax, doc_blobs, name, commands, first_unfinished, last)
   378             case None => commands
   378             case None => commands
   379           }
   379           }
   380         case None => commands
   380         case None => commands
   381       }
   381       }
   382     }
   382     }
   394     removed.reverse.map(cmd => (old_cmds.prev(cmd), None)) :::
   394     removed.reverse.map(cmd => (old_cmds.prev(cmd), None)) :::
   395     inserted.map(cmd => (new_cmds.prev(cmd), Some(cmd)))
   395     inserted.map(cmd => (new_cmds.prev(cmd), Some(cmd)))
   396   }
   396   }
   397 
   397 
   398   private def text_edit(
   398   private def text_edit(
   399     thy_load: Thy_Load,
   399     resources: Resources,
   400     syntax: Outer_Syntax,
   400     syntax: Outer_Syntax,
   401     doc_blobs: Document.Blobs,
   401     doc_blobs: Document.Blobs,
   402     reparse_limit: Int,
   402     reparse_limit: Int,
   403     node: Document.Node, edit: Document.Edit_Text): Document.Node =
   403     node: Document.Node, edit: Document.Edit_Text): Document.Node =
   404   {
   404   {
   411         if (node.is_blob) node
   411         if (node.is_blob) node
   412         else {
   412         else {
   413           val commands0 = node.commands
   413           val commands0 = node.commands
   414           val commands1 = edit_text(text_edits, commands0)
   414           val commands1 = edit_text(text_edits, commands0)
   415           val commands2 =
   415           val commands2 =
   416             recover_spans(thy_load, syntax, doc_blobs, name, node.perspective.visible, commands1)
   416             recover_spans(resources, syntax, doc_blobs, name, node.perspective.visible, commands1)
   417           node.update_commands(commands2)
   417           node.update_commands(commands2)
   418         }
   418         }
   419 
   419 
   420       case (_, Document.Node.Deps(_)) => node
   420       case (_, Document.Node.Deps(_)) => node
   421 
   421 
   424         val perspective: Document.Node.Perspective_Command =
   424         val perspective: Document.Node.Perspective_Command =
   425           Document.Node.Perspective(required, visible_overlay, overlays)
   425           Document.Node.Perspective(required, visible_overlay, overlays)
   426         if (node.same_perspective(perspective)) node
   426         if (node.same_perspective(perspective)) node
   427         else
   427         else
   428           node.update_perspective(perspective).update_commands(
   428           node.update_perspective(perspective).update_commands(
   429             consolidate_spans(thy_load, syntax, doc_blobs, reparse_limit,
   429             consolidate_spans(resources, syntax, doc_blobs, reparse_limit,
   430               name, visible, node.commands))
   430               name, visible, node.commands))
   431     }
   431     }
   432   }
   432   }
   433 
   433 
   434   def text_edits(
   434   def text_edits(
   435       thy_load: Thy_Load,
   435       resources: Resources,
   436       reparse_limit: Int,
   436       reparse_limit: Int,
   437       previous: Document.Version,
   437       previous: Document.Version,
   438       doc_blobs: Document.Blobs,
   438       doc_blobs: Document.Blobs,
   439       edits: List[Document.Edit_Text])
   439       edits: List[Document.Edit_Text])
   440     : (Boolean, List[Document.Edit_Command], Document.Version) =
   440     : (Boolean, List[Document.Edit_Command], Document.Version) =
   441   {
   441   {
   442     val ((syntax, syntax_changed), reparse0, nodes0, doc_edits0) =
   442     val ((syntax, syntax_changed), reparse0, nodes0, doc_edits0) =
   443       header_edits(thy_load.base_syntax, previous, edits)
   443       header_edits(resources.base_syntax, previous, edits)
   444 
   444 
   445     if (edits.isEmpty)
   445     if (edits.isEmpty)
   446       (false, Nil, Document.Version.make(syntax, previous.nodes))
   446       (false, Nil, Document.Version.make(syntax, previous.nodes))
   447     else {
   447     else {
   448       val reparse =
   448       val reparse =
   467           val commands = node.commands
   467           val commands = node.commands
   468 
   468 
   469           val node1 =
   469           val node1 =
   470             if (reparse_set(name) && !commands.isEmpty)
   470             if (reparse_set(name) && !commands.isEmpty)
   471               node.update_commands(
   471               node.update_commands(
   472                 reparse_spans(thy_load, syntax, doc_blobs,
   472                 reparse_spans(resources, syntax, doc_blobs,
   473                   name, commands, commands.head, commands.last))
   473                   name, commands, commands.head, commands.last))
   474             else node
   474             else node
   475           val node2 = (node1 /: edits)(text_edit(thy_load, syntax, doc_blobs, reparse_limit, _, _))
   475           val node2 = (node1 /: edits)(text_edit(resources, syntax, doc_blobs, reparse_limit, _, _))
   476 
   476 
   477           if (!(node.same_perspective(node2.perspective)))
   477           if (!(node.same_perspective(node2.perspective)))
   478             doc_edits += (name -> node2.perspective)
   478             doc_edits += (name -> node2.perspective)
   479 
   479 
   480           doc_edits += (name -> Document.Node.Edits(diff_commands(commands, node2.commands)))
   480           doc_edits += (name -> Document.Node.Edits(diff_commands(commands, node2.commands)))