DEBUGGING DSLS WITH XTEXTS NEW TRACING API 1 Debugging of - - PowerPoint PPT Presentation

debugging dsls with xtext s new tracing api
SMART_READER_LITE
LIVE PREVIEW

DEBUGGING DSLS WITH XTEXTS NEW TRACING API 1 Debugging of - - PowerPoint PPT Presentation

Christian Schneider, Miro Spnemann TypeFox.io DEBUGGING DSLS WITH XTEXTS NEW TRACING API 1 Debugging of Generated Code Whats needed? Mapping of code regions in source to code regions in target Data structures


slide-1
SLIDE 1

DEBUGGING DSLS WITH XTEXT’S NEW TRACING API

1

Christian Schneider, Miro Spönemann
 TypeFox.io

slide-2
SLIDE 2

Debugging of Generated Code

slide-3
SLIDE 3

What’s needed?

  • Mapping of code regions in source 


to code regions in target

  • Data structures implemented in org.eclipse.xtext
slide-4
SLIDE 4

What’s already there?

  • Xtext maps AST elements to


code regions in source

slide-5
SLIDE 5

What’s missing?

  • Mapping of AST elements to code regions in target

public class Debugging { public static void main(final String[] args) throws Throwable { IntegerRange _upTo = new IntegerRange(2, 100); final List<Integer> candidates = IterableExtensions.<Integer>toList(_upTo); List<Integer> _immutableCopy = ImmutableList.<Integer>copyOf(candidates); final Function1<Integer, Boolean> _function = new Function1<Integer, Boolean>() { @Override public Boolean apply(final Integer i) { return Boolean.valueOf(candidates.contains(i)); } }; Iterable<Integer> _filter = IterableExtensions.<Integer>filter(_immutableCopy final Function2<List<Integer>, Integer, List<Integer>> _function_1 = new Function2<List<Integer>, Integer, List<Integer>>() { @Override public List<Integer> apply(final List<Integer> res, final Integer i) { final Function1<Integer, Boolean> _function = new Function1<Integer, Boolean>() { @Override public Boolean apply(final Integer j) { return Boolean.valueOf((((j).intValue() % (i).intValue()) == 0)); } }; Iterable<Integer> _filter = IterableExtensions.<Integer>filter(candidates final List<Integer> sieved = IterableExtensions.<Integer>toList(_filter Iterables.removeAll(res, sieved); return res; } }; List<Integer> _fold = IterableExtensions.<Integer, List<Integer>>fold(_filter String _join = IterableExtensions.join(_fold, ", "); InputOutput.<String>println(_join); InputOutput.<String>println("done"); }

slide-6
SLIDE 6

Requirements

  • API for tracing code regions in code generators
  • Should integrate nicely with Xtend’s template

expressions

  • Trace code regions per eObject
  • Attributes:


Distinguish code regions corresponding to attributes

  • Containment:


Distinguish code regions corresponding to children

slide-7
SLIDE 7

XTEND

def foo(Object parameter) ''' Code code «parameter» code code with leading white space «IF guard» guard is satisfied code «ELSE» guard is missed code «ENDIF» «FOR element : list» element «element.name» code: more element specific code «ENDFOR» ''' @Accessors @FinalFieldsConstructor class Foo implements Bar { @Delegate val Bar bar } def String name(Object o) { ... }

http://xtend-lang.org

slide-8
SLIDE 8

Example

https://github.com/TypeFox/tracing_codegen

slide-9
SLIDE 9

Model: types+=ClassDeclaration*; ClassDeclaration: 'class' name=ID '{' members+=Member* '}'; Member: Property | Operation; Property: name=ID ':' type=TypeRef; Operation: name=ID '(' parameters+=Parameter* ')' ':' type=TypeRef '{' expression=Expression? '}'; class Person { name: string bag: Bag getCash(): number { bag.wallet.cash } }

slide-10
SLIDE 10

class MyDslGenerator extends AbstractGenerator {

  • verride void doGenerate(Resource resource,

IFileSystemAccess2 fsa, IGeneratorContext context) { val model = resource.contents.head as Model val baseName = resource.baseName fsa.generateFile(baseName + '.h', ''' /******************************** * Header file for «resource.URI.lastSegment» */ #ifndef «baseName.toUpperCase»_H #define «baseName.toUpperCase»_H «FOR c : model.types» «generateHeader(c)» «ENDFOR» #endif ''') } }

slide-11
SLIDE 11

class MyDslGenerator extends AbstractGenerator {

  • verride void doGenerate(Resource resource,

IFileSystemAccess2 fsa, IGeneratorContext context) { val model = resource.contents.head as Model val baseName = resource.baseName fsa.generateTracedFile(baseName + '.h', model, ''' /******************************** * Header file for «resource.URI.lastSegment» */ #ifndef «baseName.toUpperCase»_H #define «baseName.toUpperCase»_H «FOR c : model.types» «generateHeader(c)» «ENDFOR» #endif ''') } }

slide-12
SLIDE 12

protected def generateHeader(ClassDeclaration decl) ''' /* * Declaration of «decl.name» class */ struct «decl.name» { «FOR prop : decl.members.filter(Property)» /* Property «decl.name».«prop.name» */ «generateDeclaration(prop)» «ENDFOR» }; '''

slide-13
SLIDE 13

@Traced protected def generateHeader(ClassDeclaration decl) ''' /* * Declaration of «decl.name» class */ struct «decl.name» { «FOR prop : decl.members.filter(Property)» /* Property «decl.name».«prop.name» */ «generateDeclaration(prop)» «ENDFOR» }; '''

slide-14
SLIDE 14

@Traced protected def generateHeader(ClassDeclaration decl) ''' /* * Declaration of «decl.name» class */ struct «decl._name» { «FOR prop : decl.members.filter(Property)» /* Property «decl.name».«prop.name» */ «generateDeclaration(prop)» «ENDFOR» }; '''

slide-15
SLIDE 15

ClassDeclaration: 'class' name=ID '{' members+=Member* '}'; @TracedAccessors(MyDslFactory) class MyDslTraceExtensions {}

ClassDeclaration name: String members: Member[] MyDslFactory createClassDeclaration() …

Xtext + EMF public IGeneratorNode _name(ClassDeclaration target) {…} Xtend Annotation Processor @Inject extension MyDslTraceExtensions

slide-16
SLIDE 16

The Generator Tree

double __local_2 = __local_1

  • >

cash ;

double __local_2 = __local_1->cash;

slide-17
SLIDE 17

double __local_2 = __local_1

  • >

cash ;

AST

Location Location Location

The Generator Tree

slide-18
SLIDE 18

Building a Generator Tree

val node = trace(expression) node.append(generateType(expression.feature.type)) node.append(' ') node.append(resultVar) node.append(' = ') node.append(receiverVar ?: 'this') node.append('->') node.append(expression.feature.name)

slide-19
SLIDE 19

Demo

slide-20
SLIDE 20

What else?

  • What if debugging the DSL is not possible?
  • Feeding back changes in target to the source is

strongly recommended

slide-21
SLIDE 21

What else?

slide-22
SLIDE 22

https://github.com/TypeFox/tracing_codegen

To Go Further

slide-23
SLIDE 23

Evaluate the Sessions

  • 1 0 +1

Sign in and vote at eclipsecon.org