KEMBAR78
Java fx smart code econ | PDF
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