Smart Code editors with JavaFX (and e4) Tom Schindl <tom.schindl@bestsolution.at> Twitter: @tomsontom Blog: http://tomsondev.bestsolution.at Website: http://www.bestsolution.at
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 About Me ‣ CTO BestSolution.at Systemhaus GmbH ‣ Eclipse Committer ‣ e4 ‣ Platform ‣ EMF ‣ Project lead ‣ e(fx)clipse ‣ Twitter: @tomsontom ‣ Blog: tomsondev.bestsolution.at ‣ Cooperate: http://bestsolution.at
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Today
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Today ‣ Current situation ‣ Eclipse 4 Application Platform does not support editors ‣ Eclipse IDE / Eclipse 3.x RCP is still required to get an editor framework
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Today ‣ Current situation ‣ Eclipse 4 Application Platform does not support editors ‣ Eclipse IDE / Eclipse 3.x RCP is still required to get an editor framework ‣ Future situation ‣ Eclipse 4 should support editors natively ‣ Loosely coupled components / services who work in Eclipse4, plain Java, jigsaw world
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 3.x Codeeditors ‣ Should we directly port the 3.x code-editor stuff to Eclipse 4?
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 3.x Codeeditors ‣ Should we directly port the 3.x code-editor stuff to Eclipse 4? EditorPart
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 3.x Codeeditors ‣ Should we directly port the 3.x code-editor stuff to Eclipse 4? EditorPart AbstractTextEditor
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 3.x Codeeditors ‣ Should we directly port the 3.x code-editor stuff to Eclipse 4? EditorPart AbstractTextEditor JavaEditor DartEditor …Editor
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Codeeditors the e4 way ‣ Editors in a DI/Service env
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Syntax-Highlighting Codeeditors the e4 way ‣ Editors in a DI/Service env
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Syntax-Highlighting Error Marker Codeeditors the e4 way ‣ Editors in a DI/Service env
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Syntax-Highlighting Documentation Info Error Marker Codeeditors the e4 way ‣ Editors in a DI/Service env
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Syntax-Highlighting Autocomplete Documentation Info Error Marker Codeeditors the e4 way ‣ Editors in a DI/Service env
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 IEditorInput replacement ‣ Basic API is named Input<O>
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 IEditorInput replacement ‣ Basic API is named Input<O> public interface Input<O> { public void dispose(); public O getData(); public void setData(O data); public void persist(); }
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 IEditorInput replacement ‣ Basic API is named Input<O> public interface Input<O> { public void dispose(); public O getData(); public void setData(O data); public void persist(); } Input<O>
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 IEditorInput replacement ‣ Basic API is named Input<O> public interface Input<O> { public void dispose(); public O getData(); public void setData(O data); public void persist(); } Input<O> StringInput<String>
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 IEditorInput replacement ‣ Basic API is named Input<O> public interface Input<O> { public void dispose(); public O getData(); public void setData(O data); public void persist(); } Input<O> StringInput<String> SourceFileInput
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 IEditorInput replacement ‣ Basic API is named Input<O> public interface Input<O> { public void dispose(); public O getData(); public void setData(O data); public void persist(); } Input<O> StringInput<String> SourceFileInput NIOSourceFile EFSSourceFile
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Text Parsing/Highlighting
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Text Parsing/Highlighting ‣ Stay with Eclipse Text!
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Text Parsing/Highlighting ‣ Stay with Eclipse Text! ‣ many parts are UI-Toolkit agnostic
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Text Parsing/Highlighting ‣ Stay with Eclipse Text! ‣ many parts are UI-Toolkit agnostic ‣ Eclipse text does not require OSGi / 3.x APIs
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Text Parsing/Highlighting ‣ Stay with Eclipse Text! ‣ many parts are UI-Toolkit agnostic ‣ Eclipse text does not require OSGi / 3.x APIs ‣ It is fast
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Text Parsing/Highlighting ‣ Stay with Eclipse Text! ‣ many parts are UI-Toolkit agnostic ‣ Eclipse text does not require OSGi / 3.x APIs ‣ It is fast ‣ It does its job
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Text Parsing/Highlighting ‣ Stay with Eclipse Text! ‣ many parts are UI-Toolkit agnostic ‣ Eclipse text does not require OSGi / 3.x APIs ‣ It is fast ‣ It does its job ‣ It is insanely fast
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse Text Performance ‣ In JavaFX world there are 2 opensource controls for StyledTextArea (from e(fx)clipse), RichTextArea on github ‣ Both Frameworks have a pluggable Parser Infrastructure and provide default/sample parsers
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse Text Performance StyleText (Eclipse Text) RichText (regex) ‣ In JavaFX world there are 2 opensource controls for StyledTextArea (from e(fx)clipse), RichTextArea on github ‣ Both Frameworks have a pluggable Parser Infrastructure and provide default/sample parsers
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse Text Performance StyleText (Eclipse Text) RichText (regex) init - 10 000 Loc 327ms 400ms ‣ In JavaFX world there are 2 opensource controls for StyledTextArea (from e(fx)clipse), RichTextArea on github ‣ Both Frameworks have a pluggable Parser Infrastructure and provide default/sample parsers
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse Text Performance StyleText (Eclipse Text) RichText (regex) init - 10 000 Loc 327ms 400ms init - 150 000 Loc 1100ms 3300ms ‣ In JavaFX world there are 2 opensource controls for StyledTextArea (from e(fx)clipse), RichTextArea on github ‣ Both Frameworks have a pluggable Parser Infrastructure and provide default/sample parsers
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse Text Performance StyleText (Eclipse Text) RichText (regex) init - 10 000 Loc 327ms 400ms init - 150 000 Loc 1100ms 3300ms change - 10 000 Loc 30ms 110ms (*) ‣ In JavaFX world there are 2 opensource controls for StyledTextArea (from e(fx)clipse), RichTextArea on github ‣ Both Frameworks have a pluggable Parser Infrastructure and provide default/sample parsers
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse Text Performance StyleText (Eclipse Text) RichText (regex) init - 10 000 Loc 327ms 400ms init - 150 000 Loc 1100ms 3300ms change - 10 000 Loc 30ms 110ms (*) change - 150 000 Loc 50ms 1800ms (*) ‣ In JavaFX world there are 2 opensource controls for StyledTextArea (from e(fx)clipse), RichTextArea on github ‣ Both Frameworks have a pluggable Parser Infrastructure and provide default/sample parsers
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse Text Performance * Potential Bug: numbers might be devided by 2 StyleText (Eclipse Text) RichText (regex) init - 10 000 Loc 327ms 400ms init - 150 000 Loc 1100ms 3300ms change - 10 000 Loc 30ms 110ms (*) change - 150 000 Loc 50ms 1800ms (*) ‣ In JavaFX world there are 2 opensource controls for StyledTextArea (from e(fx)clipse), RichTextArea on github ‣ Both Frameworks have a pluggable Parser Infrastructure and provide default/sample parsers
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse Text in a nutshell ‣ Two step process
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse Text in a nutshell ‣ Two step process ‣ Step 1: Partitioning done by the org.eclipse.jface.text.IDocumentPartitioner
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse Text in a nutshell ‣ Two step process ‣ Step 1: Partitioning done by the org.eclipse.jface.text.IDocumentPartitioner ‣ Step 2: Tokenizing done by the org.eclipse.jface.text.presentation.IPresentationReconc iler
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning /** * This is a sample class */ class Sample { //Some information public void test() { /* * Some more information */ var s = "Hello World" ; print(s); } }
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning /** * This is a sample class */ class Sample { //Some information public void test() { /* * Some more information */ var s = "Hello World" ; print(s); } } __dart_dartdoc
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning /** * This is a sample class */ class Sample { //Some information public void test() { /* * Some more information */ var s = "Hello World" ; print(s); } } __dart_dartdoc __dart_sl_comment
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning /** * This is a sample class */ class Sample { //Some information public void test() { /* * Some more information */ var s = "Hello World" ; print(s); } } __dart_dartdoc __dart_sl_comment __dart_ml_comment
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning /** * This is a sample class */ class Sample { //Some information public void test() { /* * Some more information */ var s = "Hello World" ; print(s); } } __dart_dartdoc __dart_sl_comment __dart_ml_comment __dart_string
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning /** * This is a sample class */ class Sample { //Some information public void test() { /* * Some more information */ var s = "Hello World" ; print(s); } } __dart_dartdoc __dart_sl_comment __dart_ml_comment __dart_string __dftl_partitioning
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning Rules
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning Rules Start End MultiLine
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning Rules Start End MultiLine dartdoc /** */ !
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning Rules Start End MultiLine dartdoc /** */ ! comment single // "
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning Rules Start End MultiLine dartdoc /** */ ! comment single // " comment multi /* */ !
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning Rules Start End MultiLine dartdoc /** */ ! comment single // " comment multi /* */ ! string " " "
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning Rules Start End MultiLine dartdoc /** */ ! comment single // " comment multi /* */ ! string " " " character ' ' "
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 ‣ Base interface org.eclipse.jface.text.rules.IRule ‣ 2 Basic implementations ‣ SingleLineRule ‣ MultiLineRule Rules in Eclipse Text
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 ‣ Base interface org.eclipse.jface.text.rules.IRule ‣ 2 Basic implementations ‣ SingleLineRule ‣ MultiLineRule Rules in Eclipse Text new SingleLineRule("//", null, new Token("__dart_sl_comment")); new MultiLineRule("/**", "*/", new Token("__dart_dartdoc");
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 ‣ Eclipse Text provides a default implementation for the IDocumentParitioner named FastPartitioner ‣ FastPartitioner delegates the real partitioning to an IPartitionTokenScanner ‣ Eclipse Text provides a default implementation for IPartitionScanner named RuleBasedPartitionScanner ‣ RuleBasedPartitionScanner use IRule definitions to detect partitions From Rules to Partitioner
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 From Rules to Partitioner
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 From Rules to Partitioner public class DartPartitionScanner extends RuleBasedPartitionScanner {
 IPredicateRule[] pr = new org.eclipse.jface.text.rules.IPredicateRule[6];
 pr[0] = new SingleLineRule("//", null, new Token("__dart_sl_comment");
 // … 
 }

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 From Rules to Partitioner public class DartPartitionScanner extends RuleBasedPartitionScanner {
 IPredicateRule[] pr = new org.eclipse.jface.text.rules.IPredicateRule[6];
 pr[0] = new SingleLineRule("//", null, new Token("__dart_sl_comment");
 // … 
 }
 public class DartPartitioner extends FastPartitioner {
 public DartPartitioner() {
 super(new DartPartitionScanner(), new String[] {
 "__dart_singlelinedoc_comment"
 ,"__dart_dartdoc"
 ,"__dart_sl_comment"
 ,"__dart_multiline_comment"
 ,"__dart_string"
 });
 }
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 From Rules to Partitioner public class DartPartitionScanner extends RuleBasedPartitionScanner {
 IPredicateRule[] pr = new org.eclipse.jface.text.rules.IPredicateRule[6];
 pr[0] = new SingleLineRule("//", null, new Token("__dart_sl_comment");
 // … 
 }
 public class DartPartitioner extends FastPartitioner {
 public DartPartitioner() {
 super(new DartPartitionScanner(), new String[] {
 "__dart_singlelinedoc_comment"
 ,"__dart_dartdoc"
 ,"__dart_sl_comment"
 ,"__dart_multiline_comment"
 ,"__dart_string"
 });
 } }
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Express Partitions in a DSL ‣ Instead of writing a bunch of Java configuration code we could define a DSL and generate the code
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Express Partitions in a DSL ‣ Instead of writing a bunch of Java configuration code we could define a DSL and generate the code package langs dart { partitioning { partition __dftl_partition_content_type partition __dart_singlelinedoc_comment partition __dart_dartdoc partition __dart_sl_comment partition __dart_multiline_comment partition __dart_string rule { single_line __dart_string "'" => "'" escaped by "" single_line __dart_string '"' => '"' escaped by "" single_line __dart_singlelinedoc_comment '///' single_line __dart_sl_comment '//' multi_line __dart_dartdoc '/**' => '*/' multi_line __dart_multiline_comment '/*' => '*/' } } … }
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Tokenizing a Partition /** * This is a sample class */ class Sample { public void test(String s) { print(s); } }
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Tokenizing a Partition /** * This is a sample class */ class Sample { public void test(String s) { print(s); } } tk(dart_doc,0,25)
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Tokenizing a Partition /** * This is a sample class */ class Sample { public void test(String s) { print(s); } } tk(dart_doc,0,25)
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Tokenizing a Partition /** * This is a sample class */ class Sample { public void test(String s) { print(s); } } tk(dart_doc,0,25) tk(dart_keyword,27,31) tk(dart_keyword,41,45)
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Tokenizing a Partition /** * This is a sample class */ class Sample { public void test(String s) { print(s); } } tk(dart_doc,0,25) tk(dart_keyword,27,31) tk(dart_keyword,41,45) tk(dart_default,28,34)
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 ‣ Uses same IRules APIs as for partitioning ‣ Prebuilt rules useable for Tokenizing ‣ CombinedWordRule: Used for keywords ‣ CharacterRule: Used for single chars eg braces, operators ‣ SingleLineRule, MultiLineRule, PatternRule, … Tokenizing Rules
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 From Rules to Reconciler ‣ Eclipse Text provides a default implementation for IPresentationReconciler named PresentationReconciler ‣ PresentationReconciler requires an IPresentationDamager and IPresentationRepairer / Partition ‣ Eclipse Text provides a default implementation for IPresentationDamager & IPresentationRepairer named DefaultDamagerRepairer ‣ DefaultDamagerRepairer uses an ITokenScanner ‣ Eclipse Text provide a default implementation ITokenScanner named RuleBasedScanner who uses IRule
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 From Rules to Reconciler
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 From Rules to Reconciler public class DartDefPartitionScanner extends RuleBasedScanner {
 public DartDefPartitionScanner() {
 Token dart_defaultToken = new Token(new TextAttribute("dart.dart_default"));
 setDefaultReturnToken(dart_defaultToken);
 Token dart_keywordToken = new Token(new TextAttribute("dart.dart_keyword"));
 
 JavaLikeWordDetector wordDetector= new JavaLikeWordDetector();
 CombinedWordRule combinedWordRule= new CombinedWordRule(wordDetector, dart_defaultToken);
 CombinedWordRule.WordMatcher dart_keywordWordRule = new CombinedWordRule.WordMatcher();
 dart_keywordWordRule.addWord("break", dart_keywordToken);
 // … 
 combinedWordRule.addWordMatcher(dart_keywordWordRule);
 } 
 }

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 From Rules to Reconciler public class DartDefPartitionScanner extends RuleBasedScanner {
 public DartDefPartitionScanner() {
 Token dart_defaultToken = new Token(new TextAttribute("dart.dart_default"));
 setDefaultReturnToken(dart_defaultToken);
 Token dart_keywordToken = new Token(new TextAttribute("dart.dart_keyword"));
 
 JavaLikeWordDetector wordDetector= new JavaLikeWordDetector();
 CombinedWordRule combinedWordRule= new CombinedWordRule(wordDetector, dart_defaultToken);
 CombinedWordRule.WordMatcher dart_keywordWordRule = new CombinedWordRule.WordMatcher();
 dart_keywordWordRule.addWord("break", dart_keywordToken);
 // … 
 combinedWordRule.addWordMatcher(dart_keywordWordRule);
 } 
 }
 public class DartPresentationReconciler extends PresentationReconciler {
 public DartPresentationReconciler() {
 DefaultDamagerRepairer defDamageRepairer = new DefaultDamagerRepairer(new DartDefPartitionScanner());
 setDamager(defDamageRepairer, "__dftl_partition_content_type");
 setRepairer(defDamageRepairer, "__dftl_partition_content_type");
 
 DefaultDamagerRepairer docDamageRepairer = new DefaultDamagerRepairer(new DartDocPartitionScanner());
 setDamager(docDamageRepairer, "__dart_dartdoc");
 setRepairer(docDamageRepairer, "__dart_dartdoc");
 // …
 }
 }
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Express Tokens in the DSL
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Express Tokens in the DSL package langs
 
 dart {
 partitioning {
 partition __dftl_partition_content_type
 partition __dart_dartdoc
 // …
 }
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Express Tokens in the DSL package langs
 
 dart {
 partitioning {
 partition __dftl_partition_content_type
 partition __dart_dartdoc
 // …
 } lexical_highlighting {
 rule __dftl_partition_content_type {
 default dart_default
 dart_keyword {
 keywords [ "break", "case", /* … */ ]
 }
 }
 rule __dart_dartdoc {
 default dart_doc
 dart_doc_reference {
 single_line "[" => "]"
 } 
 }
 }
 }
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Visual representation
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Visual representation public class DartDefPartitionScanner extends RuleBasedScanner {
 public DartDefPartitionScanner() {
 Token dart_defaultToken = new Token(new TextAttribute("dart.dart_default"));
 setDefaultReturnToken(dart_defaultToken);
 Token dart_keywordToken = new Token(new TextAttribute("dart.dart_keyword"));
 
 // …
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Visual representation public class DartDefPartitionScanner extends RuleBasedScanner {
 public DartDefPartitionScanner() {
 Token dart_defaultToken = new Token(new TextAttribute("dart.dart_default"));
 setDefaultReturnToken(dart_defaultToken);
 Token dart_keywordToken = new Token(new TextAttribute("dart.dart_keyword"));
 
 // … // … somewhere in StyledTextArea StyledTextNode s = new StyledTextNode("public"); s.getStyleClass().setAll("dart","dart_keyword"); // … somewhere in StyledTextArea
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Visual representation public class DartDefPartitionScanner extends RuleBasedScanner {
 public DartDefPartitionScanner() {
 Token dart_defaultToken = new Token(new TextAttribute("dart.dart_default"));
 setDefaultReturnToken(dart_defaultToken);
 Token dart_keywordToken = new Token(new TextAttribute("dart.dart_keyword"));
 
 // … // … somewhere in StyledTextArea StyledTextNode s = new StyledTextNode("public"); s.getStyleClass().setAll("dart","dart_keyword"); // … somewhere in StyledTextArea .styled-text-area .dart.dart_keyword { -styled-text-color: rgb(127, 0, 85); -fx-font-weight: bold; }
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Visual representation public class DartDefPartitionScanner extends RuleBasedScanner {
 public DartDefPartitionScanner() {
 Token dart_defaultToken = new Token(new TextAttribute("dart.dart_default"));
 setDefaultReturnToken(dart_defaultToken);
 Token dart_keywordToken = new Token(new TextAttribute("dart.dart_keyword"));
 
 // … // … somewhere in StyledTextArea StyledTextNode s = new StyledTextNode("public"); s.getStyleClass().setAll("dart","dart_keyword"); // … somewhere in StyledTextArea .styled-text-area .dart.dart_keyword { -styled-text-color: rgb(127, 0, 85); -fx-font-weight: bold; } .styled-text-area .dart.dart_keyword { -styled-text-color: -source-editor-keyword; -fx-font-weight: bold; }
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Live Demo (Lexicalhighlighting)
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 4 Architecture
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 4 Architecture Java VM
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 4 Architecture Java VM OSGi
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 4 Architecture Java VM OSGi Eclipse 4 Application Platform (Core)
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 4 Architecture Java VM OSGi Eclipse 4 Application Platform (Core) Eclipse 4 SWT Rendering SWT/JFace
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 4 Architecture Java VM OSGi Eclipse 4 Application Platform (Core) Eclipse 4 SWT Rendering SWT/JFace Application Code
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 4 Architecture Java VM OSGi Eclipse 4 Application Platform (Core) Application Code
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 4 Architecture Java VM OSGi Eclipse 4 Application Platform (Core) Application Code Eclipse 4 FX Rendering JavaFX 8
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 4 Architecture Java VM OSGi Eclipse 4 Application Platform (Core) Application Code Eclipse 4 FX Rendering JavaFX 8
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 4 Architecture Java VM OSGi Eclipse 4 Application Platform (Core) Application Code Eclipse 4 FX Rendering JavaFX 8 e(fx)clipse code framework
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Integration in Eclipse 4 ‣ The task: We need to create the correct IDocumentPartitioner and IPresentationReconciler for a given Source-File ‣ e(fx)clipse defines a TypeProviderService Service-API who is consulted to find a type for a given Input (=SourceFile) ‣ ALL TypeProviderService-Instances are registered in the OSGi-Service-Registry and consulted by the framework when it requires an instance of IDocumentPartitioner or IPresentationReconciler
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Integration into e4 ‣ The TypeProviderService APIs
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Integration into e4 ‣ The TypeProviderService APIs /** * A service who provides a type based upon a selector value * * @param <S> * the selector value type * @param <T> * the type * @since 2.1 */ public interface TypeProviderService<S, T> extends Predicate<S> { @Override boolean test(S t); public Class<? extends T> getType(S s); } interface InputDependentTypeProviderService<T> extends TypeProviderService<Input<?>, T> { } interface DocumentPartitionerTypeProvider extends InputDependentTypeProviderService<IDocumentPartitioner> { }
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Integration in e4
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Integration in e4 package org.eclipse.fx.code.editor.fx; /** * Component setting up a JavaFX text editor */ @SuppressWarnings("restriction") public class TextEditor { @Inject public void setPartitioner(IDocumentPartitioner partitioner) { } }
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Integration in e4 package org.eclipse.fx.code.editor.fx; /** * Component setting up a JavaFX text editor */ @SuppressWarnings("restriction") public class TextEditor { @Inject public void setPartitioner(IDocumentPartitioner partitioner) { } } ContextFunction IEclipseContext#get("org.eclipse.jface.text.IDocumentPartitioner")
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Integration in e4 package org.eclipse.fx.code.editor.fx; /** * Component setting up a JavaFX text editor */ @SuppressWarnings("restriction") public class TextEditor { @Inject public void setPartitioner(IDocumentPartitioner partitioner) { } } DocumentPartitionerTypeProvider test(NIOSourceFile("sample.dart")) ContextFunction IEclipseContext#get("org.eclipse.jface.text.IDocumentPartitioner")
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Integration in e4
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Integration in e4 @Component
 public class DartDocumentPartitionerTypeProvider implements DocumentPartitionerTypeProvider {
 
 public Class<? extends IDocumentPartitioner> getType(Input<?> s) {
 return DartPartitioner.class;
 }
 
 public boolean test(Input<?> t) {
 return (t instanceof URIProvider) && ((URIProvider)t).getURI().lastSegment().endsWith(".dart");
 }
 }

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Integration in e4 @Component
 public class DartDocumentPartitionerTypeProvider implements DocumentPartitionerTypeProvider {
 
 public Class<? extends IDocumentPartitioner> getType(Input<?> s) {
 return DartPartitioner.class;
 }
 
 public boolean test(Input<?> t) {
 return (t instanceof URIProvider) && ((URIProvider)t).getURI().lastSegment().endsWith(".dart");
 }
 }
 @Component
 public class DartPresentationReconcilerTypeProvider implements PresentationReconcilerTypeProvider {
 
 public Class<? extends PresentationReconciler> getType(Input<?> s) {
 return DartPresentationReconciler.class;
 }
 
 public boolean test(Input<?> t) {
 return (t instanceof URIProvider) && ((URIProvider)t).getURI().lastSegment().endsWith(".dart");
 }
 }
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Autocomplete ‣ There’s a trend of having headless applications providing things like autocomplete, error reporting, … ‣ Dart: DartAnalysis Server ‣ Typescript: LanguageService in tsserver ‣ Java: ‣ Eclipse Flux, Eclipse Che (Cloudbased) ‣ CodeSurf: internal research project
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 ‣ Communication with DartAnalysisServer is via JSON on STDIN/STDOUT ‣ 2 Interaction Types: ‣ Requests with a direct response (client driven) ‣ Notification informing about things (server driven) Autocomplete for Dart
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Interact with Dart Server 1. Step
 Inform DartServer about the source dir { "id" : "default_1", "method" : "analysis.setAnalysisRoots" , "params" : { "included":["/Users/tomschindl/dart-samples/"], "excluded":[] } }
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Interact with Dart Server 2. Step
 Request autocompletion { "id" : "default_2", "method" : "completion.getSuggestions" , "params" : { "file":"/Users/tomschindl/dart-samples/test.dart", "offset":367 } }
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 { "event":"completion.results", "params":{ "id":"0", "replacementOffset":367, "replacementLength":0, "results": [ { "kind":"INVOCATION", "relevance":1000, "completion":"left", "selectionOffset":4, "selectionLength":0, "isDeprecated":false, "isPotential":false, "declaringType":"Rectangle", "element":{ "kind":"FIELD", "name":"left", "location":{ "file":"/Users/tomschindl/dart-samples/test.dart", "offset":24, "length":4, "startLine":2, "startColumn":7 }, "flags":0, "returnType":"num" },"returnType":"num" }, // Many more … "isLast":true } } Interact with Dart Server 3. Step
 Server asynchronously delivers completion results
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 ‣ Interaction with Java Code Interact with Dart Server
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 ‣ Interaction with Java Code Interact with Dart Server DartServerFactory serverFactory = Util.lookupService(DartServerFactory.class);
 DartServer server = serverFactory.getServer("server");

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 ‣ Interaction with Java Code Interact with Dart Server DartServerFactory serverFactory = Util.lookupService(DartServerFactory.class);
 DartServer server = serverFactory.getServer("server");
 ServiceAnalysis analysisService = server.getService(ServiceAnalysis.class);
 ServiceCompletion completionService = server.getService(ServiceCompletion.class);

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 ‣ Interaction with Java Code Interact with Dart Server DartServerFactory serverFactory = Util.lookupService(DartServerFactory.class);
 DartServer server = serverFactory.getServer("server");
 ServiceAnalysis analysisService = server.getService(ServiceAnalysis.class);
 ServiceCompletion completionService = server.getService(ServiceCompletion.class);
 analysisService.setAnalysisRoots(new String[] {"/Users/tomschindl/dart-samples/"}, new String[0], null);
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 ‣ Interaction with Java Code Interact with Dart Server DartServerFactory serverFactory = Util.lookupService(DartServerFactory.class);
 DartServer server = serverFactory.getServer("server");
 ServiceAnalysis analysisService = server.getService(ServiceAnalysis.class);
 ServiceCompletion completionService = server.getService(ServiceCompletion.class);
 analysisService.setAnalysisRoots(new String[] {"/Users/tomschindl/dart-samples/"}, new String[0], null); 
 Registration proposalRegistration = completionService.results(this::handleHandleResults);
 completionService.getSuggestions("/Users/tomschindl/dart-samples/test.dart", 367);
 
 private static void handleHandleResults(CompletionResultsNotification notification) {
 Stream.of(notification.getResults()).forEach( c -> System.err.println(c.getCompletion()));
 }
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Code Editor Autocomplete
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Code Editor Autocomplete ‣ Autocomplete is implemented by a service of type org.eclipse.fx.code.editor.fx.services.ProposalComputer
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Code Editor Autocomplete ‣ Autocomplete is implemented by a service of type org.eclipse.fx.code.editor.fx.services.ProposalComputer ‣ and registered in the OSGi-Service registry through org.eclipse.fx.code.editor.fx.services.ProposalComputerTyp eProvider
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Code Editor Autocomplete ‣ Autocomplete is implemented by a service of type org.eclipse.fx.code.editor.fx.services.ProposalComputer ‣ and registered in the OSGi-Service registry through org.eclipse.fx.code.editor.fx.services.ProposalComputerTyp eProvider public class DartProposalComputer implements ProposalComputer { //… @Override public Future<List<ICompletionProposal>> compute(ProposalContext context) { URIProvider p = (URIProvider) context.input; Path file = Paths.get(java.net.URI.create(p.getURI().toString())).toAbsolutePath(); CompletionGetSuggestionsResult result = completionService.getSuggestions(file.toString(), context.location); requestId = result.getId(); future = new CompletableFuture<>(); return future; } }
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Live Demo (Autocomplete)
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 ‣Syntax Highlighting ‣Autocomplete ‣Error Reporting
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Error Markers ‣ DartServer provides the possibility to ‣ subscribe to error notifications ‣ fetch the current list of errors
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Error Markers ‣ DartServer provides the possibility to ‣ subscribe to error notifications ‣ fetch the current list of errors ServiceAnalysis service = server.getService(ServiceAnalysis.class); subscription = service.errors(this::accept); CompletableFuture.supplyAsync( () -> service.getErrors(file.toString())).thenAccept(this::accept);
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Code Editor Markers ‣ Code editor consults to services for error support: ‣ org.eclipse.jface.text.source.IAnnotationModel: Collects all errors and stores them for later useage ‣ org.eclipse.jface.text.source.AnnotationPresenter: Presents the errors in the TextEditor (eg as markers in the line ruler) ‣ services are contributed through org.eclipse.fx.code.editor.services.AnnotationModelTypePr ovider and org.eclipse.fx.code.editor.fx.services.AnnotationPresente rTypeProvider
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Live Demo (Error Marker)
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Language Support ‣ Syntaxhighlighting: ‣ Opensource: asciidoc, ceylon, dart, go, groovy, java, js, kotlin, lua, php, python, rust, swift, xml ‣ Internal research: Typescript ‣ Autocomplete: ‣ Opensource: Dart ‣ Internal research: Java, JavaScript, Typescript ‣ Outline: ‣ Opensource: Dart ‣ Internal research: JavaScript, Java, Typescript

Java fx smart code econ

  • 1.
    Smart Code editorswith JavaFX (and e4) Tom Schindl <tom.schindl@bestsolution.at> Twitter: @tomsontom Blog: http://tomsondev.bestsolution.at Website: http://www.bestsolution.at
  • 2.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 About Me ‣ CTO BestSolution.at Systemhaus GmbH ‣ Eclipse Committer ‣ e4 ‣ Platform ‣ EMF ‣ Project lead ‣ e(fx)clipse ‣ Twitter: @tomsontom ‣ Blog: tomsondev.bestsolution.at ‣ Cooperate: http://bestsolution.at
  • 3.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Today
  • 4.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Today ‣ Current situation ‣ Eclipse 4 Application Platform does not support editors ‣ Eclipse IDE / Eclipse 3.x RCP is still required to get an editor framework
  • 5.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Today ‣ Current situation ‣ Eclipse 4 Application Platform does not support editors ‣ Eclipse IDE / Eclipse 3.x RCP is still required to get an editor framework ‣ Future situation ‣ Eclipse 4 should support editors natively ‣ Loosely coupled components / services who work in Eclipse4, plain Java, jigsaw world
  • 6.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 3.x Codeeditors ‣ Should we directly port the 3.x code-editor stuff to Eclipse 4?
  • 7.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 3.x Codeeditors ‣ Should we directly port the 3.x code-editor stuff to Eclipse 4? EditorPart
  • 8.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 3.x Codeeditors ‣ Should we directly port the 3.x code-editor stuff to Eclipse 4? EditorPart AbstractTextEditor
  • 9.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 3.x Codeeditors ‣ Should we directly port the 3.x code-editor stuff to Eclipse 4? EditorPart AbstractTextEditor JavaEditor DartEditor …Editor
  • 10.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Codeeditors the e4 way ‣ Editors in a DI/Service env
  • 11.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Syntax-Highlighting Codeeditors the e4 way ‣ Editors in a DI/Service env
  • 12.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Syntax-Highlighting Error Marker Codeeditors the e4 way ‣ Editors in a DI/Service env
  • 13.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Syntax-Highlighting Documentation Info Error Marker Codeeditors the e4 way ‣ Editors in a DI/Service env
  • 14.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Syntax-Highlighting Autocomplete Documentation Info Error Marker Codeeditors the e4 way ‣ Editors in a DI/Service env
  • 15.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 IEditorInput replacement ‣ Basic API is named Input<O>
  • 16.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 IEditorInput replacement ‣ Basic API is named Input<O> public interface Input<O> { public void dispose(); public O getData(); public void setData(O data); public void persist(); }
  • 17.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 IEditorInput replacement ‣ Basic API is named Input<O> public interface Input<O> { public void dispose(); public O getData(); public void setData(O data); public void persist(); } Input<O>
  • 18.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 IEditorInput replacement ‣ Basic API is named Input<O> public interface Input<O> { public void dispose(); public O getData(); public void setData(O data); public void persist(); } Input<O> StringInput<String>
  • 19.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 IEditorInput replacement ‣ Basic API is named Input<O> public interface Input<O> { public void dispose(); public O getData(); public void setData(O data); public void persist(); } Input<O> StringInput<String> SourceFileInput
  • 20.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 IEditorInput replacement ‣ Basic API is named Input<O> public interface Input<O> { public void dispose(); public O getData(); public void setData(O data); public void persist(); } Input<O> StringInput<String> SourceFileInput NIOSourceFile EFSSourceFile
  • 21.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Text Parsing/Highlighting
  • 22.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Text Parsing/Highlighting ‣ Stay with Eclipse Text!
  • 23.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Text Parsing/Highlighting ‣ Stay with Eclipse Text! ‣ many parts are UI-Toolkit agnostic
  • 24.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Text Parsing/Highlighting ‣ Stay with Eclipse Text! ‣ many parts are UI-Toolkit agnostic ‣ Eclipse text does not require OSGi / 3.x APIs
  • 25.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Text Parsing/Highlighting ‣ Stay with Eclipse Text! ‣ many parts are UI-Toolkit agnostic ‣ Eclipse text does not require OSGi / 3.x APIs ‣ It is fast
  • 26.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Text Parsing/Highlighting ‣ Stay with Eclipse Text! ‣ many parts are UI-Toolkit agnostic ‣ Eclipse text does not require OSGi / 3.x APIs ‣ It is fast ‣ It does its job
  • 27.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Text Parsing/Highlighting ‣ Stay with Eclipse Text! ‣ many parts are UI-Toolkit agnostic ‣ Eclipse text does not require OSGi / 3.x APIs ‣ It is fast ‣ It does its job ‣ It is insanely fast
  • 28.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse Text Performance ‣ In JavaFX world there are 2 opensource controls for StyledTextArea (from e(fx)clipse), RichTextArea on github ‣ Both Frameworks have a pluggable Parser Infrastructure and provide default/sample parsers
  • 29.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse Text Performance StyleText (Eclipse Text) RichText (regex) ‣ In JavaFX world there are 2 opensource controls for StyledTextArea (from e(fx)clipse), RichTextArea on github ‣ Both Frameworks have a pluggable Parser Infrastructure and provide default/sample parsers
  • 30.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse Text Performance StyleText (Eclipse Text) RichText (regex) init - 10 000 Loc 327ms 400ms ‣ In JavaFX world there are 2 opensource controls for StyledTextArea (from e(fx)clipse), RichTextArea on github ‣ Both Frameworks have a pluggable Parser Infrastructure and provide default/sample parsers
  • 31.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse Text Performance StyleText (Eclipse Text) RichText (regex) init - 10 000 Loc 327ms 400ms init - 150 000 Loc 1100ms 3300ms ‣ In JavaFX world there are 2 opensource controls for StyledTextArea (from e(fx)clipse), RichTextArea on github ‣ Both Frameworks have a pluggable Parser Infrastructure and provide default/sample parsers
  • 32.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse Text Performance StyleText (Eclipse Text) RichText (regex) init - 10 000 Loc 327ms 400ms init - 150 000 Loc 1100ms 3300ms change - 10 000 Loc 30ms 110ms (*) ‣ In JavaFX world there are 2 opensource controls for StyledTextArea (from e(fx)clipse), RichTextArea on github ‣ Both Frameworks have a pluggable Parser Infrastructure and provide default/sample parsers
  • 33.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse Text Performance StyleText (Eclipse Text) RichText (regex) init - 10 000 Loc 327ms 400ms init - 150 000 Loc 1100ms 3300ms change - 10 000 Loc 30ms 110ms (*) change - 150 000 Loc 50ms 1800ms (*) ‣ In JavaFX world there are 2 opensource controls for StyledTextArea (from e(fx)clipse), RichTextArea on github ‣ Both Frameworks have a pluggable Parser Infrastructure and provide default/sample parsers
  • 34.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse Text Performance * Potential Bug: numbers might be devided by 2 StyleText (Eclipse Text) RichText (regex) init - 10 000 Loc 327ms 400ms init - 150 000 Loc 1100ms 3300ms change - 10 000 Loc 30ms 110ms (*) change - 150 000 Loc 50ms 1800ms (*) ‣ In JavaFX world there are 2 opensource controls for StyledTextArea (from e(fx)clipse), RichTextArea on github ‣ Both Frameworks have a pluggable Parser Infrastructure and provide default/sample parsers
  • 35.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse Text in a nutshell ‣ Two step process
  • 36.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse Text in a nutshell ‣ Two step process ‣ Step 1: Partitioning done by the org.eclipse.jface.text.IDocumentPartitioner
  • 37.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse Text in a nutshell ‣ Two step process ‣ Step 1: Partitioning done by the org.eclipse.jface.text.IDocumentPartitioner ‣ Step 2: Tokenizing done by the org.eclipse.jface.text.presentation.IPresentationReconc iler
  • 38.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning /** * This is a sample class */ class Sample { //Some information public void test() { /* * Some more information */ var s = "Hello World" ; print(s); } }
  • 39.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning /** * This is a sample class */ class Sample { //Some information public void test() { /* * Some more information */ var s = "Hello World" ; print(s); } } __dart_dartdoc
  • 40.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning /** * This is a sample class */ class Sample { //Some information public void test() { /* * Some more information */ var s = "Hello World" ; print(s); } } __dart_dartdoc __dart_sl_comment
  • 41.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning /** * This is a sample class */ class Sample { //Some information public void test() { /* * Some more information */ var s = "Hello World" ; print(s); } } __dart_dartdoc __dart_sl_comment __dart_ml_comment
  • 42.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning /** * This is a sample class */ class Sample { //Some information public void test() { /* * Some more information */ var s = "Hello World" ; print(s); } } __dart_dartdoc __dart_sl_comment __dart_ml_comment __dart_string
  • 43.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning /** * This is a sample class */ class Sample { //Some information public void test() { /* * Some more information */ var s = "Hello World" ; print(s); } } __dart_dartdoc __dart_sl_comment __dart_ml_comment __dart_string __dftl_partitioning
  • 44.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning Rules
  • 45.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning Rules Start End MultiLine
  • 46.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning Rules Start End MultiLine dartdoc /** */ !
  • 47.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning Rules Start End MultiLine dartdoc /** */ ! comment single // "
  • 48.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning Rules Start End MultiLine dartdoc /** */ ! comment single // " comment multi /* */ !
  • 49.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning Rules Start End MultiLine dartdoc /** */ ! comment single // " comment multi /* */ ! string " " "
  • 50.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Partitioning Rules Start End MultiLine dartdoc /** */ ! comment single // " comment multi /* */ ! string " " " character ' ' "
  • 51.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 ‣ Base interface org.eclipse.jface.text.rules.IRule ‣ 2 Basic implementations ‣ SingleLineRule ‣ MultiLineRule Rules in Eclipse Text
  • 52.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 ‣ Base interface org.eclipse.jface.text.rules.IRule ‣ 2 Basic implementations ‣ SingleLineRule ‣ MultiLineRule Rules in Eclipse Text new SingleLineRule("//", null, new Token("__dart_sl_comment")); new MultiLineRule("/**", "*/", new Token("__dart_dartdoc");
  • 53.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 ‣ Eclipse Text provides a default implementation for the IDocumentParitioner named FastPartitioner ‣ FastPartitioner delegates the real partitioning to an IPartitionTokenScanner ‣ Eclipse Text provides a default implementation for IPartitionScanner named RuleBasedPartitionScanner ‣ RuleBasedPartitionScanner use IRule definitions to detect partitions From Rules to Partitioner
  • 54.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 From Rules to Partitioner
  • 55.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 From Rules to Partitioner public class DartPartitionScanner extends RuleBasedPartitionScanner {
 IPredicateRule[] pr = new org.eclipse.jface.text.rules.IPredicateRule[6];
 pr[0] = new SingleLineRule("//", null, new Token("__dart_sl_comment");
 // … 
 }

  • 56.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 From Rules to Partitioner public class DartPartitionScanner extends RuleBasedPartitionScanner {
 IPredicateRule[] pr = new org.eclipse.jface.text.rules.IPredicateRule[6];
 pr[0] = new SingleLineRule("//", null, new Token("__dart_sl_comment");
 // … 
 }
 public class DartPartitioner extends FastPartitioner {
 public DartPartitioner() {
 super(new DartPartitionScanner(), new String[] {
 "__dart_singlelinedoc_comment"
 ,"__dart_dartdoc"
 ,"__dart_sl_comment"
 ,"__dart_multiline_comment"
 ,"__dart_string"
 });
 }
  • 57.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 From Rules to Partitioner public class DartPartitionScanner extends RuleBasedPartitionScanner {
 IPredicateRule[] pr = new org.eclipse.jface.text.rules.IPredicateRule[6];
 pr[0] = new SingleLineRule("//", null, new Token("__dart_sl_comment");
 // … 
 }
 public class DartPartitioner extends FastPartitioner {
 public DartPartitioner() {
 super(new DartPartitionScanner(), new String[] {
 "__dart_singlelinedoc_comment"
 ,"__dart_dartdoc"
 ,"__dart_sl_comment"
 ,"__dart_multiline_comment"
 ,"__dart_string"
 });
 } }
  • 58.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Express Partitions in a DSL ‣ Instead of writing a bunch of Java configuration code we could define a DSL and generate the code
  • 59.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Express Partitions in a DSL ‣ Instead of writing a bunch of Java configuration code we could define a DSL and generate the code package langs dart { partitioning { partition __dftl_partition_content_type partition __dart_singlelinedoc_comment partition __dart_dartdoc partition __dart_sl_comment partition __dart_multiline_comment partition __dart_string rule { single_line __dart_string "'" => "'" escaped by "" single_line __dart_string '"' => '"' escaped by "" single_line __dart_singlelinedoc_comment '///' single_line __dart_sl_comment '//' multi_line __dart_dartdoc '/**' => '*/' multi_line __dart_multiline_comment '/*' => '*/' } } … }
  • 60.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Tokenizing a Partition /** * This is a sample class */ class Sample { public void test(String s) { print(s); } }
  • 61.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Tokenizing a Partition /** * This is a sample class */ class Sample { public void test(String s) { print(s); } } tk(dart_doc,0,25)
  • 62.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Tokenizing a Partition /** * This is a sample class */ class Sample { public void test(String s) { print(s); } } tk(dart_doc,0,25)
  • 63.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Tokenizing a Partition /** * This is a sample class */ class Sample { public void test(String s) { print(s); } } tk(dart_doc,0,25) tk(dart_keyword,27,31) tk(dart_keyword,41,45)
  • 64.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Tokenizing a Partition /** * This is a sample class */ class Sample { public void test(String s) { print(s); } } tk(dart_doc,0,25) tk(dart_keyword,27,31) tk(dart_keyword,41,45) tk(dart_default,28,34)
  • 65.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 ‣ Uses same IRules APIs as for partitioning ‣ Prebuilt rules useable for Tokenizing ‣ CombinedWordRule: Used for keywords ‣ CharacterRule: Used for single chars eg braces, operators ‣ SingleLineRule, MultiLineRule, PatternRule, … Tokenizing Rules
  • 66.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 From Rules to Reconciler ‣ Eclipse Text provides a default implementation for IPresentationReconciler named PresentationReconciler ‣ PresentationReconciler requires an IPresentationDamager and IPresentationRepairer / Partition ‣ Eclipse Text provides a default implementation for IPresentationDamager & IPresentationRepairer named DefaultDamagerRepairer ‣ DefaultDamagerRepairer uses an ITokenScanner ‣ Eclipse Text provide a default implementation ITokenScanner named RuleBasedScanner who uses IRule
  • 67.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 From Rules to Reconciler
  • 68.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 From Rules to Reconciler public class DartDefPartitionScanner extends RuleBasedScanner {
 public DartDefPartitionScanner() {
 Token dart_defaultToken = new Token(new TextAttribute("dart.dart_default"));
 setDefaultReturnToken(dart_defaultToken);
 Token dart_keywordToken = new Token(new TextAttribute("dart.dart_keyword"));
 
 JavaLikeWordDetector wordDetector= new JavaLikeWordDetector();
 CombinedWordRule combinedWordRule= new CombinedWordRule(wordDetector, dart_defaultToken);
 CombinedWordRule.WordMatcher dart_keywordWordRule = new CombinedWordRule.WordMatcher();
 dart_keywordWordRule.addWord("break", dart_keywordToken);
 // … 
 combinedWordRule.addWordMatcher(dart_keywordWordRule);
 } 
 }

  • 69.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 From Rules to Reconciler public class DartDefPartitionScanner extends RuleBasedScanner {
 public DartDefPartitionScanner() {
 Token dart_defaultToken = new Token(new TextAttribute("dart.dart_default"));
 setDefaultReturnToken(dart_defaultToken);
 Token dart_keywordToken = new Token(new TextAttribute("dart.dart_keyword"));
 
 JavaLikeWordDetector wordDetector= new JavaLikeWordDetector();
 CombinedWordRule combinedWordRule= new CombinedWordRule(wordDetector, dart_defaultToken);
 CombinedWordRule.WordMatcher dart_keywordWordRule = new CombinedWordRule.WordMatcher();
 dart_keywordWordRule.addWord("break", dart_keywordToken);
 // … 
 combinedWordRule.addWordMatcher(dart_keywordWordRule);
 } 
 }
 public class DartPresentationReconciler extends PresentationReconciler {
 public DartPresentationReconciler() {
 DefaultDamagerRepairer defDamageRepairer = new DefaultDamagerRepairer(new DartDefPartitionScanner());
 setDamager(defDamageRepairer, "__dftl_partition_content_type");
 setRepairer(defDamageRepairer, "__dftl_partition_content_type");
 
 DefaultDamagerRepairer docDamageRepairer = new DefaultDamagerRepairer(new DartDocPartitionScanner());
 setDamager(docDamageRepairer, "__dart_dartdoc");
 setRepairer(docDamageRepairer, "__dart_dartdoc");
 // …
 }
 }
  • 70.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Express Tokens in the DSL
  • 71.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Express Tokens in the DSL package langs
 
 dart {
 partitioning {
 partition __dftl_partition_content_type
 partition __dart_dartdoc
 // …
 }
  • 72.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Express Tokens in the DSL package langs
 
 dart {
 partitioning {
 partition __dftl_partition_content_type
 partition __dart_dartdoc
 // …
 } lexical_highlighting {
 rule __dftl_partition_content_type {
 default dart_default
 dart_keyword {
 keywords [ "break", "case", /* … */ ]
 }
 }
 rule __dart_dartdoc {
 default dart_doc
 dart_doc_reference {
 single_line "[" => "]"
 } 
 }
 }
 }
  • 73.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Visual representation
  • 74.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Visual representation public class DartDefPartitionScanner extends RuleBasedScanner {
 public DartDefPartitionScanner() {
 Token dart_defaultToken = new Token(new TextAttribute("dart.dart_default"));
 setDefaultReturnToken(dart_defaultToken);
 Token dart_keywordToken = new Token(new TextAttribute("dart.dart_keyword"));
 
 // …
  • 75.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Visual representation public class DartDefPartitionScanner extends RuleBasedScanner {
 public DartDefPartitionScanner() {
 Token dart_defaultToken = new Token(new TextAttribute("dart.dart_default"));
 setDefaultReturnToken(dart_defaultToken);
 Token dart_keywordToken = new Token(new TextAttribute("dart.dart_keyword"));
 
 // … // … somewhere in StyledTextArea StyledTextNode s = new StyledTextNode("public"); s.getStyleClass().setAll("dart","dart_keyword"); // … somewhere in StyledTextArea
  • 76.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Visual representation public class DartDefPartitionScanner extends RuleBasedScanner {
 public DartDefPartitionScanner() {
 Token dart_defaultToken = new Token(new TextAttribute("dart.dart_default"));
 setDefaultReturnToken(dart_defaultToken);
 Token dart_keywordToken = new Token(new TextAttribute("dart.dart_keyword"));
 
 // … // … somewhere in StyledTextArea StyledTextNode s = new StyledTextNode("public"); s.getStyleClass().setAll("dart","dart_keyword"); // … somewhere in StyledTextArea .styled-text-area .dart.dart_keyword { -styled-text-color: rgb(127, 0, 85); -fx-font-weight: bold; }
  • 77.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Visual representation public class DartDefPartitionScanner extends RuleBasedScanner {
 public DartDefPartitionScanner() {
 Token dart_defaultToken = new Token(new TextAttribute("dart.dart_default"));
 setDefaultReturnToken(dart_defaultToken);
 Token dart_keywordToken = new Token(new TextAttribute("dart.dart_keyword"));
 
 // … // … somewhere in StyledTextArea StyledTextNode s = new StyledTextNode("public"); s.getStyleClass().setAll("dart","dart_keyword"); // … somewhere in StyledTextArea .styled-text-area .dart.dart_keyword { -styled-text-color: rgb(127, 0, 85); -fx-font-weight: bold; } .styled-text-area .dart.dart_keyword { -styled-text-color: -source-editor-keyword; -fx-font-weight: bold; }
  • 78.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Live Demo (Lexicalhighlighting)
  • 79.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 4 Architecture
  • 80.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 4 Architecture Java VM
  • 81.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 4 Architecture Java VM OSGi
  • 82.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 4 Architecture Java VM OSGi Eclipse 4 Application Platform (Core)
  • 83.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 4 Architecture Java VM OSGi Eclipse 4 Application Platform (Core) Eclipse 4 SWT Rendering SWT/JFace
  • 84.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 4 Architecture Java VM OSGi Eclipse 4 Application Platform (Core) Eclipse 4 SWT Rendering SWT/JFace Application Code
  • 85.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 4 Architecture Java VM OSGi Eclipse 4 Application Platform (Core) Application Code
  • 86.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 4 Architecture Java VM OSGi Eclipse 4 Application Platform (Core) Application Code Eclipse 4 FX Rendering JavaFX 8
  • 87.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 4 Architecture Java VM OSGi Eclipse 4 Application Platform (Core) Application Code Eclipse 4 FX Rendering JavaFX 8
  • 88.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Eclipse 4 Architecture Java VM OSGi Eclipse 4 Application Platform (Core) Application Code Eclipse 4 FX Rendering JavaFX 8 e(fx)clipse code framework
  • 89.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Integration in Eclipse 4 ‣ The task: We need to create the correct IDocumentPartitioner and IPresentationReconciler for a given Source-File ‣ e(fx)clipse defines a TypeProviderService Service-API who is consulted to find a type for a given Input (=SourceFile) ‣ ALL TypeProviderService-Instances are registered in the OSGi-Service-Registry and consulted by the framework when it requires an instance of IDocumentPartitioner or IPresentationReconciler
  • 90.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Integration into e4 ‣ The TypeProviderService APIs
  • 91.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Integration into e4 ‣ The TypeProviderService APIs /** * A service who provides a type based upon a selector value * * @param <S> * the selector value type * @param <T> * the type * @since 2.1 */ public interface TypeProviderService<S, T> extends Predicate<S> { @Override boolean test(S t); public Class<? extends T> getType(S s); } interface InputDependentTypeProviderService<T> extends TypeProviderService<Input<?>, T> { } interface DocumentPartitionerTypeProvider extends InputDependentTypeProviderService<IDocumentPartitioner> { }
  • 92.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Integration in e4
  • 93.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Integration in e4 package org.eclipse.fx.code.editor.fx; /** * Component setting up a JavaFX text editor */ @SuppressWarnings("restriction") public class TextEditor { @Inject public void setPartitioner(IDocumentPartitioner partitioner) { } }
  • 94.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Integration in e4 package org.eclipse.fx.code.editor.fx; /** * Component setting up a JavaFX text editor */ @SuppressWarnings("restriction") public class TextEditor { @Inject public void setPartitioner(IDocumentPartitioner partitioner) { } } ContextFunction IEclipseContext#get("org.eclipse.jface.text.IDocumentPartitioner")
  • 95.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Integration in e4 package org.eclipse.fx.code.editor.fx; /** * Component setting up a JavaFX text editor */ @SuppressWarnings("restriction") public class TextEditor { @Inject public void setPartitioner(IDocumentPartitioner partitioner) { } } DocumentPartitionerTypeProvider test(NIOSourceFile("sample.dart")) ContextFunction IEclipseContext#get("org.eclipse.jface.text.IDocumentPartitioner")
  • 96.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Integration in e4
  • 97.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Integration in e4 @Component
 public class DartDocumentPartitionerTypeProvider implements DocumentPartitionerTypeProvider {
 
 public Class<? extends IDocumentPartitioner> getType(Input<?> s) {
 return DartPartitioner.class;
 }
 
 public boolean test(Input<?> t) {
 return (t instanceof URIProvider) && ((URIProvider)t).getURI().lastSegment().endsWith(".dart");
 }
 }

  • 98.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Integration in e4 @Component
 public class DartDocumentPartitionerTypeProvider implements DocumentPartitionerTypeProvider {
 
 public Class<? extends IDocumentPartitioner> getType(Input<?> s) {
 return DartPartitioner.class;
 }
 
 public boolean test(Input<?> t) {
 return (t instanceof URIProvider) && ((URIProvider)t).getURI().lastSegment().endsWith(".dart");
 }
 }
 @Component
 public class DartPresentationReconcilerTypeProvider implements PresentationReconcilerTypeProvider {
 
 public Class<? extends PresentationReconciler> getType(Input<?> s) {
 return DartPresentationReconciler.class;
 }
 
 public boolean test(Input<?> t) {
 return (t instanceof URIProvider) && ((URIProvider)t).getURI().lastSegment().endsWith(".dart");
 }
 }
  • 99.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Autocomplete ‣ There’s a trend of having headless applications providing things like autocomplete, error reporting, … ‣ Dart: DartAnalysis Server ‣ Typescript: LanguageService in tsserver ‣ Java: ‣ Eclipse Flux, Eclipse Che (Cloudbased) ‣ CodeSurf: internal research project
  • 100.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 ‣ Communication with DartAnalysisServer is via JSON on STDIN/STDOUT ‣ 2 Interaction Types: ‣ Requests with a direct response (client driven) ‣ Notification informing about things (server driven) Autocomplete for Dart
  • 101.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Interact with Dart Server 1. Step
 Inform DartServer about the source dir { "id" : "default_1", "method" : "analysis.setAnalysisRoots" , "params" : { "included":["/Users/tomschindl/dart-samples/"], "excluded":[] } }
  • 102.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Interact with Dart Server 2. Step
 Request autocompletion { "id" : "default_2", "method" : "completion.getSuggestions" , "params" : { "file":"/Users/tomschindl/dart-samples/test.dart", "offset":367 } }
  • 103.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 { "event":"completion.results", "params":{ "id":"0", "replacementOffset":367, "replacementLength":0, "results": [ { "kind":"INVOCATION", "relevance":1000, "completion":"left", "selectionOffset":4, "selectionLength":0, "isDeprecated":false, "isPotential":false, "declaringType":"Rectangle", "element":{ "kind":"FIELD", "name":"left", "location":{ "file":"/Users/tomschindl/dart-samples/test.dart", "offset":24, "length":4, "startLine":2, "startColumn":7 }, "flags":0, "returnType":"num" },"returnType":"num" }, // Many more … "isLast":true } } Interact with Dart Server 3. Step
 Server asynchronously delivers completion results
  • 104.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 ‣ Interaction with Java Code Interact with Dart Server
  • 105.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 ‣ Interaction with Java Code Interact with Dart Server DartServerFactory serverFactory = Util.lookupService(DartServerFactory.class);
 DartServer server = serverFactory.getServer("server");

  • 106.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 ‣ Interaction with Java Code Interact with Dart Server DartServerFactory serverFactory = Util.lookupService(DartServerFactory.class);
 DartServer server = serverFactory.getServer("server");
 ServiceAnalysis analysisService = server.getService(ServiceAnalysis.class);
 ServiceCompletion completionService = server.getService(ServiceCompletion.class);

  • 107.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 ‣ Interaction with Java Code Interact with Dart Server DartServerFactory serverFactory = Util.lookupService(DartServerFactory.class);
 DartServer server = serverFactory.getServer("server");
 ServiceAnalysis analysisService = server.getService(ServiceAnalysis.class);
 ServiceCompletion completionService = server.getService(ServiceCompletion.class);
 analysisService.setAnalysisRoots(new String[] {"/Users/tomschindl/dart-samples/"}, new String[0], null);
  • 108.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 ‣ Interaction with Java Code Interact with Dart Server DartServerFactory serverFactory = Util.lookupService(DartServerFactory.class);
 DartServer server = serverFactory.getServer("server");
 ServiceAnalysis analysisService = server.getService(ServiceAnalysis.class);
 ServiceCompletion completionService = server.getService(ServiceCompletion.class);
 analysisService.setAnalysisRoots(new String[] {"/Users/tomschindl/dart-samples/"}, new String[0], null); 
 Registration proposalRegistration = completionService.results(this::handleHandleResults);
 completionService.getSuggestions("/Users/tomschindl/dart-samples/test.dart", 367);
 
 private static void handleHandleResults(CompletionResultsNotification notification) {
 Stream.of(notification.getResults()).forEach( c -> System.err.println(c.getCompletion()));
 }
  • 109.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Code Editor Autocomplete
  • 110.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Code Editor Autocomplete ‣ Autocomplete is implemented by a service of type org.eclipse.fx.code.editor.fx.services.ProposalComputer
  • 111.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Code Editor Autocomplete ‣ Autocomplete is implemented by a service of type org.eclipse.fx.code.editor.fx.services.ProposalComputer ‣ and registered in the OSGi-Service registry through org.eclipse.fx.code.editor.fx.services.ProposalComputerTyp eProvider
  • 112.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Code Editor Autocomplete ‣ Autocomplete is implemented by a service of type org.eclipse.fx.code.editor.fx.services.ProposalComputer ‣ and registered in the OSGi-Service registry through org.eclipse.fx.code.editor.fx.services.ProposalComputerTyp eProvider public class DartProposalComputer implements ProposalComputer { //… @Override public Future<List<ICompletionProposal>> compute(ProposalContext context) { URIProvider p = (URIProvider) context.input; Path file = Paths.get(java.net.URI.create(p.getURI().toString())).toAbsolutePath(); CompletionGetSuggestionsResult result = completionService.getSuggestions(file.toString(), context.location); requestId = result.getId(); future = new CompletableFuture<>(); return future; } }
  • 113.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Live Demo (Autocomplete)
  • 114.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 ‣Syntax Highlighting ‣Autocomplete ‣Error Reporting
  • 115.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Error Markers ‣ DartServer provides the possibility to ‣ subscribe to error notifications ‣ fetch the current list of errors
  • 116.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Error Markers ‣ DartServer provides the possibility to ‣ subscribe to error notifications ‣ fetch the current list of errors ServiceAnalysis service = server.getService(ServiceAnalysis.class); subscription = service.errors(this::accept); CompletableFuture.supplyAsync( () -> service.getErrors(file.toString())).thenAccept(this::accept);
  • 117.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Code Editor Markers ‣ Code editor consults to services for error support: ‣ org.eclipse.jface.text.source.IAnnotationModel: Collects all errors and stores them for later useage ‣ org.eclipse.jface.text.source.AnnotationPresenter: Presents the errors in the TextEditor (eg as markers in the line ruler) ‣ services are contributed through org.eclipse.fx.code.editor.services.AnnotationModelTypePr ovider and org.eclipse.fx.code.editor.fx.services.AnnotationPresente rTypeProvider
  • 118.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Live Demo (Error Marker)
  • 119.
    (c) BestSolution.at -Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0 Language Support ‣ Syntaxhighlighting: ‣ Opensource: asciidoc, ceylon, dart, go, groovy, java, js, kotlin, lua, php, python, rust, swift, xml ‣ Internal research: Typescript ‣ Autocomplete: ‣ Opensource: Dart ‣ Internal research: Java, JavaScript, Typescript ‣ Outline: ‣ Opensource: Dart ‣ Internal research: JavaScript, Java, Typescript