Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The Play Template compiler is too slow for interactive use #50

Open
dragos opened this issue Mar 26, 2013 · 14 comments
Open

The Play Template compiler is too slow for interactive use #50

dragos opened this issue Mar 26, 2013 · 14 comments

Comments

@dragos
Copy link
Member

dragos commented Mar 26, 2013

We need to rewrite the template compiler. The current version, based on parser combinators, is too slow to be used in the IDE. One example (about 200ms between each keystroke), caught by Svelto:

    at scala.util.parsing.combinator.RegexParsers$$anon$1.apply(RegexParsers.scala:85)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1$$anonfun$apply$2.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1$$anonfun$apply$2.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Failure.append(Parsers.scala:202)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$$anonfun$not$1.apply(Parsers.scala:844)
    at scala.util.parsing.combinator.Parsers$$anonfun$not$1.apply(Parsers.scala:843)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$flatMap$1.apply(Parsers.scala:239)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$flatMap$1.apply(Parsers.scala:239)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Success.flatMapWithNext(Parsers.scala:142)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$flatMap$1.apply(Parsers.scala:239)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$flatMap$1.apply(Parsers.scala:239)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1$$anonfun$apply$2.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1$$anonfun$apply$2.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Failure.append(Parsers.scala:202)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$$anonfun$rep1$1.applyp$1(Parsers.scala:727)
    at scala.util.parsing.combinator.Parsers$$anonfun$rep1$1.continue$1(Parsers.scala:733)
    at scala.util.parsing.combinator.Parsers$$anonfun$rep1$1.apply(Parsers.scala:737)
    at scala.util.parsing.combinator.Parsers$$anonfun$rep1$1.apply(Parsers.scala:721)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$$anonfun$positioned$1.apply(Parsers.scala:874)
    at scala.util.parsing.combinator.Parsers$$anonfun$positioned$1.apply(Parsers.scala:873)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.RegexParsers$$anon$3.apply(RegexParsers.scala:134)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1$$anonfun$apply$2.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1$$anonfun$apply$2.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Failure.append(Parsers.scala:202)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at play.templates.ScalaTemplateCompiler$TemplateParser$$anonfun$several$1.applyp$1(ScalaTemplateCompiler.scala:259)
    at play.templates.ScalaTemplateCompiler$TemplateParser$$anonfun$several$1.continue$1(ScalaTemplateCompiler.scala:264)
    at play.templates.ScalaTemplateCompiler$TemplateParser$$anonfun$several$1.apply(ScalaTemplateCompiler.scala:266)
    at play.templates.ScalaTemplateCompiler$TemplateParser$$anonfun$several$1.apply(ScalaTemplateCompiler.scala:253)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Success.flatMapWithNext(Parsers.scala:142)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$flatMap$1.apply(Parsers.scala:239)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$flatMap$1.apply(Parsers.scala:239)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Success.flatMapWithNext(Parsers.scala:142)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$flatMap$1.apply(Parsers.scala:239)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$flatMap$1.apply(Parsers.scala:239)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$flatMap$1.apply(Parsers.scala:239)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$flatMap$1.apply(Parsers.scala:239)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at play.templates.ScalaTemplateCompiler$TemplateParser$$anonfun$ensureMatchedBrackets$1.apply(ScalaTemplateCompiler.scala:320)
    at play.templates.ScalaTemplateCompiler$TemplateParser$$anonfun$ensureMatchedBrackets$1.apply(ScalaTemplateCompiler.scala:318)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Success.flatMapWithNext(Parsers.scala:142)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$flatMap$1.apply(Parsers.scala:239)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$flatMap$1.apply(Parsers.scala:239)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$$anonfun$positioned$1.apply(Parsers.scala:874)
    at scala.util.parsing.combinator.Parsers$$anonfun$positioned$1.apply(Parsers.scala:873)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.RegexParsers$$anon$3.apply(RegexParsers.scala:134)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1$$anonfun$apply$2.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1$$anonfun$apply$2.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Failure.append(Parsers.scala:202)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at play.templates.ScalaTemplateCompiler$TemplateParser$$anonfun$several$1.applyp$1(ScalaTemplateCompiler.scala:259)
    at play.templates.ScalaTemplateCompiler$TemplateParser$$anonfun$several$1.continue$1(ScalaTemplateCompiler.scala:264)
    at play.templates.ScalaTemplateCompiler$TemplateParser$$anonfun$several$1.apply(ScalaTemplateCompiler.scala:266)
    at play.templates.ScalaTemplateCompiler$TemplateParser$$anonfun$several$1.apply(ScalaTemplateCompiler.scala:253)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Success.flatMapWithNext(Parsers.scala:142)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$flatMap$1.apply(Parsers.scala:239)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$flatMap$1.apply(Parsers.scala:239)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$flatMap$1.apply(Parsers.scala:239)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$flatMap$1.apply(Parsers.scala:239)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Success.flatMapWithNext(Parsers.scala:142)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$flatMap$1.apply(Parsers.scala:239)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$flatMap$1.apply(Parsers.scala:239)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$flatMap$1.apply(Parsers.scala:239)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$flatMap$1.apply(Parsers.scala:239)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1$$anonfun$apply$2.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1$$anonfun$apply$2.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Failure.append(Parsers.scala:202)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1$$anonfun$apply$2.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1$$anonfun$apply$2.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Failure.append(Parsers.scala:202)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$append$1.apply(Parsers.scala:254)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at play.templates.ScalaTemplateCompiler$TemplateParser$$anonfun$several$1.applyp$1(ScalaTemplateCompiler.scala:259)
    at play.templates.ScalaTemplateCompiler$TemplateParser$$anonfun$several$1.continue$1(ScalaTemplateCompiler.scala:264)
    at play.templates.ScalaTemplateCompiler$TemplateParser$$anonfun$several$1.apply(ScalaTemplateCompiler.scala:266)
    at play.templates.ScalaTemplateCompiler$TemplateParser$$anonfun$several$1.apply(ScalaTemplateCompiler.scala:253)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Success.flatMapWithNext(Parsers.scala:142)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$flatMap$1.apply(Parsers.scala:239)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$flatMap$1.apply(Parsers.scala:239)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$Parser$$anonfun$map$1.apply(Parsers.scala:242)
    at scala.util.parsing.combinator.Parsers$$anon$3.apply(Parsers.scala:222)
    at play.templates.ScalaTemplateCompiler$.parseAndGenerateCode(ScalaTemplateCompiler.scala:194)
    at play.templates.ScalaTemplateCompiler$.compileVirtual(ScalaTemplateCompiler.scala:188)
    at org.scalaide.play2.templateeditor.compiler.CompilerUsing$.compileTemplateToScalaVirtual(CompilerUsing.scala:37)
    at org.scalaide.play2.templateeditor.TemplateCompilationUnit.generatedSource(TemplateCompilationUnit.scala:174)
    -  locked org.scalaide.play2.templateeditor.TemplateCompilationUnit@6f392e38
    at org.scalaide.play2.templateeditor.TemplateCompilationUnit.<init>(TemplateCompilationUnit.scala:163)
    at org.scalaide.play2.templateeditor.TemplateCompilationUnit$.fromEditorInput(TemplateCompilationUnit.scala:190)
    at org.scalaide.play2.templateeditor.TemplateCompilationUnit$.fromEditor(TemplateCompilationUnit.scala:197)
    at org.scalaide.play2.templateeditor.TemplateEditor.getInteractiveCompilationUnit(TemplateEditor.scala:61)
    at scala.tools.eclipse.util.EditorUtils$.getEditorCompilationUnit(EditorUtils.scala:27)
    at scala.tools.eclipse.hyperlink.text.detector.BaseHyperlinkDetector.detectHyperlinks(BaseHyperlinkDetector.scala:35)
    at scala.tools.eclipse.hyperlink.text.detector.BaseHyperlinkDetector.detectHyperlinks(BaseHyperlinkDetector.scala:23)
    at org.eclipse.jface.text.hyperlink.HyperlinkManager.findHyperlinks(HyperlinkManager.java:286)
    -  locked [Lorg.eclipse.jface.text.hyperlink.IHyperlinkDetector;@477543fa
    at org.eclipse.jface.text.hyperlink.HyperlinkManager.findHyperlinks(HyperlinkManager.java:258)
    at org.eclipse.jface.text.hyperlink.HyperlinkManager.mouseMove(HyperlinkManager.java:462)
    at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:211)
    at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
    at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4128)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1457)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1480)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1465)
    at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:1270)
    at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3974)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3613)
    at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2701)
    at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2665)
    at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2499)
    at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:679)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
    at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:668)
    at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
    at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123)
    at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
@skyluc
Copy link
Member

skyluc commented Mar 26, 2013

I'm not against it, but first we will have to create some spec of the format ... 😕

@rschellhorn
Copy link

Noticed this behavior too, especially in files containing a compilation error.

@aldenml
Copy link
Contributor

aldenml commented Mar 26, 2013

Hi @dragos, any insight of how to tackle this rewrite? Is the presentation compiler a good example to dive in?

@dragos
Copy link
Member Author

dragos commented Mar 26, 2013

@aldenml, what I have in mind is a plain old recursive descent parser. The Scala parser is one example, but probably way too complex to start with.

@aldenml
Copy link
Contributor

aldenml commented Mar 27, 2013

@dragos I was taking a deep look to ScalaTemplateCompiler and Parsers (from Scala nsc). It seems to me that ScalaTemplateCompiler (directly copied from Play2) is using an outdated (not so fast) API and could be reimplemented using the new compiler framework (avoiding the combinators based JavaTokensParser). It would be ideal to perform this change in sync with the Play2 team. This change alone could improve the performance issue.

The other point is that this "template compiler" is used as part of the code generation with every template file change. I didn't have the time to review what happens if you use Play2 with Java, btw.

Do you think it is a viable path first fix/improve what is already in place before creating another compiler?

@skyluc Do you know where can I find documentation about creating unit tests for this kind of hard UI-Core issue?

@dragos
Copy link
Member Author

dragos commented Mar 27, 2013

@aldenml, on a cursory inspection, the parser here doesn't look very different from the one we forked a few months ago. I am not terribly fond of combinator parsers, but if you think they can be made fast, why not.

Regarding contributing it back upstream, we'd be very happy to do that, of course. I imagine that the parser should be disentangled from the code-generating part. If the AST stays the same, the current code generator can be reused.

As for tests, there's nothing UI specific here, so if there's a test suite in Play, it should be able to pass that. And we should also make sure it's sufficiently fast (the benchmark remains to be decided)

@aldenml
Copy link
Contributor

aldenml commented Mar 27, 2013

Just to make myself more clear. The current ScalaTemplateCompiler is from a PR I made, I just copy/paste-ed the source code from Play2. Its the original "compiler" in Play2 that its based on combinators and a bit outdated. They will see an improvement if the compiler is moved to the new nsc, IMO. In any case, this is not an easy task.

@dragos
Copy link
Member Author

dragos commented Mar 27, 2013

Ah, so it's you! :)

Anyway, since the template parser does not need to parse scala source, but only a few syntax elements and the @ magic, it shouldn't be too difficult, nor do I think it needs to reuse the Scala parser (that was just an example).

@aldenml
Copy link
Contributor

aldenml commented Mar 27, 2013

Well, yeah...:)

I need to study more about the plugin to follow this thread (specially the template source code generation)

@dragos
Copy link
Member Author

dragos commented Mar 28, 2013

@aldenml, I didn't mean to discourage you! I am happy to clarify any points I made (maybe we can take this to the scala-ide-dev@ mailing list).

@aldenml
Copy link
Contributor

aldenml commented Mar 28, 2013

@dragos Sure! and I'm very motivated, now that I see a lot of activity towards a release. I need more time to study in deep this part and I will post any generic question in the mailing list.

@aldenml
Copy link
Contributor

aldenml commented Apr 27, 2013

I noticed that the compiler is called about 4X for each keystroke in the editor (2 with the old content and 2 (or 1) with the new one). Optimizing this will help a lot.

@dragos
Copy link
Member Author

dragos commented Apr 27, 2013

@aldenml that's a good starting point indeed! Not sure what's going on..

@jhaberstro
Copy link
Contributor

I've come across the same issue in writing the structured text template editor. For example, try button smashing in this file: https://github.com/playframework/Play20/blob/master/samples/scala/computer-database/app/views/list.scala.html

You will see that the editor very noticeably lags behind keystrokes. I performed a cpu sampling, and by far and large all of the time spent was in the parser combinator library. Just reiterating this information here to remind us to replace the parser soon :-).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants