狠狠撸

狠狠撸Share a Scribd company logo
?2014 Shintaro Hosoai
Xtext & Xtend
Documents
細合 晋太郎
2014/3/31 SEA関西プロセス分科会
?2014 Shintaro Hosoai
Xtext
2014/3/31 SEA関西プロセス分科会 2
?2014 Shintaro Hosoai
Xtext構造
grammar org.eclipse.xtext.example.fowlerdsl.Statemachine with
org.eclipse.xtext.common.Terminals
generate statemachine "http://www.eclipse.org/xtext/example/fowlerdsl/Statemachine"
Statemachine :
{Statemachine}
('events'
events+=Event+
'end')?
('resetEvents'
resetEvents+=[Event]+
'end')?
('commands'
commands+=Command+
'end')?
states+=State*;
terminal MYID:
'A''0'..'9';
言語名宣言と言語Mixin
言語モデル宣言
Parser Rule/言語構造定義
lexis/語彙定義
初めのうちは,上二つは自動生成ままで利用するのがよい
Event:
name=ID;
...
?2014 Shintaro Hosoai
DSL Mixin
? DSL Mixinを行うにはWith句にDSL名を指定する.
grammar DSL名 with ベースDSL名
? デフォルトのDSL
org.eclipse.xtext.common.Terminals
IDやINT,STRING等のTerminalが定義されている.
? Xbase
org.eclipse.xtext.xbase.Xbase
Jvm統合に必要な各種要素が定義されている.
? 自前DSLをMixinするには,以下のようにwith句にDSL名を
指定
42014/3/31 SEA関西プロセス分科会
grammar my.SuperGrammar
generate super "http://my.org/super"
...
RuleA : "a" stuff=RuleB;
RuleB : "{" name=ID "}";
grammar my.SubGrammar with my.SuperGrammar
...
ベースDSL
子DSL
?2014 Shintaro Hosoai
Parser Rules
? 定義名:~‘;’までが一つのルールとなる.
? この定義名のモデルが生成される(Returnsを
指定しない場合,Returnsで指定したモデルを
割り当てることも出来る.)
52014/3/31 SEA関西プロセス分科会
State:
'state' name=ID
('actions' '{' actions+=[Command]+ '}')?
transitions+=Transition*
'end';
Transition:
event=[Event] '=>' state=[State];
DSL定義
?2014 Shintaro Hosoai
語彙
? ’’で区切った部分は語彙として定義される
62014/3/31 SEA関西プロセス分科会
State:
'state' name=ID
('actions' '{' actions+=[Command]+ '}')?
transitions+=Transition*
'end';
DSL定義
state myState
actions { myCommand1 myCommand2 }
event2 => myState2
event3 => myState3
end
DSL例
?2014 Shintaro Hosoai
変数
? 変数は,属性として生成される.
? 割り当てに応じて
=:単体,
+=:EList
? として生成される
72014/3/31 SEA関西プロセス分科会
State:
'state' name=ID
('actions' '{' actions+=[Command]+ '}')?
transitions+=Transition*
'end';
Transition:
event=[Event] '=>' state=[State];
DSL定義
State
name : ID
actions : List<Command>
transitions:List<Transition>
Transition
event : Event
state : State
?2014 Shintaro Hosoai
数量子
? ():グループ
? * :0回以上
? + :1回以上
? ? :0または1
? Terminal 限定
? . :任意の一文字
? ! :否定.!(‘A’|’B’|’C’)なら ABC以外の文字が
マッチ.
? -> : Until, ‘/*’ -> ‘*/’ なら*/が来るまでスキップさ
れる
? .. :範囲値.‘A’..’D’ ならABCD,数値も可
Unicodeの並びで範囲指定しているらし
い.
このため日本語を指定することも可能.
82014/3/31 SEA関西プロセス分科会
?2014 Shintaro Hosoai
Type Reference
State:
'state' name=ID
('actions' '{' actions+=[Command]+ '}')?
transitions+=Transition*
'end';
state myState
actions { myCommand1 myCommand2 }
event2 => myState2
event3 => myState3
end
Transition:
event=[Event] '=>' state=[State];
DSL定義
DSL例
[]で指定した要素はnameによりで
インスタンスを参照する.
このため参照されるRuleにはname=ID
を持つ必要がある.
例ではState,Event,Commandは参照可
Transitionはname=IDを持たないので,
参照出来ない.
割り当てに用いることが出来るのは,
?Terminal Rule (ex: ID)
?Parser Rule (ex: Transition)
?Parser Ruleの実体への参照(ex: [Command])
?2014 Shintaro Hosoai
Terminal
? 任意の語彙の作成
? terminal 語彙名 :
定義;
? 例えば,アルファベットから始まる英数字の羅
列
? terminal MyID :
(‘a’..’z’|’A’..’Z’)(‘a’..’z’|’A’..’Z’|’0’..’9’)*;
102014/3/31 SEA関西プロセス分科会
?2014 Shintaro Hosoai
Xtend
2014/3/31 SEA関西プロセス分科会 11
?2014 Shintaro Hosoai
こんにちはXtend!
? Xtendの記法はJavaによく似ています.
? メソッド定義はdefキーワードで行います.
?class HelloWorld {
def static void main(String[] args) {
println("Hello World")
}
}
// Generated Java Source Code
import org.eclipse.xtext.xbase.lib.InputOutput;
public class HelloWorld {
public static void main(final String[] args) {
InputOutput.<String>println("Hello World");
}
}
自動生成
生成されたJavaコード
Xtendコード
記述したXtendコードはセーブ
タイミングで自動的にJavaコー
に変換されます.
?2014 Shintaro Hosoai
Xtendの特徴
? Extension methods
? Lambda Expression
? Active Annotations
? Operator overloading
? Powerful switch expressions
? Multiple dispatch
? Template expressions
? No statement
? Properties
? Type inference
? Full support for Java generics
? Translate to Java (not bytecode)
?2014 Shintaro Hosoai
Classes and Members
package com.acme
import java.util.List
class MyClass {
String name
new(String name) {
this.name = name
}
def String first(List<String> elements) {
elements.get(0)
}
}
セミコロンは不要(あってもよ
い)
コンストラクタはnewキーワードで定義
クラス内で自身のコンストラクタ呼び出しは
this().
親コンストラクタはsuper() (Javaと同じ)
メソッドはdefキー
ワードで定義
デフォルトはpublic. protected,
package, privateを指定可能
extends, implementsの使い方は
Javaと同じ
?2014 Shintaro Hosoai
Field(1)
? 変数宣言の方法は3つ
? Javaと同じ型名 変数名
メソッド内の定義には使えない.var/valを利用する
こと
? var 変数名 :動的型.型推論で適切な型が振られ
る
? val 定数名 :定数宣言.こちらも明確な型指定は
行わず,初回代入時の型に応じて決まる.
? アクセス指示子はデフォルトでPrivate
?2014 Shintaro Hosoai
Field(2)
? getter/setterの自動呼出し
? FooクラスにsetHoge(), getHoge()定義されている場
合.
? val foo = new Foo
? foo.hoge : getHoge()が呼ばれる
? foo.hoge = “aaa”:setHoge(“aaa”)が呼ばれる
? getter/setterの自動生成
? @Property
? Type variable
? とすることで,自動的にGetter/Setterが生成される
162014/3/31 SEA関西プロセス分科会
?2014 Shintaro Hosoai
Field(3)
? this
? Javaと同じ.省略可
? it:
省略可能になる変数,Lambdaと組合わせるといいら
しい
? val it = new Person
? name = “Horst” : it.setName()が呼ばれる
? クラス変数,クラスメソッドへのアクセス
? MyClass::myField
? MyClass::myMethod()
172014/3/31 SEA関西プロセス分科会
?2014 Shintaro Hosoai
Expression
? Xtendの構文はすべて式です.メソッド呼び出
しはもちろん,ブロック,各種制御構文,メ
ソッド定義もすべて値を返します.
? 関数型もあります
? val toUpperCaseFunction = [String s |
s.toUpperCase]
↑String.toUpperCaseメソッドを
toUpperCaseFunctionという変数に代入
182014/3/31 SEA関西プロセス分科会
?2014 Shintaro Hosoai
Operators(1)
? 一覧は演算子とオーバーライド章を参照
? 等価?比較演算子
? ==, != : equals()で比較.文字列比較はこれ
で
? ===, !== : 従来のJavaの比較演算子.Reference
? >, <, >=, <= : Javaと同じ.Comparable
? 算術演算:
+, -, *, /, %, **.Javaと同じだが,Primitive Type以外に
もオーバーライドして利用可
? Elvis Operator: null-safe feature call
? val salutation = person.firstName ?: ‘Sir/Madam’
? personがNullでもぬるぽにならない.’Sir/Madam’が
代入される
192014/3/31 SEA関西プロセス分科会
?2014 Shintaro Hosoai
Operators(2)
? With Operator:オブジェクトの属性に簡単代入
? var person = new Person => [
firstName = “Shintaro”
lastName = “Hosoai”
address = new Address => [
city = “Fukuoka”
]
]
? Range Operator : 範囲値作成
? 0..10 → 012345678910
? Pair Operator : ペア値作成(簡易Hash?)
? val nameAndAge = ‘Homer’ -> 42
202014/3/31 SEA関西プロセス分科会
?2014 Shintaro Hosoai
制御構文:IF
? if (cond) {
? expression
? }else{
? elseExpression
? }
? ifも式として用いる事ができます.
? var name = if (firstName!=null)
firstName+’ ’+lastName else lastName
? var name = if (str.length>1) str : elseを省略する
とelse nullと見なされます(nullが返る)
212014/3/31 SEA関西プロセス分科会
?2014 Shintaro Hosoai
制御構文:switch
switch myString {
case myString.length > 5 : “a long string”
case ‘some’ : “It’s some string”.
default : “It’s another short string”
}
? caseに条件文が使えます.break句は不要です.
Stringの比較が行えます.
222014/3/31 SEA関西プロセス分科会
?2014 Shintaro Hosoai
制御構文:switch:Type Guard
def something(Object o){
switch o {
String : o.substring(3)
Integer case o > 10 : o.toString
default : “not match”
}
}
型で条件分岐できます.(instanceof)
型にマッチした後にさらにCaseで条件を加える
事ができます.マッチした時点で自動的にCast
されています.
232014/3/31 SEA関西プロセス分科会
このOはIntegerに
Castされている
このOはStringに
Castされている
?2014 Shintaro Hosoai
制御構文:for
? Xtendのforはjava5の拡張Forのみです.従来の
for(int a=0; a<10;a++)といった書き方はできませ
ん.
(Range記法と組み合わせる事で同様の事はで
きます)
for ( Type variable : arrayOrIterable){
expressions.
}
型宣言や{}は省略可です.適切な型が選択さ
れます.ex) List<String>ならStringの変数となる.
for(variable : arrayOrIterable) expression
242014/3/31 SEA関西プロセス分科会
?2014 Shintaro Hosoai
制御構文:for Rangeとの組み合わ
せ
? 1~10までループしたい場合どうするの?
for (i : 1 ..10)
print i
10..1で逆順も可能
Range Operations
? 0..10 → 012345678910
? 0..<10 → 0123456789
? 10>..0 → 9876543210
? 0 .. hoge.length といった表記も可
252014/3/31 SEA関西プロセス分科会
?2014 Shintaro Hosoai
Methods(1)
? メソッド宣言はdefで行う.デフォルトのアク
セス指示子はpublic. protected, package, private指
定可.
? 返り値の型は省略可能.またReturnも省略可
能,一番最後の式の値が返る.
? staticでクラスメソッドとすることも出来る
(Javaと同じ)
? 抽象メソッド
? 抽象クラスやインターフェイス内で,Bodyの
無いメソッド定義は,抽象メソッドとなる.
abstract class MyAbstractClass() {
def String abstractMethod() // no body
}
?2014 Shintaro Hosoai
Methods(2)
? オーバーライドはdefの代わりにoverrideキー
ワードを用いて明示する.
? Exception
? Javaと同様
? Generic
? Javaと同様
? Method Call
? Javaと同様.引数がない場合は()省略可能
override String second(List<String> elements) {
elements.get(1)
}
?2014 Shintaro Hosoai
Lambda(1)
? [ Type variable | expression]
? 以下,JavaとXtendのLambdaの実装比較
Java
final JTextField textField = new JTextField();
textFeild.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
textField.text=“Something happend”);
}});
Xtend
val textField = new JTextField
textField.addActionListener([ActionEvent e |
textField.text = “Something happned”
])
282014/3/31 SEA関西プロセス分科会
これも省略可
?2014 Shintaro Hosoai
Lambda(2)
? [a, b | a.length – b.length] <二引数の関数の場合
? 変数への代入も可能
? val myFunction = [Type a | a.doAnything()]
? コレクションにももちろん利用可能
? 予め便利なメソッド群がExtension Methodとして追
加されている
? forEach((T)=>void Procedure) : void
? map((T)=>R Transformation) : List<R>
? filter((T)=> Boolean Predicate) : Iteratable<T>
? findFirst((T)=>Boolean Predicate): T
? reduce((T,T)=> T function): T
? などなど.
292014/3/31 SEA関西プロセス分科会
?2014 Shintaro Hosoai
Dispatch Methods(1)
? Javaはコンパイル時の型に基づいて,メソッド
呼び出しを決定する.このため,動的に
Dispatchできない
左図のような構造で,Dispatcher
に
MyInterface a = MyClass1();
Dispatcher.dispatch(a);
とすると,呼び出しは不
定となる
(コンパイルできない)
? 言語AST(Abstract Syntax Tree)へのアクセスは,
このようなDispatch Methodが多用される
MyInterface
MyClass1 MyClass2
Dispatcher
dispatch(MyClass1 a)
dispatch(MyClass2 b)
?2014 Shintaro Hosoai
Dispatch Methods(2)
? Xtendではdispatch
キーワードを付与する
ことで,Dispatch Method
として定義できる
? 次のようなXtext定義を
行った際などは,dispatch
を指定するとよい
class DispatchSample {
def doGenerate(){
val expressions = new
ArrayList<Expression>
expressions.add(new Add)
expressions.add(new Sub)
expressions.add(new Mul)
expressions.add(new Div)
for(e : expressions){
genExpression(e);
}
}
dispatch def genExpression(Add a)''''''
dispatch def genExpression(Sub a)''''''
dispatch def genExpression(Mul a)''''''
dispatch def genExpression(Div a)''''''
}
interface Expression{}
class Add implements Expression{}
class Sub implements Expression{}
class Mul implements Expression{}
class Div implements Expression{}
Expression :
Add | Sub | Mul | Div;
Add : ...;
Sub : ...;
Mul : ...;
Div : ...;
実際にはDSL
のパーサがこ
のようにモデ
ルを詰めて渡
してくる
Xtextで
生成
される
AST
?2014 Shintaro Hosoai
Extension Methods
? クラスにメソッドを(仮想的に)付け加える
? たとえば.StringにtoFirstUpper()メソッドを加
えたり
? 第一引数を対象の型にしたメソッドはExtension
Methodとして呼び出せる
? def extensionCall(String str, Hoge any){
? str.doSomething()
? }
? “hello”.extensionCall(hogeAny) ←呼び出す時は左
辺のオブジェクトが第一引数として渡される.
?2014 Shintaro Hosoai
Extension Imports/Provider
? Xtendには,モデル操作等の便利なユーティリ
ティメソッドがExtension Methodのライブラリ
として提供されている
? ObjectExtensions (src)
? IterableExtensions (src)
? MapExtensions (src)
? ListExtensions (src)
? CollectionExtensions (src)
? BooleanExtensions (src)
? IntegerExtensions (src)
? FunctionExtensions (src)
?2014 Shintaro Hosoai
Active Annotation
? @Property
? 属性に付与することで,private変数とgetter/setter
を生成する
? @Property
String name
? ->
private String _name;
String getName(){return _name;}
void setName(String name){this._name=name;}
? @Data
? クラスに付与することで,含まれる属性の
getter/setter, 属性設定を行うコンストラクタ等を生
成
?2014 Shintaro Hosoai
Annotation Type Declaration
annotation MyAnnotation {
String[] value
boolean isTricky = false
int[] lotteryNumbers = #[ 42, 137 ]
}
?2014 Shintaro Hosoai
Enum Type Declaration
? Javaと同じ?
enum MyColor {
GREEN,
BLUE,
RED
}
?2014 Shintaro Hosoai
演算子とオーバーライド(1)
? Xtendでは,演算子のオーバーライドが可能
? 演算子に対応するメソッドを定義すると,その
演算子が使われた際に対応するメソッドが呼ば
れる.
class OperatorOverwrite {
String name = “hoge”
def operator_plus(OperatorOverwrite e2){
this.name+"::"+e2.name
}
def static void main(String[] args) {
var op1 = new OperatorOverwrite;
var op2 = new OperatorOverwrite;
print(op1+op2)
}
}
+二項演算子の定義.
オーバーライドではある
がoverrideではなくdefで
定義する.
thisが左辺,引数が右辺.
ここでは自身と同じ型を
引数に取っているが,異
なる型でも可能.オー
バーロードも可.
+二項演算子の呼び出し
?2014 Shintaro Hosoai
演算子とオーバーライド(2)
演算子 対応メソッド名 演算子 対応メソッド名
! e1 e1.operator_not() e1 == e2 e1.operator_equals(e2)
- e1 e1.operator_minus() e1 != e2 e1.operator_notEquals(e2)
+ e1 e1.operator_plus() e1 === e2 e1.operator_tripleEquals(e2)
e1 + e2 e1.operator_plus(e2) e1 !== e2 e1.operator_tripleNotEquals(e2)
e1 – e2 e1.operator_minus(e2) e1 < e2 e1.operator_lessThan(e2)
e1 * e2 e1.operator_multiply(e2) e1 > e2 e1.operator_greaterThan(e2)
e1 / e2 e1.operator_divide(e2) e1 <= e2 e1.operator_lessEqualsThan(e2)
e1 % e2 e1.operator_modulo(e2) e1 >= e2 e1.operator_greaterEqualsThan(e2)
e1 ** e2 e1.operator_power(e2) e1 -> e2 e1.operator_mappedTo(e2)
e1 += e2 e1.operator_add(e2) e1 .. e2 e1.operator_upTo(e2)
e1 –= e2 e1.operator_remove(e2) e1 >.. e2 e1.operator_greaterThanDoubleDot(
e2)
e1 || e2 e1.operator_or(e2) e1 ..<e2 e1.operator_doubleDotLessThan(e2)
e1 && e2 e1.operator_and(e2)
?2014 Shintaro Hosoai
演算子とオーバーライド(3)
演算子 対応メソッド名 演算子 対応メソッド名
e1 => e2 e1.operator_equals(e2)
e1 <= e2 e1.operator_notEquals(e2) e1 >>> e2 e1.operator_greaterThan(e2)
e1 << e2 e1.operator_tripleEquals(e2) e1 <> e2 e1.operator_lessEqualsThan(e2)
e1 >> e2 e1.operator_tripleNotEquals(
e2)
e1 ?: e2 e1.operator_greaterEqualsThan(
e2)
e1 <<< e2 e1.operator_lessThan(e2) e1 <=> e2 e1.operator_mappedTo(e2)

More Related Content

Xtext&Xtend documents

  • 1. ?2014 Shintaro Hosoai Xtext & Xtend Documents 細合 晋太郎 2014/3/31 SEA関西プロセス分科会
  • 2. ?2014 Shintaro Hosoai Xtext 2014/3/31 SEA関西プロセス分科会 2
  • 3. ?2014 Shintaro Hosoai Xtext構造 grammar org.eclipse.xtext.example.fowlerdsl.Statemachine with org.eclipse.xtext.common.Terminals generate statemachine "http://www.eclipse.org/xtext/example/fowlerdsl/Statemachine" Statemachine : {Statemachine} ('events' events+=Event+ 'end')? ('resetEvents' resetEvents+=[Event]+ 'end')? ('commands' commands+=Command+ 'end')? states+=State*; terminal MYID: 'A''0'..'9'; 言語名宣言と言語Mixin 言語モデル宣言 Parser Rule/言語構造定義 lexis/語彙定義 初めのうちは,上二つは自動生成ままで利用するのがよい Event: name=ID; ...
  • 4. ?2014 Shintaro Hosoai DSL Mixin ? DSL Mixinを行うにはWith句にDSL名を指定する. grammar DSL名 with ベースDSL名 ? デフォルトのDSL org.eclipse.xtext.common.Terminals IDやINT,STRING等のTerminalが定義されている. ? Xbase org.eclipse.xtext.xbase.Xbase Jvm統合に必要な各種要素が定義されている. ? 自前DSLをMixinするには,以下のようにwith句にDSL名を 指定 42014/3/31 SEA関西プロセス分科会 grammar my.SuperGrammar generate super "http://my.org/super" ... RuleA : "a" stuff=RuleB; RuleB : "{" name=ID "}"; grammar my.SubGrammar with my.SuperGrammar ... ベースDSL 子DSL
  • 5. ?2014 Shintaro Hosoai Parser Rules ? 定義名:~‘;’までが一つのルールとなる. ? この定義名のモデルが生成される(Returnsを 指定しない場合,Returnsで指定したモデルを 割り当てることも出来る.) 52014/3/31 SEA関西プロセス分科会 State: 'state' name=ID ('actions' '{' actions+=[Command]+ '}')? transitions+=Transition* 'end'; Transition: event=[Event] '=>' state=[State]; DSL定義
  • 6. ?2014 Shintaro Hosoai 語彙 ? ’’で区切った部分は語彙として定義される 62014/3/31 SEA関西プロセス分科会 State: 'state' name=ID ('actions' '{' actions+=[Command]+ '}')? transitions+=Transition* 'end'; DSL定義 state myState actions { myCommand1 myCommand2 } event2 => myState2 event3 => myState3 end DSL例
  • 7. ?2014 Shintaro Hosoai 変数 ? 変数は,属性として生成される. ? 割り当てに応じて =:単体, +=:EList ? として生成される 72014/3/31 SEA関西プロセス分科会 State: 'state' name=ID ('actions' '{' actions+=[Command]+ '}')? transitions+=Transition* 'end'; Transition: event=[Event] '=>' state=[State]; DSL定義 State name : ID actions : List<Command> transitions:List<Transition> Transition event : Event state : State
  • 8. ?2014 Shintaro Hosoai 数量子 ? ():グループ ? * :0回以上 ? + :1回以上 ? ? :0または1 ? Terminal 限定 ? . :任意の一文字 ? ! :否定.!(‘A’|’B’|’C’)なら ABC以外の文字が マッチ. ? -> : Until, ‘/*’ -> ‘*/’ なら*/が来るまでスキップさ れる ? .. :範囲値.‘A’..’D’ ならABCD,数値も可 Unicodeの並びで範囲指定しているらし い. このため日本語を指定することも可能. 82014/3/31 SEA関西プロセス分科会
  • 9. ?2014 Shintaro Hosoai Type Reference State: 'state' name=ID ('actions' '{' actions+=[Command]+ '}')? transitions+=Transition* 'end'; state myState actions { myCommand1 myCommand2 } event2 => myState2 event3 => myState3 end Transition: event=[Event] '=>' state=[State]; DSL定義 DSL例 []で指定した要素はnameによりで インスタンスを参照する. このため参照されるRuleにはname=ID を持つ必要がある. 例ではState,Event,Commandは参照可 Transitionはname=IDを持たないので, 参照出来ない. 割り当てに用いることが出来るのは, ?Terminal Rule (ex: ID) ?Parser Rule (ex: Transition) ?Parser Ruleの実体への参照(ex: [Command])
  • 10. ?2014 Shintaro Hosoai Terminal ? 任意の語彙の作成 ? terminal 語彙名 : 定義; ? 例えば,アルファベットから始まる英数字の羅 列 ? terminal MyID : (‘a’..’z’|’A’..’Z’)(‘a’..’z’|’A’..’Z’|’0’..’9’)*; 102014/3/31 SEA関西プロセス分科会
  • 11. ?2014 Shintaro Hosoai Xtend 2014/3/31 SEA関西プロセス分科会 11
  • 12. ?2014 Shintaro Hosoai こんにちはXtend! ? Xtendの記法はJavaによく似ています. ? メソッド定義はdefキーワードで行います. ?class HelloWorld { def static void main(String[] args) { println("Hello World") } } // Generated Java Source Code import org.eclipse.xtext.xbase.lib.InputOutput; public class HelloWorld { public static void main(final String[] args) { InputOutput.<String>println("Hello World"); } } 自動生成 生成されたJavaコード Xtendコード 記述したXtendコードはセーブ タイミングで自動的にJavaコー に変換されます.
  • 13. ?2014 Shintaro Hosoai Xtendの特徴 ? Extension methods ? Lambda Expression ? Active Annotations ? Operator overloading ? Powerful switch expressions ? Multiple dispatch ? Template expressions ? No statement ? Properties ? Type inference ? Full support for Java generics ? Translate to Java (not bytecode)
  • 14. ?2014 Shintaro Hosoai Classes and Members package com.acme import java.util.List class MyClass { String name new(String name) { this.name = name } def String first(List<String> elements) { elements.get(0) } } セミコロンは不要(あってもよ い) コンストラクタはnewキーワードで定義 クラス内で自身のコンストラクタ呼び出しは this(). 親コンストラクタはsuper() (Javaと同じ) メソッドはdefキー ワードで定義 デフォルトはpublic. protected, package, privateを指定可能 extends, implementsの使い方は Javaと同じ
  • 15. ?2014 Shintaro Hosoai Field(1) ? 変数宣言の方法は3つ ? Javaと同じ型名 変数名 メソッド内の定義には使えない.var/valを利用する こと ? var 変数名 :動的型.型推論で適切な型が振られ る ? val 定数名 :定数宣言.こちらも明確な型指定は 行わず,初回代入時の型に応じて決まる. ? アクセス指示子はデフォルトでPrivate
  • 16. ?2014 Shintaro Hosoai Field(2) ? getter/setterの自動呼出し ? FooクラスにsetHoge(), getHoge()定義されている場 合. ? val foo = new Foo ? foo.hoge : getHoge()が呼ばれる ? foo.hoge = “aaa”:setHoge(“aaa”)が呼ばれる ? getter/setterの自動生成 ? @Property ? Type variable ? とすることで,自動的にGetter/Setterが生成される 162014/3/31 SEA関西プロセス分科会
  • 17. ?2014 Shintaro Hosoai Field(3) ? this ? Javaと同じ.省略可 ? it: 省略可能になる変数,Lambdaと組合わせるといいら しい ? val it = new Person ? name = “Horst” : it.setName()が呼ばれる ? クラス変数,クラスメソッドへのアクセス ? MyClass::myField ? MyClass::myMethod() 172014/3/31 SEA関西プロセス分科会
  • 18. ?2014 Shintaro Hosoai Expression ? Xtendの構文はすべて式です.メソッド呼び出 しはもちろん,ブロック,各種制御構文,メ ソッド定義もすべて値を返します. ? 関数型もあります ? val toUpperCaseFunction = [String s | s.toUpperCase] ↑String.toUpperCaseメソッドを toUpperCaseFunctionという変数に代入 182014/3/31 SEA関西プロセス分科会
  • 19. ?2014 Shintaro Hosoai Operators(1) ? 一覧は演算子とオーバーライド章を参照 ? 等価?比較演算子 ? ==, != : equals()で比較.文字列比較はこれ で ? ===, !== : 従来のJavaの比較演算子.Reference ? >, <, >=, <= : Javaと同じ.Comparable ? 算術演算: +, -, *, /, %, **.Javaと同じだが,Primitive Type以外に もオーバーライドして利用可 ? Elvis Operator: null-safe feature call ? val salutation = person.firstName ?: ‘Sir/Madam’ ? personがNullでもぬるぽにならない.’Sir/Madam’が 代入される 192014/3/31 SEA関西プロセス分科会
  • 20. ?2014 Shintaro Hosoai Operators(2) ? With Operator:オブジェクトの属性に簡単代入 ? var person = new Person => [ firstName = “Shintaro” lastName = “Hosoai” address = new Address => [ city = “Fukuoka” ] ] ? Range Operator : 範囲値作成 ? 0..10 → 012345678910 ? Pair Operator : ペア値作成(簡易Hash?) ? val nameAndAge = ‘Homer’ -> 42 202014/3/31 SEA関西プロセス分科会
  • 21. ?2014 Shintaro Hosoai 制御構文:IF ? if (cond) { ? expression ? }else{ ? elseExpression ? } ? ifも式として用いる事ができます. ? var name = if (firstName!=null) firstName+’ ’+lastName else lastName ? var name = if (str.length>1) str : elseを省略する とelse nullと見なされます(nullが返る) 212014/3/31 SEA関西プロセス分科会
  • 22. ?2014 Shintaro Hosoai 制御構文:switch switch myString { case myString.length > 5 : “a long string” case ‘some’ : “It’s some string”. default : “It’s another short string” } ? caseに条件文が使えます.break句は不要です. Stringの比較が行えます. 222014/3/31 SEA関西プロセス分科会
  • 23. ?2014 Shintaro Hosoai 制御構文:switch:Type Guard def something(Object o){ switch o { String : o.substring(3) Integer case o > 10 : o.toString default : “not match” } } 型で条件分岐できます.(instanceof) 型にマッチした後にさらにCaseで条件を加える 事ができます.マッチした時点で自動的にCast されています. 232014/3/31 SEA関西プロセス分科会 このOはIntegerに Castされている このOはStringに Castされている
  • 24. ?2014 Shintaro Hosoai 制御構文:for ? Xtendのforはjava5の拡張Forのみです.従来の for(int a=0; a<10;a++)といった書き方はできませ ん. (Range記法と組み合わせる事で同様の事はで きます) for ( Type variable : arrayOrIterable){ expressions. } 型宣言や{}は省略可です.適切な型が選択さ れます.ex) List<String>ならStringの変数となる. for(variable : arrayOrIterable) expression 242014/3/31 SEA関西プロセス分科会
  • 25. ?2014 Shintaro Hosoai 制御構文:for Rangeとの組み合わ せ ? 1~10までループしたい場合どうするの? for (i : 1 ..10) print i 10..1で逆順も可能 Range Operations ? 0..10 → 012345678910 ? 0..<10 → 0123456789 ? 10>..0 → 9876543210 ? 0 .. hoge.length といった表記も可 252014/3/31 SEA関西プロセス分科会
  • 26. ?2014 Shintaro Hosoai Methods(1) ? メソッド宣言はdefで行う.デフォルトのアク セス指示子はpublic. protected, package, private指 定可. ? 返り値の型は省略可能.またReturnも省略可 能,一番最後の式の値が返る. ? staticでクラスメソッドとすることも出来る (Javaと同じ) ? 抽象メソッド ? 抽象クラスやインターフェイス内で,Bodyの 無いメソッド定義は,抽象メソッドとなる. abstract class MyAbstractClass() { def String abstractMethod() // no body }
  • 27. ?2014 Shintaro Hosoai Methods(2) ? オーバーライドはdefの代わりにoverrideキー ワードを用いて明示する. ? Exception ? Javaと同様 ? Generic ? Javaと同様 ? Method Call ? Javaと同様.引数がない場合は()省略可能 override String second(List<String> elements) { elements.get(1) }
  • 28. ?2014 Shintaro Hosoai Lambda(1) ? [ Type variable | expression] ? 以下,JavaとXtendのLambdaの実装比較 Java final JTextField textField = new JTextField(); textFeild.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ textField.text=“Something happend”); }}); Xtend val textField = new JTextField textField.addActionListener([ActionEvent e | textField.text = “Something happned” ]) 282014/3/31 SEA関西プロセス分科会 これも省略可
  • 29. ?2014 Shintaro Hosoai Lambda(2) ? [a, b | a.length – b.length] <二引数の関数の場合 ? 変数への代入も可能 ? val myFunction = [Type a | a.doAnything()] ? コレクションにももちろん利用可能 ? 予め便利なメソッド群がExtension Methodとして追 加されている ? forEach((T)=>void Procedure) : void ? map((T)=>R Transformation) : List<R> ? filter((T)=> Boolean Predicate) : Iteratable<T> ? findFirst((T)=>Boolean Predicate): T ? reduce((T,T)=> T function): T ? などなど. 292014/3/31 SEA関西プロセス分科会
  • 30. ?2014 Shintaro Hosoai Dispatch Methods(1) ? Javaはコンパイル時の型に基づいて,メソッド 呼び出しを決定する.このため,動的に Dispatchできない 左図のような構造で,Dispatcher に MyInterface a = MyClass1(); Dispatcher.dispatch(a); とすると,呼び出しは不 定となる (コンパイルできない) ? 言語AST(Abstract Syntax Tree)へのアクセスは, このようなDispatch Methodが多用される MyInterface MyClass1 MyClass2 Dispatcher dispatch(MyClass1 a) dispatch(MyClass2 b)
  • 31. ?2014 Shintaro Hosoai Dispatch Methods(2) ? Xtendではdispatch キーワードを付与する ことで,Dispatch Method として定義できる ? 次のようなXtext定義を 行った際などは,dispatch を指定するとよい class DispatchSample { def doGenerate(){ val expressions = new ArrayList<Expression> expressions.add(new Add) expressions.add(new Sub) expressions.add(new Mul) expressions.add(new Div) for(e : expressions){ genExpression(e); } } dispatch def genExpression(Add a)'''''' dispatch def genExpression(Sub a)'''''' dispatch def genExpression(Mul a)'''''' dispatch def genExpression(Div a)'''''' } interface Expression{} class Add implements Expression{} class Sub implements Expression{} class Mul implements Expression{} class Div implements Expression{} Expression : Add | Sub | Mul | Div; Add : ...; Sub : ...; Mul : ...; Div : ...; 実際にはDSL のパーサがこ のようにモデ ルを詰めて渡 してくる Xtextで 生成 される AST
  • 32. ?2014 Shintaro Hosoai Extension Methods ? クラスにメソッドを(仮想的に)付け加える ? たとえば.StringにtoFirstUpper()メソッドを加 えたり ? 第一引数を対象の型にしたメソッドはExtension Methodとして呼び出せる ? def extensionCall(String str, Hoge any){ ? str.doSomething() ? } ? “hello”.extensionCall(hogeAny) ←呼び出す時は左 辺のオブジェクトが第一引数として渡される.
  • 33. ?2014 Shintaro Hosoai Extension Imports/Provider ? Xtendには,モデル操作等の便利なユーティリ ティメソッドがExtension Methodのライブラリ として提供されている ? ObjectExtensions (src) ? IterableExtensions (src) ? MapExtensions (src) ? ListExtensions (src) ? CollectionExtensions (src) ? BooleanExtensions (src) ? IntegerExtensions (src) ? FunctionExtensions (src)
  • 34. ?2014 Shintaro Hosoai Active Annotation ? @Property ? 属性に付与することで,private変数とgetter/setter を生成する ? @Property String name ? -> private String _name; String getName(){return _name;} void setName(String name){this._name=name;} ? @Data ? クラスに付与することで,含まれる属性の getter/setter, 属性設定を行うコンストラクタ等を生 成
  • 35. ?2014 Shintaro Hosoai Annotation Type Declaration annotation MyAnnotation { String[] value boolean isTricky = false int[] lotteryNumbers = #[ 42, 137 ] }
  • 36. ?2014 Shintaro Hosoai Enum Type Declaration ? Javaと同じ? enum MyColor { GREEN, BLUE, RED }
  • 37. ?2014 Shintaro Hosoai 演算子とオーバーライド(1) ? Xtendでは,演算子のオーバーライドが可能 ? 演算子に対応するメソッドを定義すると,その 演算子が使われた際に対応するメソッドが呼ば れる. class OperatorOverwrite { String name = “hoge” def operator_plus(OperatorOverwrite e2){ this.name+"::"+e2.name } def static void main(String[] args) { var op1 = new OperatorOverwrite; var op2 = new OperatorOverwrite; print(op1+op2) } } +二項演算子の定義. オーバーライドではある がoverrideではなくdefで 定義する. thisが左辺,引数が右辺. ここでは自身と同じ型を 引数に取っているが,異 なる型でも可能.オー バーロードも可. +二項演算子の呼び出し
  • 38. ?2014 Shintaro Hosoai 演算子とオーバーライド(2) 演算子 対応メソッド名 演算子 対応メソッド名 ! e1 e1.operator_not() e1 == e2 e1.operator_equals(e2) - e1 e1.operator_minus() e1 != e2 e1.operator_notEquals(e2) + e1 e1.operator_plus() e1 === e2 e1.operator_tripleEquals(e2) e1 + e2 e1.operator_plus(e2) e1 !== e2 e1.operator_tripleNotEquals(e2) e1 – e2 e1.operator_minus(e2) e1 < e2 e1.operator_lessThan(e2) e1 * e2 e1.operator_multiply(e2) e1 > e2 e1.operator_greaterThan(e2) e1 / e2 e1.operator_divide(e2) e1 <= e2 e1.operator_lessEqualsThan(e2) e1 % e2 e1.operator_modulo(e2) e1 >= e2 e1.operator_greaterEqualsThan(e2) e1 ** e2 e1.operator_power(e2) e1 -> e2 e1.operator_mappedTo(e2) e1 += e2 e1.operator_add(e2) e1 .. e2 e1.operator_upTo(e2) e1 –= e2 e1.operator_remove(e2) e1 >.. e2 e1.operator_greaterThanDoubleDot( e2) e1 || e2 e1.operator_or(e2) e1 ..<e2 e1.operator_doubleDotLessThan(e2) e1 && e2 e1.operator_and(e2)
  • 39. ?2014 Shintaro Hosoai 演算子とオーバーライド(3) 演算子 対応メソッド名 演算子 対応メソッド名 e1 => e2 e1.operator_equals(e2) e1 <= e2 e1.operator_notEquals(e2) e1 >>> e2 e1.operator_greaterThan(e2) e1 << e2 e1.operator_tripleEquals(e2) e1 <> e2 e1.operator_lessEqualsThan(e2) e1 >> e2 e1.operator_tripleNotEquals( e2) e1 ?: e2 e1.operator_greaterEqualsThan( e2) e1 <<< e2 e1.operator_lessThan(e2) e1 <=> e2 e1.operator_mappedTo(e2)