Smart Code editors with JavaFX (and e4) Tom Schindl - - PowerPoint PPT Presentation

smart code editors with javafx and e4
SMART_READER_LITE
LIVE PREVIEW

Smart Code editors with JavaFX (and e4) Tom Schindl - - PowerPoint PPT Presentation

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 About Me CTO BestSolution.at Systemhaus GmbH Eclipse


slide-1
SLIDE 1

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

slide-2
SLIDE 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
slide-3
SLIDE 3

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Today

slide-4
SLIDE 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

slide-5
SLIDE 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

slide-6
SLIDE 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?

slide-7
SLIDE 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

slide-8
SLIDE 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

slide-9
SLIDE 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

slide-10
SLIDE 10

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Codeeditors the e4 way

  • Editors in a DI/Service env
slide-11
SLIDE 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
slide-12
SLIDE 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
slide-13
SLIDE 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
slide-14
SLIDE 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
slide-15
SLIDE 15

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

IEditorInput replacement

  • Basic API is named Input<O>
slide-16
SLIDE 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(); }

slide-17
SLIDE 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>

slide-18
SLIDE 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>

slide-19
SLIDE 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

slide-20
SLIDE 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

slide-21
SLIDE 21

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Text Parsing/Highlighting

slide-22
SLIDE 22

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Text Parsing/Highlighting

  • Stay with Eclipse Text!
slide-23
SLIDE 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
slide-24
SLIDE 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
slide-25
SLIDE 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
slide-26
SLIDE 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
slide-27
SLIDE 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
slide-28
SLIDE 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

slide-29
SLIDE 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

slide-30
SLIDE 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

slide-31
SLIDE 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

slide-32
SLIDE 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

slide-33
SLIDE 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

slide-34
SLIDE 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

slide-35
SLIDE 35

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Eclipse Text in a nutshell

  • Two step process
slide-36
SLIDE 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
  • rg.eclipse.jface.text.IDocumentPartitioner
slide-37
SLIDE 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
  • rg.eclipse.jface.text.IDocumentPartitioner
  • Step 2: Tokenizing done by the
  • rg.eclipse.jface.text.presentation.IPresentationReconc

iler

slide-38
SLIDE 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); } }

slide-39
SLIDE 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

slide-40
SLIDE 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

slide-41
SLIDE 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

slide-42
SLIDE 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

slide-43
SLIDE 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

slide-44
SLIDE 44

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Partitioning Rules

slide-45
SLIDE 45

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Partitioning Rules

Start End MultiLine

slide-46
SLIDE 46

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Partitioning Rules

Start End MultiLine dartdoc /** */

slide-47
SLIDE 47

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Partitioning Rules

Start End MultiLine dartdoc /** */

  • comment single

//

slide-48
SLIDE 48

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Partitioning Rules

Start End MultiLine dartdoc /** */

  • comment single

//

  • comment multi

/* */

slide-49
SLIDE 49

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Partitioning Rules

Start End MultiLine dartdoc /** */

  • comment single

//

  • comment multi

/* */

  • string

" "

slide-50
SLIDE 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

' '

slide-51
SLIDE 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

slide-52
SLIDE 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");

slide-53
SLIDE 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

slide-54
SLIDE 54

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

From Rules to Partitioner

slide-55
SLIDE 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");
 // … 
 }


slide-56
SLIDE 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"
 });
 }

slide-57
SLIDE 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"
 });
 } }

slide-58
SLIDE 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

slide-59
SLIDE 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 '/*' => '*/' } } … }

slide-60
SLIDE 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); } }

slide-61
SLIDE 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)

slide-62
SLIDE 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)

slide-63
SLIDE 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)

slide-64
SLIDE 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)

slide-65
SLIDE 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,
  • perators
  • SingleLineRule, MultiLineRule, PatternRule, …

Tokenizing Rules

slide-66
SLIDE 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

slide-67
SLIDE 67

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

From Rules to Reconciler

slide-68
SLIDE 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);
 } 
 }


slide-69
SLIDE 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");
 // …
 }
 }

slide-70
SLIDE 70

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Express Tokens in the DSL

slide-71
SLIDE 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
 // …
 }

slide-72
SLIDE 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 "[" => "]"
 } 
 }
 }
 }

slide-73
SLIDE 73

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Visual representation

slide-74
SLIDE 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"));
 
 // …

slide-75
SLIDE 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

slide-76
SLIDE 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;

}

slide-77
SLIDE 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;

}

slide-78
SLIDE 78

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Live Demo (Lexicalhighlighting)

slide-79
SLIDE 79

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Eclipse 4 Architecture

slide-80
SLIDE 80

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Eclipse 4 Architecture

Java VM

slide-81
SLIDE 81

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Eclipse 4 Architecture

Java VM OSGi

slide-82
SLIDE 82

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Eclipse 4 Architecture

Java VM OSGi Eclipse 4 Application Platform (Core)

slide-83
SLIDE 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

slide-84
SLIDE 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

slide-85
SLIDE 85

(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 Application Code

slide-86
SLIDE 86

(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 Application Code Eclipse 4 FX Rendering JavaFX 8

slide-87
SLIDE 87

(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 Application Code Eclipse 4 FX Rendering JavaFX 8

slide-88
SLIDE 88

(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 Application Code Eclipse 4 FX Rendering JavaFX 8 e(fx)clipse code framework

slide-89
SLIDE 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

slide-90
SLIDE 90

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Integration into e4

  • The TypeProviderService APIs
slide-91
SLIDE 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> { }

slide-92
SLIDE 92

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Integration in e4

slide-93
SLIDE 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) { } }

slide-94
SLIDE 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")

slide-95
SLIDE 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")

slide-96
SLIDE 96

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Integration in e4

slide-97
SLIDE 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");
 }
 }


slide-98
SLIDE 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");
 }
 }

slide-99
SLIDE 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
slide-100
SLIDE 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

slide-101
SLIDE 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":[] } }

slide-102
SLIDE 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 } }

slide-103
SLIDE 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

slide-104
SLIDE 104

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

  • Interaction with Java Code

Interact with Dart Server

slide-105
SLIDE 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");


slide-106
SLIDE 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);


slide-107
SLIDE 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);

slide-108
SLIDE 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()));
 }

slide-109
SLIDE 109

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Code Editor Autocomplete

slide-110
SLIDE 110

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Code Editor Autocomplete

  • Autocomplete is implemented by a service of type
  • rg.eclipse.fx.code.editor.fx.services.ProposalComputer
slide-111
SLIDE 111

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Code Editor Autocomplete

  • Autocomplete is implemented by a service of type
  • rg.eclipse.fx.code.editor.fx.services.ProposalComputer
  • and registered in the OSGi-Service registry through
  • rg.eclipse.fx.code.editor.fx.services.ProposalComputerTyp

eProvider

slide-112
SLIDE 112

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Code Editor Autocomplete

  • Autocomplete is implemented by a service of type
  • rg.eclipse.fx.code.editor.fx.services.ProposalComputer
  • and registered in the OSGi-Service registry through
  • rg.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; } }

slide-113
SLIDE 113

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Live Demo (Autocomplete)

slide-114
SLIDE 114

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

  • Syntax Highlighting
  • Autocomplete
  • Error Reporting
slide-115
SLIDE 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
slide-116
SLIDE 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);

slide-117
SLIDE 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
  • rg.eclipse.fx.code.editor.services.AnnotationModelTypePr
  • vider and
  • rg.eclipse.fx.code.editor.fx.services.AnnotationPresente

rTypeProvider

slide-118
SLIDE 118

(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0

Live Demo (Error Marker)

slide-119
SLIDE 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