Anda di halaman 1dari 16

Generator kode

Fase terakhir dalam model compiler adalah code generator. Code generator sebagai input yang
representasi lanjutan dari source program dan hasil sebagai output equivalent dgn target
program. Sesuai gambar 9.1. teknik pembangkit dalam bab ini digunakan sebagai tahap optimasi
sebelum pembangkit code, hal ini disebut compiler “optimizing”.

Chapter 9 Code Generation


(kode pembangkit)

Source intermediate intermediate


Program code code target
program

Gambar. 9.1.
Tujuan secara tradisional membuat pembangkit code secara mencukil. code Output harus benar
dan berkualitas, berarti harus efektiv pengguanan resource dari target mesin. Lebih dari itu
pembangkit code dapat dijalankan penterjemah secara efektif.
Masalah untuk membangkitkan code optimal secara matematika tdk dapat dijalankan. Secara
praktis harus berisi cara-cara heuristik yg membangkitkan produk, tetapi tdk perlu mendapati
code optimal. Pemilihan kode heuristic ini perlu dan dirancang dgn algoritma pembangkit code
yang lebih mudah dan lebih cepat dgn algoritma yg diprkirakan secara serentak.

9.1 persoalan-persoalan dalam merancang code generator

Persoalan-persoalan Seperti memory management, instruction selection, register allocation dan


evaluation order adalah masalah-masalah yang ada dihampir semua code generation. Pada bab
ini, kita akan menjelaskan permasalahan yg umum dlm merancang pembangkitan kode.

Input ke code generator


Input ke pembangkit code terdiri dari representasi source program lanjutan yang menghasilkan
ujung akhir, bersamaan dengan informasi di tabel symbol yg di gunakan untuk menentukan
alamat run-time dari data objek yang ditandai dgn nama pada representasi lanjutan.

Target program
Output dari pembangkitan code adalah target program. Output ini mungkin memiliki bentuk
yang berbeda: bahasa mesin absolut, bahasa mesin relocatable, atau bahasa assembly.
Membuat program bahasa mesin sebagai output memiliki pengembangan yang ditempatkan di
lokasi memori yg tetap dan dieksekusi segera. Program yg kecil dapat di-compil dan dieksekusi
dgn cepat.
Membuat program bahasa mesin yg ditempatkan kembali (modul objek) sebagai output
menizinkan sub-program di-compile secara terpisah. Pengaturan modul objek yg ditmpatkan
kembali bisa di-link bersamaan dan diproses untuk dieksekusi.
Membuat program bahasa assembli sebagai output membuat proses pembangkitan kode mudah.
Kita bisa mengembangkan instruksi simbolik dan menggunakan fasilitas-fasilitas macro dalam
pembangkitan kode. Harga terbayarkan tahapan rakitan setalah pembangkitan kode. Karena
membuat kode rakitan tidak bisa menduplikat tugas-tugas assembler, pilihan ini adalah alternativ
lain khususnya untuk mesin dgn memori yg kecil, dimana kompiler harus memakai pass lainnya.

Memory management
Pemetaan nama dalam source program ke alamat-alamat data objek di memory run-time
dilakukan bersama diujung akhir dan pembangkit code.
Jika kode mesin dibangkitkan, lebel di pernyataan tiga-alamat harus dikonversi ke instruksi
alamat. Proses ini dianalogikan seperti teknik ”backpatching”.

Instruction selection
Pengaturan instruksi dari target mesin menentukan kesulitan instruksi pilihan. Keseragaman dan
kelengkapan set instuksi adalah factor penting. Jika target mesin tidak mendukung setiap tipe
data yang seragam. Kecepatan instruksi dan idiom mesin adalah faktor penting lainnya.Kualitas
dari kode pembangkit ditentukan oleh speed dan size-nya. Contoh, setiap statement tiga-alamat
dgn bentuk x:=y+z, bisa diubah kedlm urutan code.
Mov y,R0 /* proses y ke register R0 */
Add z,R0 /* tambah z ke R0 */
Mov R0,x /* simpan R0 ke x */
Sayangnya, statement-statement kode pembangkit seperti ini sering salah kode prosedur. Contoh,
statement
a := b + c
d := a + e
akan diterjemahkan kedalam
MOV b,R0
ADD c,R0
MOV R0,a
MOV a,R0
ADD e,R0
MOV R0,d

Pada statement keempat di-redundant, begitu juga yg ketiga jika a bukan kelanjutan yg
digunakan.

Register allocation
Perintah-perintah menyertakan operasi register biasanya untuk memperpendek dan mempercepat
dari pada perintah-perintah tersebut menyertakan operasi di memori. Menggunakan register
sering dibagi lagi kedalam 2 sub-masalah:
- Selama register allocation, kita pilih variabel yang akan kita letakkan di register didalam
sebuah program.
- Kemudian saat fase register assignment, kita angkat register yang khusus itu yang akan
diletakkan variabel didalamnya.

Secara matematis, masalahnya adalah NP-complete. Maslahnya lebih rumit karena hardware
dan/atau operating system target mesin yg mungkin membutuhkan aturan register-usage tertentu
untuk diamati.

Mesin-mesin tertentu meminta register-pairs untuk beberapa operasi dan hasil. Contoh, pd mesin
IBM system/370

Choice of evaluation order


Pesanan dimana proses perhitungan dilakukan bisa mempengaruhi efisiensi target code.
Awalnya, kita seharusnya menghindari masalah dengan me-generat code untuk stetmen three-
address, selama pesanan yang mereka telah dibuat oleh code generator lanjutan.

Approaches to code generation


Tidak diragukan lagi bahwa ukuran yang terpenting untuk code generator adalah peng-code-an
yang benar.

9.2 target mesin


Pada bab ini, kita akan guanakan target computer sebagai mesin register yang mewakili beberapa
minikomputer. Biargimanapun teknik code-generation dijelaskan di bab ini telah digunakan pada
kelas-kelas mesin lain.

Instruction costs
Contoh:
1. instruksi MOV R0,R1 copy isi yg ada di register R0 ke register R1. insstruksi ini memiliki
nilai satu, sejak itu menempati satu kata dr memori.
2. instruksi ADD #1,R3 menambah constanta 1 ke isi dr register 3, dan memiliki nilai dua, sejak
konstanta 1 harus muncul di kata selanjutnya mengikuti instruksinya.

9.3 run-time storage management


Informasi dibutuhkan selama eksekusi dr suatu prosedur disimpan di blok penyimpanan yang
memanggil aktivasi record; penyimpanan untuk nama local ke prosedur juga kelihatan pd saat
melakukan record.
Saat run-time alokasi dan dealokasi melakukan record terjadi sebagai bagian dari prosedur
rangkaian call dan return, kita focus pd three-address statements berikut:
1. call,
2. return,
3. halt, dan
4. action, suatu tempat untuk statement lainnya.

9.4 basic blocks and flow graphs


Sebuah graph mewakili statement three-address, yang disebut alur graph(flow graph), digunakan
untuk menjelaskan algoritma code-generator, bahkan jika graph tidak dibuat dengan tegas oleh
algoritma code-generator. Node-node menjelalaskan proses computasi, dan edge-edge
manjelaskan arah alur.
Basic blocks
Basic blok adalah sebuah rangkaian statement yang dpt memutuskan dimana arah alur masuk
saat mulai dan keluar saat akhir.

Transformations on basic blocks


Basic blok menghitung suatu set ekspresion. Ekspresion tersebut berupa nilai dr nama blok. Dua
basic blok dinyatakan equivalen jika melakukan suatu set ekspresion yg sama. Bilangan dr
trnsformasi bisa diterapkan ke sebuah basic blok tanpa merubah set ekspresion hitung oleh blok.

Structure-preserving transformations
Srtucture-preserving transformation yg utama pd basic blok adalah:
1. common subexpression elimination
2. dead-code elimination
3. renaming of temporary variables
4. interchange of two independent adjacent statements

Algebraic transformation
Transformation aljabar bisa digunakan untuk merubah set ekspresion yg dihitung oleh sebuah
basic blok kedalam set equivalent aljabar.
Contoh:
x:= x + 0
or
x:= x * 1
bisa dieliminasi dari block dasar tanpa mengganti set kalimat penghitungan itu. Operasi
eksponen pada statement
x:= y ** 2
biasanya permintaan fungsi call untuk diimplementasi. Dengan transformasi aljabar, statement
ini bisa diganti dgn murah, tapi statement equivalen
x:= y * y

Flow graphs
Kita bisa menambahkan informasi arah alur ke set basic blok yg dpt meningkatkan program
dengan membuat arah graph yg disebut flow graph. Node-node dr flow graph adlah basic blok.
Satu node dibedakan sebagai inisial; blok yg pertama adalah statement yang pertama.

Representation of basic bloks


Basic blok dapat direpresentasikan oleh struktur data yg berbeda.

Loops
Loop adalah kumpulan node-node dalm flow graph. Loop yg berisi tdk lain loop disebut inner
loop.

9.5 Next-Use Information


Pada bagian ini,kami kumpulkan informasi yg digunakan tentang nama-nama di dasar blok. Jika
nama di register tidak lagi diperlukan, maka register dapat diberi nama lain. Ide ini, nama dalam
penyimpanan hanya jika akan digunakan kemudian dapat diterapkan dalam sejumlah konteks.
kode generator yang sederhana di bagian selanjutnya berlaku untuk tugas register. Sebagai akhir
aplikasi, kami mempertimbangkan tugas penyimpanan sementara untuk nama.

Penyimpanan untuk nama yg sementara


walaupun mungkin berguna dalam mengoptimalkan kompiler untuk membuat nama sementara
yang berbeda setiap kali diperlukan, ruang harus dialokasikan untuk memegang nilai-nilai
temporaries. ukuran field yg sementara dlm aktivasi umum yg dicatatan pd bagian 7,2 tumbuh
dengan jumlah sementara.
Umumnya,kumpulan dua temporariries kedalam lokasi yg sama jika tdak berlangsung secara
simulta.
Kita bisa menempatkan lokasi penyimpanan untuk sementara oleh masing-masing secara
bergantian memeriksa dan menugaskan sementara ke lokasi yang pertama di lapangan untuk
temporaries yang tidak berisi tinggal sementara. jika sementara tidak dapat diberikan ke setiap
lokasi dibuat sebelumnya, tambahkan ke lokasi baru data daerah untuk prosedur saat ini. dalam
banyak kasus, temporaries dapat dikemas ke dalam register daripada memori lokasi.

9.6 A Simple Code generator


Contoh, kita asumsikan; untuk setiap operasi statement ada sesuai target bahasa operator. Kita
juga asumsikan bahwa hasil penghitungan bisa dapat dibiarkan dalam register selama mungkin,
mereka hanya menyimpan (a) jika register diperlukan untuk komputasi lain atau (b) hanya
sebelum prosedure call, jump atau pernyataan berlabel.
Kondisi (b) menunjukkan bahwa semuanya harus disimpan sebelum akhir dasar blok.

Register dan deskripsi Alamat


Algoritma Kode pembangkit menggunakan descriptors untuk melacak konten register dan alamat
untuk nama.
1. register melacak keterangan atas apa yang sedang disetiap register. berkonsultasi ketika ia
baru register diperlukan. Kami menganggap bahwa pada awalnya register keterangan
menunjukkan bahwa semua register yg kosong.Sebagai kode pembangkit blok
berlangsung.masing-masing register akan memegang nilai nol atau lebih nama pada suatu waktu.
2. keterangan alamat melacak lokasi dimana nama nilai bisa ditemukan saat dijalankan. Lokasi
mungkin di register, tumpukan lokasi, memori alamat atau beberapa set ini, sejak saat disalin,
nilai juga tetap di mana itu berada. informasi ini dapat disimpan dalam tabel simbol dan
digunakan untuk menentukan metode untuk mengakses nama.

Algoritma Code generation


Algoritma code pembangkit mengambil sebagai masukan yang urutan tiga alamat dasar
pernyataan constituting blok. untuk setiap tiga alamat-pernyataan dalam bentuk x:= y kami
melakukan tindakan berikut:
1. memohon fungsi getreg untuk menentukan lokasi di mana L hasil penghitungan y op z harus
disimpan.
2. berkonsultasi dengan alamat dan keterangan untuk menentukan y '. register lebih memilih
untuk y 'jika nilai y saat ini baik dalam memori dan register. jika nilai y belum di L,
menghasilkan instruksi MOV y', L untuk menempatkan salinan y di L.
3. menghasilkan instruksi op z’ , L dimana z’ adalah lokasi z. lagi, lebih suka mendaftar ke
lokasi memori jika z dalam keduanya. memperbarui alamat keterangan of x untuk menunjukkan
bahwa x adalah di lokasi L.
4. jika saat ini nilai-nilai y and/or z tidak menggunakan keluar, tidak tinggal di keluar dari blok,
dan berada dalam register, mengubah register keterangan untuk menunjukkan bahwa, setelah
pelaksanaan x:= y op z, register yang tidak lagi akan mengandung y and/or z, masing-masing.
Yang dimaksud kode generator disini adalah sebuah aplikasi yang digunakan untuk membuat
sebuah project. Adapun tujuan utamanya ialah untuk menghemat waktu, tenaga, dan biaya
sedangkan tujuan lainnya yang tidak kalah penting adalah kecepatan.

Kode generator sangat baik sekali digunakan untuk men-generate aplikasi-aplikasi database,
karena aplikasi database hampir memliki kode-kode yang sama (insert-update-delete-dsb) hanya
objeknya saja yang berbeda. Maka jika kita ingin membuat belasan aplikasi database dengan
objek yang berbeda, pembuatan kode generator dengan rancangan yang baik sangat layak untuk
dipertimbangkan.

Hanya sebagai contoh saja, Anda dapat mendownload kode generator yang kurang baik disini.
Walaupun kurang baik, tapi coba perhatikan apakah keistimewaanya?

Membuat aplikasi kode generator, tentunya harus memiliki kemampuan menambahkan


sembarang OCX dan referensi DLL yang support VB6.0. Bagaimanakah caranya? Di bawah ini
merupakan potongan dari kode generator tersebut, gunanya untuk menambahkan referensi DLL
dan OCX.
'----------------------------------------------------------------------------
---
'http://khoiriyyah.blogspot.com
'Asep Hibban
'----------------------------------------------------------------------------
---

Public VBInstance As VBIDE.VBE


Public Connect As Connect

Option Explicit

Public Function InsertOCX(ProgID As String) As Boolean


On Error GoTo ErrHandler
'Add OCX
VBInstance.ActiveVBProject.AddToolboxProgID ProgID
InsertOCX = True
Exit Function ErrHandler:
InsertOCX = False
End Function

Public Function InsertReferences(GUID As String, Mayor As Long, Minor As


Long) As Boolean
On Error GoTo ErrHandler
'Add dll references
VBInstance.ActiveVBProject.References.AddFromGuid GUID, Mayor, Minor
InsertReferences = True ErrHandler:
InsertReferences = False
End Function

Private Sub Command1_Click()


'Add ListView to VB6 project
InsertOCX "{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}"
'Add TreeView
InsertOCX "{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}"
'Add MSFlexGrid
InsertOCX "{0ECD9B60-23AA-11D0-B351-00A0C9055D8E}"
End Sub

Private Sub Command2_Click()


'Add scrun.dll Microsoft Scripting Runtime)
InsertReferences "{420B2830-E718-11CF-893D-00A0C9054228}", 1#, 0
'Add msado15.dll Microsoft ActiveX Data Objects 2.8 Library)
InsertReferences "{2A75196C-D9EB-4129-B803-931327F72D5C}", 2, 8
End Sub
1. Penggunaan Gii
2. Meningkatkan Gii

Mulai dari versi 1.1.2, Yii sudah dilengkapi dengan sebuah code generator berbasis Web yang
disebut Gii. Tool ini menggantikan tool sebelumnya yakni yiic shell yang berjalan di
command line. Di bagian ini, kita akan melihat bagaimana menggunakan Gii dan cara
meningkatkan(mengembangkan) kemampuan Gii untuk mendongkrak produktivitas
pengembangan.

1. Penggunaan Gii
Gii diimplementasi sebagai module dan harus digunakan di dalam aplikasi Yii. Untuk
menggunakan Gii, kita pertama-tama memodifikasi konfigurasi aplikasi sebagai berikut:

return array(
......
'modules'=>array(
'gii'=>array(
'class'=>'system.gii.GiiModule',
'password'=>'masukkan password di sini',
// 'ipFilters'=>array(...a list of IPs...),
// 'newFileMode'=>0666,
// 'newDirMode'=>0777,
),
),
);

Pada kode di atas, kita mendeklarasi sebuah module bernama gii yang merupakan instance dari
kelas GiiModule. Kita juga menentukan sebuah password untuk module yang akan ditanyakan
ketika mengakses Gii.

Secara default, Gii diatur supaya hanya dapat diakses di localhost saja demi alasan keamanan.
Jika kita ingin membuatnya dapat diakses di komputer lain yang sudah dipercaya, kita dapat
mengaturnya di properti Gii::ipFilters seperti yang ditunjukkan di kode di atas.

Karena Gii bisa dihasilkan dan menyimpan file kode baru di dalam aplikasi yang sudah ada, kita
harus memastikan bahwa proses Web Server memiliki pengaturan izin(permission) yang benar.
Properti Gii:Module::newFileMode dan GiiModule::newDirMode mengatur bagaimana file dan
direktori baru harus dihasilkan.

Catatan: Gii disediakan hanya untuk sebagai tool untuk dalam tahap pengembangan. Oleh
karena itu, harap diinstal di komputer tempat pengembangan(development). Dikarenakan Gii
bisa menghasilkan file PHP baru di dalam aplikasi, kita harus lebih memperhatikan secara
khusus mengenai penanganan masalah keamanan (misalnya password, IP Filter).

Kita dapat menggunakan Gii dengan URL http://hostname/path/to/index.php?r=gii. Di


sini kita mengasumsi http://hostname/path/to/index.php merupakan URL untuk
mengakses aplikasi Yii yang sudah ada.
Jika aplikasi Yii yang sudah ada menggunakan URL format path (lihat URL management), kita
dapat mengakses Gii dengan URL http://hostname/path/to/index.php/gii. Kita perlu
menambah aturan URL berikut di depan aturan URL yang sudah ada:

'components'=>array(
......
'urlManager'=>array(
'urlFormat'=>'path',
'rules'=>array(
'gii'=>'gii',
'gii/<controller:\w+>'=>'gii/<controller>',
'gii/<controller:\w+>/<action:\w+>'=>'gii/<controller>/<action>',
...existing rules...
),
),
)

Gii dilengkapi dengan beberapa code generator(kode penghasil). Setiap code generator
bertanggung jawab untuk menghasilkan kode dengan jenis tertentu. Misalnya, untuk controller
generator menghasilkan sebuah kelas controller dengan beberapa skrip aksi view(action view);
model generator menghasilkan kelas ActiveRecord (rekaman aktif) sesuai tabel database yang
sudah ditentukan.

Pada dasarnya urutan menggunakan generator sebagai berikut:

1. Masuk ke halaman generator;


2. Isi field yang menspesifikasi parameter penghasil kode. Misalnya untuk memakai module
generator yang berfungsi menghasilkan module baru, Anda harus menspesifikasi ID
module;
3. Tekan Preview untuk melihat kode yang dihasilkan. Anda akan melihat sebuah tabel
menampilkan daftar file kode yang akan dihasilkan. Anda dapat mengklik salah satu dari
daftar tersebut untuk melihat isi kode;
4. Tekan tombol Generate untuk menghasilkan file-file kode tersebut;
5. Perhatikan catatan proses penghasilan kode (code generation log).

2. Meningkatkan Gii
Walaupun secara default, code generator yang dari Gii dapat menghasilkan kode yang sangat
powerful, kita sering perlu menyesuaikan code generator tersebut atau membuat yang baru
supaya sesuai dengan keperluan dan selera kita. Misalnya, kita ingin menghasilkan kode yang
menjadi gaya koding kita sendiri, atau kita ingin kode kita mendukung berbagai bahasa.
Semuanya dapat dilakukan dengan Gii secara mudah.

Gii dapat ditingkatkan dengan dua cara: mengubah templat kode(code template) yang sudah ada,
dan menulis code generator yang baru.

Struktur dari Code Generator


Sebuah code generator disimpan dalam sebuah direktori yang namanya diperlakukan sebagai
nama generator. Direktori biasanya terdiri dari isi berikut:

model/ folder root dari model generator


ModelCode.php kode model yang digunakan untuk menghasilkan
kode
ModelGenerator.php controller dari code generator
views/ berisi skrip tilik(view) untuk generator
index.php default dari skrip tilik
templates/ berisi kumpulan templat(template) kode
default/ kumpulan template kode 'default'
model.php kode templat untuk menghasilkan kode kelas model

Jalur Pencarian Generator(Generator Search Path)

Gii mencari generator yang tersedia di dalam kumpulan direktori yang ditentukan oleh properti
GiiModule::generatorPaths. Ketika diperlukan kustomisasi, kita dapat mengatur properti ini
dalam konfigurasi aplikasi sebagai berikut,

return array(
'modules'=>array(
'gii'=>array(
'class'=>'system.gii.GiiModule',
'generatorPaths'=>array(
'application.gii', // sebuah alias path
),
),
),
);

Konfigurasi di atas menginstruksi Gii untuk mencari generator yang terletak di dalam direktori
dengan alias application.gii, sebagai tambahan bagi lokasi default system.gii.generators.

Dimungkinkan untuk memiliki dua generator dengan nama yang sama namun memiliki jalur
pencarian(search path) yang berbeda. Kalau terjadi, generator di dalam jalur yang sudah
ditentukan pada waktu awal di GiiModule::generatorPaths akan didahulukan.

Mengkustomisasi Template Kode

Ini merupakan langkah termudah dan paling umum untuk mengembangkan Gii. Kita gunakan
sebuah contoh untuk memahami bagaimana mengkustomisasi templat kode. Misalkan kita ingin
mengkustomisasi sebuah kode yang dihasilkan oleh model generator.

Pertama-tama kita membuat sebuah direktori dengan nama


protected/gii/model/templates/compact. Di sini model artinya kita akan meng-override
default model generator. Dan templates/compatct artinya kita akan menambah kumpulan
templat kode bernama compact
Kemudian kita mengubah konfigurasi aplikasi dengan menambah application.gii ke
GiiModule::generatorPaths, seperti yang ditunjukkan pada sub-bagian sebelumnya.

Sekarang buka halaman code generator model. Klik di field Code Template. Kita akan melihat
sebuah dropdown list yang berisi direktori templat yang baru kita buat, compact. Akan tetapi,
jika kita memilih templat ini untuk menghasilkan kode, kita akan menjumpai sebuah error
dikarenakan kita belum meletakkan kode apapun ke dalam file templat di compact.

Salin(copy) file framework/gii/generators/model/templates/default/model.php ke


protected/gii/model/templates/compact. Jika kita mencoba menghasilkan koding dengan
templat compact, seharusnya akan sukses. Tetapi, kode yang dihasilkan tidak akan berbeda
dengan yang dihasilkan oleh default.

Saatnya kita melakukan kustomisasi sesungguhnya. Buka file


protected/gii/model/templates/compact/model.php untuk meng-edit-nya. Ingat bahwa
file ini akan digunakan seperti skrip tilik(view), yang artinya akan mengandung expression dan
statement PHP. Sekarang kita ubah templat sehingga metode attributeLabels() di kode yang
dihasilkan menggunakan Yii::t() untuk menerjemahkan label atribut:

public function attributeLabels()


{
return array(
<?php foreach($labels as $name=>$label): ?>
<?php echo "'$name' => Yii::t('application', '$label'),\n"; ?>
<?php endforeach; ?>
);
}

Di masing-masing templat kode, kita dapat mengakses beberapa variabel yang sudah
didefinisikan sebelumnya, seperti $labels di contoh di atas. Varaibel ini disediakan oleh
generator kode yang bersangkutan. Generator kode yang berbeda akan menghasilkan variabel-
variable yang berbeda di templat kode. Silahkan baca dengan teliti deskripsi di dalam templat
kode default.

Membuat Generator baru

Di dalam sub-bab beriktu, kita akan melihat bagaimana membuat sebuah generator baru dapat
menghasilkan kelas widget yang baru.

Pertama kita membuat sebuah direktori bernama protected/gii/widget. Di dalam direktori,


kita akan membuat file-file berikut:

 WidgetGenerator.php: berisi kelas kontroller WidgetGenerator. Kelas ini merupakan


titik awal untuk generator widget.
 WidgetCode.php: berisi kelas model WidgetCode. Kelas ini memiliki logika utama untuk
menghasilkan kode
 views/index.php: skrip tilik(view) untuk menampilkan input form dari code generator
 templates/default/widget.php: kode templat default untuk menghasilkan sebuah file
kelas widget.

Membuat WidgetGenerator.php

File WidgetGenerator.php sebetulnya sangat sederhana. File ini hanya berisi kode berikut:

class WidgetGenerator extends CCodeGenerator


{
public $codeModel='application.gii.widget.WidgetCode';
}

Di dalam kode di atas, kita menetapkan bahwa generator akan menggunakan kelas model yang
alias pathnya adalah application.gii.widget.WidgetCode. Kelas WidgetGenerator
diturunkan dari CCodeGenerator yang mengimplementasi berbagai fungsionalitas, termasuk
aksi(action) dari kontroller yang diperlukan untuk mengkoordinasi dengan proses penghasilan
kode.

Membuat WidgetCode.php

File WidgetCode.php berisi kelas model WidgetCode memiliki logika utama untuk
menghasilkan sebuah kelas widget berdasarkan input dari pengguna. Dalam contoh ini, kita
mengasumsi bahwa input yang akan diterima dari pengguna hanyalah nama kelas widget.
Tampilan WidgetCode akan seperti ini :

class WidgetCode extends CCodeModel


{
public $className;

public function rules()


{
return array_merge(parent::rules(), array(
array('className', 'required'),
array('className', 'match', 'pattern'=>'/^\w+$/'),
));
}

public function attributeLabels()


{
return array_merge(parent::attributeLabels(), array(
'className'=>'Widget Class Name',
));
}

public function prepare()


{
$path=Yii::getPathOfAlias('application.components.' . $this-
>className) . '.php';
$code=$this->render($this->templatepath.'/widget.php');

$this->files[]=new CCodeFile($path, $code);


}
}

Kelas WidgetCode diturunkan dari CCodeModel. Seperti kelas model pada umumnya, sebuah
kelas dapat dideklarasi rules() dan attributeLabels() untuk melakukan validasi input dari
pengguna dan menyediakan label atribut. Harap diingat karena kelas dasar CCodeModel sudah
mendefinisikan beberapa peraturan(rules) dan label atribut, kita harus menggabungkan menjadi
aturan dan label baru di sini.

Metode prepare() akan menyiapkan kode untuk dihasilkan. Fungsi utamanya adalah
menyiapkan daftar dari objek-objek CCodeFile, yang masing-masing mewakili sebuah file kode
yang akan dihasilkan. Di dalam contoh kita, kita hanya perlu membuat sebuah objek CCodeFile
yang mewakili file kelas widget. Kelas widget yang baru akan dihasilkan di dalam direktori
protected/components. Kita memanggil metode CCodeFile::render untuk menghasilkan kode
sebenarnya. Metode ini menyertakan templat kode sebagai skrip PHP dan mengembalikan isi
yang di-echo sebagai kode.

Membuat views/index.php

Setelah memiliki kontroller (WidgetGenerator) dan model (WidgetCode), maka selanjutnya


adalah membuat tilik views/index.php.

<h1>Widget Generator</h1>

<?php $form=$this->beginWidget('CCodeForm', array('model'=>$model)); ?>

<div class="row">
<?php echo $form->labelEx($model,'className'); ?>
<?php echo $form->textField($model,'className',array('size'=>65)); ?>
<div class="tooltip">
Widget class name must only contain word characters.
</div>
<?php echo $form->error($model,'className'); ?>
</div>

<?php $this->endWidget(); ?>

Pada kode di atas, kita menampilkan sebuah form menggunakan widget CCodeForm. Di dalam
form ini, kita menampilkan field untuk mendapatkan input dari atribut className di
WidgetCode.

Ketika membuat form, kita dapat memanfaatkan dua fitur yang disediakan oleh
widgetCCodeForm. Yang satu untuk memasukkan tooltips, dan yang satu lagi untuk sticky input.

Jika pernah mencoba code generator default, Anda pasti akan menyadari bahwa ketika kita
meletakkan fokus pada satu input field, sebuah tooltip yang bagus akan tampil di sebelah field.
Efek seperti ini bisa didapatkan dengan mudah dengan menulis di sebelah input field sebuah div
yang kelas CSS nya adalah tooltip.
Pada beberapa field input, kita mungkin ingin mengingat nilai valid sebelumnya sehingga
pengguna tidak perlu memasukkannya lagi setiap kali ingin menggunakan generator untuk
menghasilkan kode. Contohnya adalah input field yang meminta nama kelas dasar kontroller
pada controller generator. Sticky field ini pada awalnya ditampilkan sebagai teks statik yang
disorot. Jika kita mengkliknya, mereka akan berubah menjadi input field yang mengambil
inputan pengguna.

Untuk mendeklarasi sebuah input field menjadi sticky, kita perlu melakukan dua hal.

Pertama, kita perlu mendeklarasi sebuah aturan validasi sticky untuk atribut model yang
bersangkutan. Misalnya, controllger generator default memiliki aturan bahwa atribut baseClass
dan actions menjadi sticky:

public function rules()


{
return array_merge(parent::rules(), array(
......
array('baseClass, actions', 'sticky'),
));
}

Kedua, kita akan menambah sebuah kelas CSS yang bernama sticky ke dalam div dari input
field dalam di tilik, seperti berikut ini:

<div class="row sticky">


...masukkan input field ke sini...
</div>

Pembuatan templates/default/widget.php

Terakhir, kita membuat sebuah templat kode templates/default/widget.php. Seperti yang


dideskripsi pada awal tadi, file ini seperti sebuah skrip tilik yang dapat menampung expression
dan statement PHP. Di dalam templat kode, kita akan selalu mengakses variabel $this yang
ditujukan ke objek model kode. Di dalam contoh, $this merujuk ke objek WidgetModel. Kita
dapat mengambil nilai nama kelas yang dimasukkan pengguna dengan cara $this->className.

<?php echo '<?php'; ?>

class <?php echo $this->className; ?> extends CWidget


{
public function run()
{

}
}

Langkah ini mengakhiri proses pembuatan code generator yang baru. Kita dapat mengakses code
generator ini dengan segera melakui URL
http://hostname/path/to/index.php?r=gii/widget.

Anda mungkin juga menyukai