Xtending our VHDL Xtext formatter with the formatter2 API ir. - - PowerPoint PPT Presentation

xtending our vhdl xtext formatter with the formatter2 api
SMART_READER_LITE
LIVE PREVIEW

Xtending our VHDL Xtext formatter with the formatter2 API ir. - - PowerPoint PPT Presentation

EclipseCon France 2017-06-21 Xtending our VHDL Xtext formatter with the formatter2 API ir. Titouan Vervack redefine.digital.design: Helping you deal with complexity in VHDL and Verilog. EclipseCon France, Toulouse 2017-06-21 Xtending our VHDL


slide-1
SLIDE 1

redefine.digital.design: Helping you deal with complexity in VHDL and Verilog.

Xtending our VHDL Xtext formatter with the formatter2 API

  • ir. Titouan Vervack

EclipseCon France

2017-06-21

slide-2
SLIDE 2

redefine.digital.design: Helping you deal with complexity in VHDL and Verilog.

Xtending our VHDL Xtext formatter with the formatter2 API

  • ir. Titouan Vervack

EclipseCon France, Toulouse

2017-06-21

slide-3
SLIDE 3

Ghent

2

slide-4
SLIDE 4

What do we do? VHDL & SV IDE

3

slide-5
SLIDE 5

What do we do? Advanced analysis and linting

4

slide-6
SLIDE 6

What do we do? Visualisation

5

slide-7
SLIDE 7

What do we do? Visualisation

6

slide-8
SLIDE 8

What do we do? Eat cake

7

slide-9
SLIDE 9

What do we do? And cookies...

8

slide-10
SLIDE 10

What do we do? And occasionally… formatting

9

slide-11
SLIDE 11

What do we do? And occasionally… formatting

9

slide-12
SLIDE 12

Our formatter problems

10

slide-13
SLIDE 13

Our formatter problems

  • Big grammar

~1.2k LoC ○ ~200 rules

10

slide-14
SLIDE 14

Our formatter problems

  • Big grammar

~1.2k LoC ○ ~200 rules

  • Hard to fix bugs

10

slide-15
SLIDE 15

Our formatter problems

  • Big grammar

~1.2k LoC ○ ~200 rules

  • Hard to fix bugs
  • Near impossible to add new features

10

slide-16
SLIDE 16

Formatter 1.0 vs Formatter 2.0

11

Formatter 1.0 Formatter 2.0

  • No access to

○ Node model ○ AST ○ Text

  • => Specify everything purely on the grammar
  • => Lots of hacks
  • Access to

○ Node model ○ AST ○ Grammar

  • Can’t take context into account

○ Can’t adjust to the user

  • Context aware formatting

○ Conditional formatting ○ Table formatting

  • Not customizable
  • Very customizable
slide-17
SLIDE 17

Formatter 2.0 region example

variable _ foo _ : _ bit _ ; _-- bar\n

variable foo : bit; -- bar

= ISemanticRegion = IHiddenRegion

_

  • - bar

\n

= IHiddenRegionPart

12

https://de.slideshare.net/meysholdt/xtexts-new-formatter-api

slide-18
SLIDE 18

Formatting 2.0 usage example https://de.slideshare.net/meysholdt/xtexts-new-formatter-api

13

slide-19
SLIDE 19

Formatting 2.0 usage example https://de.slideshare.net/meysholdt/xtexts-new-formatter-api

class AwesomO4000 extends AbstractFormatter2 { } 13

slide-20
SLIDE 20

Formatting 2.0 usage example https://de.slideshare.net/meysholdt/xtexts-new-formatter-api

class AwesomO4000 extends AbstractFormatter2 { def dispatch void format(FunctionDecl fd, extension IFormattableDocument d) { } } 13

slide-21
SLIDE 21

Formatting 2.0 usage example https://de.slideshare.net/meysholdt/xtexts-new-formatter-api

class AwesomO4000 extends AbstractFormatter2 { def dispatch void format(FunctionDecl fd, extension IFormattableDocument d) { interior(fd.regionFor.keyword(“{”), fd.regionFor.keyword(“}”))[indent] } } 13

slide-22
SLIDE 22

Formatting 2.0 usage example https://de.slideshare.net/meysholdt/xtexts-new-formatter-api

class AwesomO4000 extends AbstractFormatter2 { def dispatch void format(FunctionDecl fd, extension IFormattableDocument d) { interior(fd.regionFor.keyword(“{”), fd.regionFor.keyword(“}”))[indent] fd.declarations.forEach[format] } } 13

slide-23
SLIDE 23

Formatting 2.0 usage example https://de.slideshare.net/meysholdt/xtexts-new-formatter-api

class AwesomO4000 extends AbstractFormatter2 { def dispatch void format(FunctionDecl fd, extension IFormattableDocument d) { interior(fd.regionFor.keyword(“{”), fd.regionFor.keyword(“}”))[indent] fd.declarations.forEach[format] fd.regionFor.keyword(“;”) } } 13

slide-24
SLIDE 24

Formatting 2.0 usage example https://de.slideshare.net/meysholdt/xtexts-new-formatter-api

class AwesomO4000 extends AbstractFormatter2 { def dispatch void format(FunctionDecl fd, extension IFormattableDocument d) { interior(fd.regionFor.keyword(“{”), fd.regionFor.keyword(“}”))[indent] fd.declarations.forEach[format] fd.regionFor.keyword(“;”) .prepend[noSpace highPriority] } } 13

slide-25
SLIDE 25

Formatting 2.0 usage example https://de.slideshare.net/meysholdt/xtexts-new-formatter-api

class AwesomO4000 extends AbstractFormatter2 { def dispatch void format(FunctionDecl fd, extension IFormattableDocument d) { interior(fd.regionFor.keyword(“{”), fd.regionFor.keyword(“}”))[indent] fd.declarations.forEach[format] fd.regionFor.keyword(“;”) .prepend[noSpace highPriority] .append[setNewlines(1, 1, 2)] } } 13

slide-26
SLIDE 26

Time for a plan

14

slide-27
SLIDE 27

Time for a plan 1. Make tests compatible

14

slide-28
SLIDE 28

Time for a plan 1. Make tests compatible 2. Start out easy: only indentation

14

slide-29
SLIDE 29

Time for a plan 1. Make tests compatible 2. Start out easy: only indentation 3. Fix tests one by one

14

slide-30
SLIDE 30

Time for a plan 1. Make tests compatible 2. Start out easy: only indentation 3. Fix tests one by one 4. Fix old bugs

14

slide-31
SLIDE 31

Time for a plan 1. Make tests compatible 2. Start out easy: only indentation 3. Fix tests one by one 4. Fix old bugs 5. Do not introduce new bugs

14

slide-32
SLIDE 32

Time for a plan 1. Make tests compatible 2. Start out easy: only indentation 3. Fix tests one by one 4. Fix old bugs 5. Do not introduce new bugs 6. Feature parity & extend with new features

14

slide-33
SLIDE 33

Time for a plan 1. Make tests compatible 2. Start out easy: only indentation 3. Fix tests one by one 4. Fix old bugs 5. Do not introduce new bugs 6. Feature parity & extend with new features 7. Performance tweaking to same or better level than old

14

slide-34
SLIDE 34

Actual timeline

formatter.format(node, node.offset, node.length).formattedText

1. Make tests compatible

15

slide-35
SLIDE 35

Actual timeline

formatter.format(node, node.offset, node.length).formattedText

1. Make tests compatible

15

slide-36
SLIDE 36

Actual timeline

formatter.format(node, node.offset, node.length).formattedText

1. Make tests compatible

val request = new FormatterRequest() val parsed = new XtextResource() parsed.contents.add(parseResult.rootASTElement) parsed.setParseResult(parseResult) val access = builder.forNodeModel(resource).create() request.setTextRegionAccess(access) val replacements = formatter.format(request) access.rewriter.renderToString(replacements) 15

slide-37
SLIDE 37

interior(entity.regionFor.keyword(“is”), entity.regionFor.keyword(“end”))[indent]

Actual timeline 2. Start out easy: only indentation

16

slide-38
SLIDE 38

interior(entity.regionFor.keyword(“is”), entity.regionFor.keyword(“end”))[indent]

Actual timeline 2. Start out easy: only indentation

  • Indentation requires newline definitions

16

slide-39
SLIDE 39

interior(entity.regionFor.keyword(“is”), entity.regionFor.keyword(“end”))[indent]

Actual timeline 2. Start out easy: only indentation

  • Indentation requires newline definitions
  • => replace all newlines with… the same amount of newlines

16

slide-40
SLIDE 40

Actual timeline 3. Fix tests one by one 4. Fix old bugs

17

slide-41
SLIDE 41

Actual timeline 3. Fix tests one by one 4. Fix old bugs

17

slide-42
SLIDE 42

Actual timeline 5. Do not introduce new bugs

18

slide-43
SLIDE 43

Actual timeline 5. Do not introduce new bugs

18

slide-44
SLIDE 44

Actual timeline 6. Feature parity & extend formatter with new features

19

slide-45
SLIDE 45

Actual timeline 6. Feature parity & extend formatter with new features

  • Parity:

19

slide-46
SLIDE 46

Actual timeline 6. Feature parity & extend formatter with new features

  • Parity:

○ Keyword casing

19

slide-47
SLIDE 47

Actual timeline 6. Feature parity & extend formatter with new features

  • Parity:

○ Keyword casing ○ Comment alignment to columns

19

slide-48
SLIDE 48

Actual timeline 6. Feature parity & extend formatter with new features

  • Parity:

○ Keyword casing ○ Comment alignment to columns ○ Vertical alignment on keywords “:”, “:=”,...

19

slide-49
SLIDE 49

Actual timeline 6. Feature parity & extend formatter with new features

  • Parity:

○ Keyword casing ○ Comment alignment to columns ○ Vertical alignment on keywords “:”, “:=”,... ○ Preserve newline

19

slide-50
SLIDE 50

Actual timeline 6. Feature parity & extend formatter with new features

  • Parity:

○ Keyword casing ○ Comment alignment to columns ○ Vertical alignment on keywords “:”, “:=”,... ○ Preserve newline

  • New features:

19

slide-51
SLIDE 51

Actual timeline 6. Feature parity & extend formatter with new features

  • Parity:

○ Keyword casing ○ Comment alignment to columns ○ Vertical alignment on keywords “:”, “:=”,... ○ Preserve newline

  • New features:

○ Correct indentation

19

slide-52
SLIDE 52

Actual timeline 6. Feature parity & extend formatter with new features

  • Parity:

○ Keyword casing ○ Comment alignment to columns ○ Vertical alignment on keywords “:”, “:=”,... ○ Preserve newline

  • New features:

○ Correct indentation ○ Formatter tags

19

slide-53
SLIDE 53

Actual timeline 6. Feature parity & extend formatter with new features

  • Parity:

○ Keyword casing ○ Comment alignment to columns ○ Vertical alignment on keywords “:”, “:=”,... ○ Preserve newline

  • New features:

○ Correct indentation ○ Formatter tags Easy once we have alignment

19

slide-54
SLIDE 54

Alignment?

20

slide-55
SLIDE 55

Alignment?

20

slide-56
SLIDE 56

Alignment?

  • Replacements are added in random order, applied in correct order

21

slide-57
SLIDE 57

Alignment?

  • Replacements are added in random order, applied in correct order
  • Alignment needs to be done on post-formatted input

21

slide-58
SLIDE 58

Alignment?

  • Replacements are added in random order, applied in correct order
  • Alignment needs to be done on post-formatted input
  • How do I know which region to format?

21

slide-59
SLIDE 59

Alignment!

22

slide-60
SLIDE 60

Alignment!

22

slide-61
SLIDE 61

Alignment!

22

slide-62
SLIDE 62

Alignment!

22

slide-63
SLIDE 63

Alignment!

start end

22

slide-64
SLIDE 64

Alignment!

start end

22

slide-65
SLIDE 65

Alignment!

Find smallest encapsulating object that formats region between start and end

start end

22

slide-66
SLIDE 66

Alignment!

Find smallest encapsulating object that formats region between start and end

start end

22

slide-67
SLIDE 67

Alignment!

clk : in std_logic := ‘X’;

23

slide-68
SLIDE 68

Alignment!

clk : in std_logic := ‘X’; start end

23

slide-69
SLIDE 69

PortDeclaration

Alignment!

clk : in std_logic := ‘X’; start end name direction type value end.getSemanticElement() PortDeclaration PortList

23

slide-70
SLIDE 70

PortDeclaration

Alignment!

clk : in std_logic := ‘X’; start end name direction type value

  • ffset x

x + 4 end.getSemanticElement() PortDeclaration PortList

23

slide-71
SLIDE 71

val rule = portDecl.getParserRule() val oldAccess = createTextRegionAccess(rule, portDecl.text) val formatted = portDecl.format()

Alignment!

Format smallest encapsulating object

24

slide-72
SLIDE 72

val rule = portDecl.getParserRule() val oldAccess = createTextRegionAccess(rule, portDecl.text) val formatted = portDecl.format()

Alignment!

val newAccess = createTextRegionAccess(rule, formatted.text) val oldIndices = oldAccess.getIndices(start, end) val length = newAccess.countBetween(oldIndices)

Format smallest encapsulating object Map unformatted string to formatted string

24

slide-73
SLIDE 73

Align on first parameter?

→return ( →→foo((5, →→·····6), →→····3));

25

slide-74
SLIDE 74

Align on first parameter?

→return ( →→foo((5, →→·····6), →→····3));

25

slide-75
SLIDE 75

Align on first parameter?

→return ( →→foo((5, →→·····6), →→····3)); →return (5, →········foo((5, →·············6), →············3));

25

slide-76
SLIDE 76

Align on first parameter?

→return ( →→foo((5, →→·····6), →→····3)); →return (5, →········foo((5, →·············6), →············3));

25

slide-77
SLIDE 77

Align on first parameter?

→return ( →→foo((5, →→·····6), →→····3)); →return (5, →········foo((5, →·············6), →············3)); →return foo((5, →············6), →···········3));

25

slide-78
SLIDE 78

Align on first parameter?

→return ( →→foo((5, →→·····6), →→····3)); →return (5, →········foo((5, →·············6), →············3)); →return foo((5, →············6), →···········3));

25

slide-79
SLIDE 79

Align on first parameter?

→return ( →→foo((5, →→·····6), →→····3)); →return (5, →········foo((5, →·············6), →············3)); →return foo((5, →············6), →···········3)); →return foo( →→(5, →→·6), →→3));

25

slide-80
SLIDE 80

Align on first parameter?

→return ( →→foo((5, →→·····6), →→····3)); →return (5, →········foo((5, →·············6), →············3)); →return foo((5, →············6), →···········3)); →return foo( →→(5, →→·6), →→3));

25

slide-81
SLIDE 81

Align on first parameter?

→return ( →→foo((5, →→·····6), →→····3)); →return (5, →········foo((5, →·············6), →············3)); →return foo((5, →············6), →···········3)); →return foo( →→(5, →→·6), →→3));

Find largest encapsulating element on same line

25

slide-82
SLIDE 82

Actual timeline 6. Feature parity & extend formatter with new features Correct indentation

26

slide-83
SLIDE 83

Actual timeline 6. Feature parity & extend formatter with new features Correct indentation

val replacements = formatter.format(request)

26

slide-84
SLIDE 84

Actual timeline 6. Feature parity & extend formatter with new features Correct indentation

val replacements = formatter.format(request) replacements .filter[ r| ]

26

slide-85
SLIDE 85

Actual timeline 6. Feature parity & extend formatter with new features Correct indentation

val replacements = formatter.format(request) replacements .filter[ r| r.lineCount > 1 ]

26

slide-86
SLIDE 86

Actual timeline 6. Feature parity & extend formatter with new features Correct indentation

val replacements = formatter.format(request) replacements .filter[ r| r.lineCount > 1 && r.replacementText.newlines + 1 == r.lineCount ]

26

slide-87
SLIDE 87

Actual timeline 6. Feature parity & extend formatter with new features Formatter tags

27

slide-88
SLIDE 88

Actual timeline 6. Feature parity & extend formatter with new features Formatter tags

  • - @formatter:off Turns formatter off
  • - @formatter:on Turns formatter on

27

slide-89
SLIDE 89

Actual timeline 6. Feature parity & extend formatter with new features Formatter tags

  • - @formatter:off Turns formatter off
  • - @formatter:on Turns formatter on

val originalRegions = request.getRegions() ?: document.region

27

slide-90
SLIDE 90

Actual timeline 6. Feature parity & extend formatter with new features Formatter tags

  • - @formatter:off Turns formatter off
  • - @formatter:on Turns formatter on

val originalRegions = request.getRegions() ?: document.region val betweenRegions = document.findRegionsBetween(off, on)

27

slide-91
SLIDE 91

Actual timeline 6. Feature parity & extend formatter with new features Formatter tags

  • - @formatter:off Turns formatter off
  • - @formatter:on Turns formatter on

val originalRegions = request.getRegions() ?: document.region val betweenRegions = document.findRegionsBetween(off, on) .addAll(document.findRegionsBetween(off, EOF))

27

slide-92
SLIDE 92

Actual timeline 6. Feature parity & extend formatter with new features Formatter tags

  • - @formatter:off Turns formatter off
  • - @formatter:on Turns formatter on

val originalRegions = request.getRegions() ?: document.region val betweenRegions = document.findRegionsBetween(off, on) .addAll(document.findRegionsBetween(off, EOF)) val newRegions = originalRegions.removeRegions(betweenRegions)

27

slide-93
SLIDE 93

Actual timeline 6. Feature parity & extend formatter with new features Formatter tags

  • - @formatter:off Turns formatter off
  • - @formatter:on Turns formatter on

val originalRegions = request.getRegions() ?: document.region val betweenRegions = document.findRegionsBetween(off, on) .addAll(document.findRegionsBetween(off, EOF)) val newRegions = originalRegions.removeRegions(betweenRegions) request.setRegions(newRegions)

27

slide-94
SLIDE 94

Performance 7. Performance tweaking to same or better level than old

28

slide-95
SLIDE 95

Performance 7. Performance tweaking to same or better level than old

  • Cache ITextRegionAccess in subformats

28

slide-96
SLIDE 96

Performance 7. Performance tweaking to same or better level than old

  • Cache ITextRegionAccess in subformats
  • Cache IParser.createAllRules(Grammar)

28

slide-97
SLIDE 97

Performance 7. Performance tweaking to same or better level than old

  • Cache ITextRegionAccess in subformats
  • Cache IParser.createAllRules(Grammar)
  • Merge all replacements into one big replacement

28

slide-98
SLIDE 98

Performance 7. Performance tweaking to same or better level than old

emacs/xtend > 25m

29

slide-99
SLIDE 99

Performance 7. Performance tweaking to same or better level than old

emacs/xtend > 25m

30

slide-100
SLIDE 100

Biggest problems in hindsight

31

slide-101
SLIDE 101

Biggest problems in hindsight

  • Tests pass, close enough?

31

slide-102
SLIDE 102

Biggest problems in hindsight

  • Tests pass, close enough?

○ Nope, old testset isn’t nearly enough

31

slide-103
SLIDE 103

Biggest problems in hindsight

  • Tests pass, close enough?

○ Nope, old testset isn’t nearly enough

  • Comments are an enormous pain: eat newlines, add spaces, eat

spaces, fake empty lines

31

slide-104
SLIDE 104

Biggest problems in hindsight

  • Tests pass, close enough?

○ Nope, old testset isn’t nearly enough

  • Comments are an enormous pain: eat newlines, add spaces, eat

spaces, fake empty lines

  • Alignment interactions with normal and first param alignments and

comments

31

slide-105
SLIDE 105

Biggest problems in hindsight

  • Tests pass, close enough?

○ Nope, old testset isn’t nearly enough

  • Comments are an enormous pain: eat newlines, add spaces, eat

spaces, fake empty lines

  • Alignment interactions with normal and first param alignments and

comments

31

slide-106
SLIDE 106

Biggest problems in hindsight

  • Tests pass, close enough?

○ Nope, old testset isn’t nearly enough

  • Comments are an enormous pain: eat newlines, add spaces, eat

spaces, fake empty lines

  • Alignment interactions with normal and first param alignments and

comments

31

slide-107
SLIDE 107

Biggest problems in hindsight

  • Tests pass, close enough?

○ Nope, old testset isn’t nearly enough

  • Comments are an enormous pain: eat newlines, add spaces, eat

spaces, fake empty lines

  • Alignment interactions with normal and first param alignments and

comments

31

slide-108
SLIDE 108

Biggest problems in hindsight

  • Tests pass, close enough?

○ Nope, old testset isn’t nearly enough

  • Comments are an enormous pain: eat newlines, add spaces, eat

spaces, fake empty lines

  • Alignment interactions with normal and first param alignments and

comments

30 31

slide-109
SLIDE 109

Biggest problems in hindsight

  • Tests pass, close enough?

○ Nope, old testset isn’t nearly enough

  • Comments are an enormous pain: eat newlines, add spaces, eat

spaces, fake empty lines

  • Alignment interactions with normal and first param alignments and

comments

30 31

slide-110
SLIDE 110

Biggest problems in hindsight

  • Tests pass, close enough?

○ Nope, old testset isn’t nearly enough

  • Comments are an enormous pain: eat newlines, add spaces, eat

spaces, fake empty lines

  • Alignment interactions with normal and first param alignments and

comments

30 31

slide-111
SLIDE 111

Warning to Xtext users Default ExceptionHandler logs DSL source code to stderr

32

slide-112
SLIDE 112

Sigasi future work

33

slide-113
SLIDE 113

Sigasi future work

  • Smooth out remaining bugs

33

slide-114
SLIDE 114

Sigasi future work

  • Smooth out remaining bugs
  • Some more context awareness

33

slide-115
SLIDE 115

Sigasi future work

  • Smooth out remaining bugs
  • Some more context awareness
  • Autowrap

33

slide-116
SLIDE 116

Sigasi future work

  • Smooth out remaining bugs
  • Some more context awareness
  • Autowrap
  • Performance

33

slide-117
SLIDE 117

Sigasi future work

  • Smooth out remaining bugs
  • Some more context awareness
  • Autowrap
  • Performance
  • Upstream features

33

slide-118
SLIDE 118

Sigasi future work

  • Smooth out remaining bugs
  • Some more context awareness
  • Autowrap
  • Performance
  • Upstream features

○ Formatter tags

33

slide-119
SLIDE 119

Sigasi future work

  • Smooth out remaining bugs
  • Some more context awareness
  • Autowrap
  • Performance
  • Upstream features

○ Formatter tags ○ Correct indentation

33

slide-120
SLIDE 120

Sigasi future work

  • Smooth out remaining bugs
  • Some more context awareness
  • Autowrap
  • Performance
  • Upstream features

○ Formatter tags ○ Correct indentation ○ Performance optimizations

33

slide-121
SLIDE 121

Xtext wish list

34

slide-122
SLIDE 122

Xtext wish list

  • Accept my PRs (tags, correct indent, performance)

34

slide-123
SLIDE 123

Xtext wish list

  • Accept my PRs (tags, correct indent, performance)
  • Fix/discuss my issues

34

slide-124
SLIDE 124

Xtext wish list

  • Accept my PRs (tags, correct indent, performance)
  • Fix/discuss my issues
  • Fix Xtend formatter issues

34

slide-125
SLIDE 125

Xtext wish list

  • Accept my PRs (tags, correct indent, performance)
  • Fix/discuss my issues
  • Fix Xtend formatter issues
  • Very slow Xtend formatter source file

34

slide-126
SLIDE 126

Xtext wish list

  • Accept my PRs (tags, correct indent, performance)
  • Fix/discuss my issues
  • Fix Xtend formatter issues
  • Very slow Xtend formatter source file
  • Add pre- and post format hooks in format(FormatterRequest)

34

slide-127
SLIDE 127

Conclusion

35

slide-128
SLIDE 128

Conclusion

  • Context aware

35

slide-129
SLIDE 129

Conclusion

  • Context aware
  • Debugable

35

slide-130
SLIDE 130

Conclusion

  • Context aware
  • Debugable
  • Good performance

35

slide-131
SLIDE 131

Conclusion

  • Context aware
  • Debugable
  • Good performance
  • Very customizable

35

slide-132
SLIDE 132

Conclusion

  • Context aware
  • Debugable
  • Good performance
  • Very customizable
  • User friendly

35

slide-133
SLIDE 133

Conclusion

  • Context aware
  • Debugable
  • Good performance
  • Very customizable
  • User friendly

○ Done in 2 months (base in 2 weeks) while first task and not used to Xtend

35

slide-134
SLIDE 134

Conclusion

  • Context aware
  • Debugable
  • Good performance
  • Very customizable
  • User friendly

○ Done in 2 months (base in 2 weeks) while first task and not used to Xtend

  • Happy with the switch

35

slide-135
SLIDE 135

Conclusion

  • Context aware
  • Debugable
  • Good performance
  • Very customizable
  • User friendly

○ Done in 2 months (base in 2 weeks) while first task and not used to Xtend

  • Happy with the switch

○ New features

35

slide-136
SLIDE 136

Conclusion

  • Context aware
  • Debugable
  • Good performance
  • Very customizable
  • User friendly

○ Done in 2 months (base in 2 weeks) while first task and not used to Xtend

  • Happy with the switch

○ New features ○ Very readable

35

slide-137
SLIDE 137

Conclusion

  • Context aware
  • Debugable
  • Good performance
  • Very customizable
  • User friendly

○ Done in 2 months (base in 2 weeks) while first task and not used to Xtend

  • Happy with the switch

○ New features ○ Very readable ○ Conditional formatting

35

slide-138
SLIDE 138

Evaluate the Sessions

  • 1 0 +1

Sign in and vote at eclipsecon.org