[svn] r7727: nemerle/trunk/snippets/aop: . makefile mgr mgr/make.bat mgr/praca.tex src src/dev_macros src/...

Luntain svnadmin at nemerle.org
Sun Jul 1 15:23:13 CEST 2007


Log:
add aop to repository, needs some more work though

Author: Luntain
Date: Sun Jul  1 15:23:10 2007
New Revision: 7727

Added:
   nemerle/trunk/snippets/aop/   (props changed)
   nemerle/trunk/snippets/aop/makefile
   nemerle/trunk/snippets/aop/mgr/   (props changed)
   nemerle/trunk/snippets/aop/mgr/make.bat
   nemerle/trunk/snippets/aop/mgr/praca.tex
   nemerle/trunk/snippets/aop/src/
   nemerle/trunk/snippets/aop/src/dev_macros/
   nemerle/trunk/snippets/aop/src/dev_macros/parser_operators.n
   nemerle/trunk/snippets/aop/src/ftests/
   nemerle/trunk/snippets/aop/src/ftests/2_aspects_positive.n
   nemerle/trunk/snippets/aop/src/ftests/Target_positive.n
   nemerle/trunk/snippets/aop/src/ftests/after/
   nemerle/trunk/snippets/aop/src/ftests/after/after_positive.n
   nemerle/trunk/snippets/aop/src/ftests/after/returning_positive.n
   nemerle/trunk/snippets/aop/src/ftests/after/throwing_positive.n
   nemerle/trunk/snippets/aop/src/ftests/after/throwing_with_parm_positive.n
   nemerle/trunk/snippets/aop/src/ftests/after/without_returning_positive.n
   nemerle/trunk/snippets/aop/src/ftests/args/
   nemerle/trunk/snippets/aop/src/ftests/args/args_positive.n
   nemerle/trunk/snippets/aop/src/ftests/args/elipsis_positive.n
   nemerle/trunk/snippets/aop/src/ftests/args/just_args_positive.n
   nemerle/trunk/snippets/aop/src/ftests/args/property_setter_positive.n
   nemerle/trunk/snippets/aop/src/ftests/args/var_binding_and_invocation_positive.n
   nemerle/trunk/snippets/aop/src/ftests/args/var_binding_positive.n
   nemerle/trunk/snippets/aop/src/ftests/around/
   nemerle/trunk/snippets/aop/src/ftests/around/around_positive.n
   nemerle/trunk/snippets/aop/src/ftests/around/around_void_positive.n
   nemerle/trunk/snippets/aop/src/ftests/around/proceed_positive.n
   nemerle/trunk/snippets/aop/src/ftests/around/proceed_with_args_positive.n
   nemerle/trunk/snippets/aop/src/ftests/around/proceed_with_target_positive.n
   nemerle/trunk/snippets/aop/src/ftests/before/
   nemerle/trunk/snippets/aop/src/ftests/before/before_positive.n
   nemerle/trunk/snippets/aop/src/ftests/before/with_args_positive.n
   nemerle/trunk/snippets/aop/src/ftests/class_pattern/
   nemerle/trunk/snippets/aop/src/ftests/class_pattern/ellipsis_positive.n
   nemerle/trunk/snippets/aop/src/ftests/class_pattern/member_classes_positive.n
   nemerle/trunk/snippets/aop/src/ftests/class_pattern/namespace_matters_positive.n
   nemerle/trunk/snippets/aop/src/ftests/class_pattern/subtype_external_interface_positive.n
   nemerle/trunk/snippets/aop/src/ftests/class_pattern/subtype_interface_positive.n
   nemerle/trunk/snippets/aop/src/ftests/class_pattern/subtypes_positive.n
   nemerle/trunk/snippets/aop/src/ftests/class_pattern/takes_using_into_consideration_positive.n
   nemerle/trunk/snippets/aop/src/ftests/class_pattern/weave_two_classes_positive.n
   nemerle/trunk/snippets/aop/src/ftests/id_pattern/
   nemerle/trunk/snippets/aop/src/ftests/id_pattern/star_positive.n
   nemerle/trunk/snippets/aop/src/ftests/method_constructor_pattern/
   nemerle/trunk/snippets/aop/src/ftests/method_constructor_pattern/attribute_positive.n
   nemerle/trunk/snippets/aop/src/ftests/method_constructor_pattern/ctor_positive.n
   nemerle/trunk/snippets/aop/src/ftests/method_constructor_pattern/meth_pattern_with_ret_negative.n
   nemerle/trunk/snippets/aop/src/ftests/method_constructor_pattern/meth_pattern_with_ret_type_positive.n
   nemerle/trunk/snippets/aop/src/ftests/method_constructor_pattern/no_method_negative.n
   nemerle/trunk/snippets/aop/src/ftests/method_constructor_pattern/non-existent-class_negative.n
   nemerle/trunk/snippets/aop/src/ftests/method_constructor_pattern/param_positive.n
   nemerle/trunk/snippets/aop/src/ftests/method_constructor_pattern/params_positive.n
   nemerle/trunk/snippets/aop/src/ftests/method_constructor_pattern/property_asterix_positive.n
   nemerle/trunk/snippets/aop/src/ftests/method_constructor_pattern/property_positive.n
   nemerle/trunk/snippets/aop/src/ftests/method_constructor_pattern/static_positive.n
   nemerle/trunk/snippets/aop/src/ftests/method_constructor_pattern/type_with_namespace_in_ret_positive.n
   nemerle/trunk/snippets/aop/src/ftests/method_constructor_pattern/visibility_attributes_positive.n
   nemerle/trunk/snippets/aop/src/ftests/no_aspect_negative.n
   nemerle/trunk/snippets/aop/src/ftests/not_change_ret_value.n
   nemerle/trunk/snippets/aop/src/ftests/or_and_operators/
   nemerle/trunk/snippets/aop/src/ftests/or_and_operators/2_ors_pointcut_positive.n
   nemerle/trunk/snippets/aop/src/ftests/or_and_operators/and_pointcut_positive.n
   nemerle/trunk/snippets/aop/src/ftests/or_and_operators/not_pointcut_positive.n
   nemerle/trunk/snippets/aop/src/ftests/or_and_operators/or_et_and_pointcut_positive.n
   nemerle/trunk/snippets/aop/src/ftests/or_and_operators/or_pointcut_positive.n
   nemerle/trunk/snippets/aop/src/ftests/param_polym/
   nemerle/trunk/snippets/aop/src/ftests/param_polym/polym_after_positive.n
   nemerle/trunk/snippets/aop/src/ftests/param_polym/polym_around_positive.n
   nemerle/trunk/snippets/aop/src/ftests/param_polym/polym_before_positive.n
   nemerle/trunk/snippets/aop/src/ftests/parentheses_positive.n
   nemerle/trunk/snippets/aop/src/ftests/target/
   nemerle/trunk/snippets/aop/src/ftests/target/polym_target_positive.n
   nemerle/trunk/snippets/aop/src/ftests/target/target_primitive_pointcut_positive.n
   nemerle/trunk/snippets/aop/src/ftests/target/target_type_of_object_positive.n
   nemerle/trunk/snippets/aop/src/ftests/target/target_type_positive.n
   nemerle/trunk/snippets/aop/src/ftests/type_pattern/
   nemerle/trunk/snippets/aop/src/ftests/type_pattern/advice_parametrs_to_typepattern_positive.n
   nemerle/trunk/snippets/aop/src/ftests/type_pattern/arrays_positive.n
   nemerle/trunk/snippets/aop/src/ftests/type_pattern/arrow_positive.n
   nemerle/trunk/snippets/aop/src/ftests/type_pattern/exact_type_positive.n
   nemerle/trunk/snippets/aop/src/ftests/type_pattern/generics_positive.n
   nemerle/trunk/snippets/aop/src/ftests/type_pattern/paretheses_positive.n
   nemerle/trunk/snippets/aop/src/ftests/type_pattern/subtype_and_typeparms_positive.n
   nemerle/trunk/snippets/aop/src/ftests/type_pattern/subtype_funtypes_positive.n
   nemerle/trunk/snippets/aop/src/ftests/type_pattern/subtyping_positive.n
   nemerle/trunk/snippets/aop/src/ftests/type_pattern/tuples_positive.n
   nemerle/trunk/snippets/aop/src/helper/
   nemerle/trunk/snippets/aop/src/helper/Advice.n
   nemerle/trunk/snippets/aop/src/helper/AdviceMethod.n
   nemerle/trunk/snippets/aop/src/helper/AdviceParameter.n
   nemerle/trunk/snippets/aop/src/helper/Advices.n
   nemerle/trunk/snippets/aop/src/helper/AndPointcut.n
   nemerle/trunk/snippets/aop/src/helper/ArgsPointcut.n
   nemerle/trunk/snippets/aop/src/helper/ConstructorPattern.n
   nemerle/trunk/snippets/aop/src/helper/ErrorPipe.n
   nemerle/trunk/snippets/aop/src/helper/ExecutionPointcut.n
   nemerle/trunk/snippets/aop/src/helper/GapMatching.n
   nemerle/trunk/snippets/aop/src/helper/IdPattern.n
   nemerle/trunk/snippets/aop/src/helper/Invocation.n
   nemerle/trunk/snippets/aop/src/helper/Joinpoint.n
   nemerle/trunk/snippets/aop/src/helper/LazyList.n
   nemerle/trunk/snippets/aop/src/helper/Lexer.n
   nemerle/trunk/snippets/aop/src/helper/MatchResult.n
   nemerle/trunk/snippets/aop/src/helper/MemberPattern.n
   nemerle/trunk/snippets/aop/src/helper/MethodPattern.n
   nemerle/trunk/snippets/aop/src/helper/NegPointcut.n
   nemerle/trunk/snippets/aop/src/helper/OrPointcut.n
   nemerle/trunk/snippets/aop/src/helper/Parameters.n
   nemerle/trunk/snippets/aop/src/helper/Parse.n
   nemerle/trunk/snippets/aop/src/helper/ParserCombinators.n
   nemerle/trunk/snippets/aop/src/helper/PatternResolver.n
   nemerle/trunk/snippets/aop/src/helper/Pointcut.n
   nemerle/trunk/snippets/aop/src/helper/PropertyJoinpoint.n
   nemerle/trunk/snippets/aop/src/helper/PropertyPattern.n
   nemerle/trunk/snippets/aop/src/helper/ReturnsPointcut.n
   nemerle/trunk/snippets/aop/src/helper/RootPointuct.n
   nemerle/trunk/snippets/aop/src/helper/TargetPointcut.n
   nemerle/trunk/snippets/aop/src/helper/TypePattern.n
   nemerle/trunk/snippets/aop/src/helper/VariableBinding.n
   nemerle/trunk/snippets/aop/src/macros/
   nemerle/trunk/snippets/aop/src/macros/aspect.n
   nemerle/trunk/snippets/aop/src/macros/macros.n
   nemerle/trunk/snippets/aop/src/utests/
   nemerle/trunk/snippets/aop/src/utests/advices.n
   nemerle/trunk/snippets/aop/src/utests/gap_matching.n
   nemerle/trunk/snippets/aop/src/utests/helper.n
   nemerle/trunk/snippets/aop/src/utests/id_pattern/
   nemerle/trunk/snippets/aop/src/utests/id_pattern/IdPattern.n
   nemerle/trunk/snippets/aop/src/utests/lexing.n
   nemerle/trunk/snippets/aop/src/utests/parsing.n
   nemerle/trunk/snippets/aop/src/utests/singleton.n

Added: nemerle/trunk/snippets/aop/makefile
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/aop/makefile	Sun Jul  1 15:23:10 2007
@@ -0,0 +1,61 @@
+
+# I use only nunit vars, I don't know how to utilize others yet
+include ../../config.mak
+
+build: bin bin/DevMacros.dll bin/Nemerle.Aop.dll
+
+bin/DevMacros.dll: bin src/dev_macros/parser_operators.n 
+	ncc -g -t:library -r Nemerle.Compiler.dll -o:$@\
+		src/dev_macros/parser_operators.n
+
+bin/Nemerle.Aop.dll: bin bin/DevMacros.dll src/macros/*.n src/helper/*.n
+	ncc -g -t:library -r Nemerle.Compiler.dll -m bin/DevMacros.dll -o:$@\
+		src/macros/*.n src/helper/*.n
+
+
+test: utests ftests
+
+# unit tests
+utests: bin/UnitTests.dll
+	cd bin; $(NUNIT_CONSOLE) UnitTests.dll
+
+bin/UnitTests.dll: bin/Nemerle.Aop.dll bin/NemerleUnit.dll src/utests/*.n
+	ncc src/utests/*.n -g -r bin/NemerleUnit.dll -m bin/DevMacros.dll -nowarn:10005 \
+		-o:$@ -t:library -r Nemerle.Compiler.dll -r bin/Nemerle.Aop.dll \
+		$(NUNIT_LIB_FLAG)
+
+bin/NemerleUnit.dll: ../../tools/nemerle-unit/bin/NemerleUnit.dll
+	cp $< bin/NemerleUnit.dll
+
+../../tools/nemerle-unit/bin/NemerleUnit.dll:
+	cd ../../tools/nemerle-unit; make
+
+# functional tests
+ftests: 
+	make functional_tests
+
+# to run a single functional test with verbose param
+# you must give value for NAME var (part of the filename)
+vtest: 
+	make functional_tests ARG=-vv
+
+functional_tests: testbin testbin/test.exe bin/Nemerle.Aop.dll
+	cp {bin,testbin}/Nemerle.Aop.dll
+	cp {../../ncc/out.stage3,testbin}/Nemerle.Macros.dll
+	cd testbin; find ../src/ftests -name  "*$(NAME)*_positive.n" \
+		-exec ./test.exe $(ARG) -ref Nemerle.Aop.dll {} +
+	cd testbin; find ../src/ftests -name "*$(NAME)*_negative.n" \
+		-exec ./test.exe $(ARG) -ref Nemerle.Aop.dll {} +
+
+testbin/test.exe: testbin
+	ncc -o:$@ -r Nemerle.Compiler.dll ../../ncc/testsuite/test.n
+
+bin:
+	mkdir -p bin 
+testbin:
+	mkdir -p testbin
+
+.PHONY: clean build test ftests utests functional_tests
+
+clean:
+	rm -r bin testbin

Added: nemerle/trunk/snippets/aop/mgr/make.bat
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/aop/mgr/make.bat	Sun Jul  1 15:23:10 2007
@@ -0,0 +1,7 @@
+latex praca
+dvips -o praca.ps -Ppdf praca.dvi
+ps2pdf praca.ps
+del praca.ps
+del praca.dvi
+del praca.log
+praca.pdf

Added: nemerle/trunk/snippets/aop/mgr/praca.tex
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/aop/mgr/praca.tex	Sun Jul  1 15:23:10 2007
@@ -0,0 +1,2168 @@
+\documentclass[a4paper,12pt]{mwbk}
+\usepackage[utf8]{inputenc}
+\usepackage{polski}
+\usepackage{listings}
+\lstset{language={[AspectJ]Java},basicstyle=\ttfamily,showstringspaces=false}
+\lstdefinestyle{aspectj}
+    {language={[AspectJ]Java},basicstyle=,showstringspaces=false}
+\renewcommand*\lstlistingname{Przykład}
+
+\author{Kamil Dworakowski}
+\title{Programowanie aspektowe w języku Nemerle}
+\date{\today}
+
+\begin{document}
+\maketitle
+
+\tableofcontents
+
+\chapter{ Wstęp }
+
+    todo
+
+\chapter{Programowanie aspektowe}
+W tym rozdziale postaram się uzasadnić przydatność programowania aspektowego.
+Myślą przewodnią jest to, że języki programowania aspektowego wspierają
+rozdzielanie zagadnień.
+
+\section{Motywacja}
+
+Podczas projektowania system dzieli się na spójne części realizujące pewne
+zadania. Najlepiej jest, kiedy każda część ma swoją dobrze zdefiniowaną
+odpowiedzialność.  Postępuje się w ten sposób, aby ogarnąć duże, skomplikowane
+systemy. Programowanie aspektowe wychodzi temu na przeciw i oferuje nowy
+paradygmat, który rozszerza paradygmat programowania obiektowego. W tym nowym
+paradygmacie można skuteczniej dzielić systemy na spójne moduły.
+
+Ważnym pojęciem dla zrozumienia istoty programowania aspektowego jest
+\emph{zagadnienie przecinające}.  Zagadnienie (ang. \emph{concern}) to
+odpowiedzialność, która ma być realizowana w systemie.  Oczywistymi
+zagadnieniami są wymagania funkcjonalne, ale nie wszystkie zagadnienia w
+systemie muszą wynikać bezpośrednio z wymagań klienta. Przykładem takiego
+zagadnienia jest zwalnianie pamięci w językach bez odśmiecania, jak również 
+zapisywanie interesujących zdarzeń do pliku
+dziennika (ang. \emph{logging}).
+
+Wskazane jest, aby zagadnienie było realizowane przez jeden moduł, bo wtedy łatwo
+jest je pielęgnować.  Mówi się, że zagadnienie jest przecinające, kiedy jego
+realizacja jest rozproszona pomiędzy modułami realizującymi inne zagadnienia.
+Innymi słowy jego kod jest rozproszony po systemie. Tak zazwyczej wygląda
+rejestrowanie wywołań metod w pliku dziennika (ang. \emph{tracing}).  W
+językach obiektowych nie da się tego zmodularyzować. Realizacja tego wymagałaby
+umieszczenia instrukcji zapisującej do pliku na początku i końcu każdej metody,
+która miałaby być śledzona.
+
+To, czy dane zagadnienie jest przecinające w konkretnym systemie, zależy od tego,
+jak jest on podzielony na moduły jak również od użytych języków programowania,
+czy też warstwy pośredniej (ang. \emph{middleware}). Język programowania może
+troszczyć się o pewne zagadnienia za programistę. Przykładem niech tu będzie
+automatyczne odśmiecanie pamięci.  Zwalnianie pamięci w języku \textsc{c++}
+jest zagadnieniem przecinającym, natomiast w języku Java już nie.
+
+Dobrym wskaźnikiem tego, że mamy do czynienia z zagadnieniem przecinającym,
+jest przekonanie, że pomimo rozproszonej implementacji powinno ono być opisane
+w osobnym rozdziale dokumentacji. 
+
+Na przykład, kiedy programista myśli o zagadnieniu rejestrowania wywołań metod,
+jego intencją jest, aby wywołania pewnego zbioru metod były zapisywane w pliku
+dziennika. Idealnie byłoby, gdyby istniała możliwość zapisania tego  jednym miejscu w
+kodzie systemu. W ten sposób implementacja zagadnienia byłaby bliska jego
+intencji.  Jedynie z powodu braku odpowiednich konstrukcji w językach
+obiektowych, implementacja tego prostego zagadnienia (śledzenia wywołań) musi
+być rozsiana po metodach systemu.
+
+Języki obiektowe ułatwiają modularyzację oprogramowania, ponieważ stosunkowo prosto 
+modeluje się w nich rzeczywistość. Niemniej jednak, są zagadnienia, które
+często nie nie dają się łatwo zamknąć w modułach za pomocą konwencjonalnych
+języków programowania. 
+
+Przykładami takich zagadnień są: 
+\begin{itemize*}
+\item rejestrowanie wywołań metod,
+\item synchronizacja,
+\item transakcje,
+\item równoważenie obciążenia (ang. \emph{load balancing}),
+\item ochrona,
+\item reagowanie na zdarzenia niepożądane (wyjątki),
+\item optymalizacje (np. optymalne wykorzystanie łącza transmisyjnego),
+\item mierzenie wydajności (ang. \emph{profiling}). 
+\end{itemize*}
+         
+           
+Obecność przecinających zagadnień powoduje, że kod klas jest {\it poprzecinany}
+kodem luźno związanym z jego odpowiedzialnościami.  Zmniejszona w ten sposób
+spójność klas utrudnia powtórne użycie, gdyż mają one dodatkowe zależności
+wynikające z obecnych w nich fragmentów kodu realizującego zagadnienie
+przecinające. Z drugiej strony kod zagadnienia przecinającego występuje w wielu
+modułach, co utrudnia jego pielęgnację.  Za każdym razem, gdy trzeba go
+modyfikować występuje problem lokalizacji wszystkich miejsc, w których
+występuje. Jest to kosztowne i obarczone dużym ryzykiem popełnienia pomyłki.
+
+Przykład \ref{pierwszy} ilustruje przypadek, w którym występuje zagadnienie
+przecinające. Klasa \lstinline!DatabaseGateway! pełni rolę pośrednika pomiędzy
+aplikacją a bazą danych. Zagadnieniem przecinającym jest zarządzanie
+transakcjami.  Kod realizujący to zagadnienie znajduje się w obu metodach
+publicznych (\lstinline!AddProduct! i \lstinline!AddSupplier!); przypuszczamy,
+że przy dodaniu kolejnej metody, również trzeba będzie w niej zawrzeć podobny
+kod.
+
+
+\begin{lstlisting}[style=AspectJ,caption=Zagadnienie przecinające,label=pierwszy]
+
+class DatabaseGateway
+   //...
+
+   public AddProduct(product: Product): void
+     // begin transaction
+     saveInDatabase(product)
+     // confirm transaction
+
+    public AddSupplier(supplier: Supplier): void
+      // begin transaction
+      saveInDatabase(supplier)
+      // confirm transaction
+
+    saveInDatabase(product: Product): void
+        //...
+
+    saveInDatabase(supplier: Supplier): void
+        //...
+
+   //...
+\end{lstlisting}
+
+W niektórych przypadkach istnieje możliwość przekształcienia struktury
+rozwiązania tak, aby uniknąć obecności zagadnienia przecinającego. Tutaj
+pewnym rozwiązaniem może być stworzenie klasy według wzorca projektowego
+Pośrednik (ang. \emph{Proxy}) \cite{GoF}, która wzięłaby na siebie
+odpowiedzialność zarządzania transakcjami.  Taka klasa musi jednak
+przedefiniować wszystkie publiczne metody klasy bazowej, ponieważ wszystkie
+metody publiczne interfejsu muszą być delegowane \cite{GoF}. Przykład
+\ref{posrednik} zawiera pseudokod takiej klasy.
+
+\begin{lstlisting}[style=AspectJ,caption=Pośrednik zarządzający transakcjami,label=posrednik]
+
+class DatabaseGatewayTransactionsProxy: DatabaseGateway
+   // ...
+   proxied_object: DatabaseGateway
+   public this(proxied_object: DatabaseGateway)
+      this.proxied_object = proxied_object
+
+   public AddProduct(product: Product): void
+     // begin transaction
+     proxied_object.AddProduct(product)
+     // confirm transaction
+
+    public AddSupplier(supplier: Supplier): void
+      // begin transaction
+      proxied_object.AddSupplier(supplier)
+      // confirm transaction
+   //...
+\end{lstlisting}
+
+Ponadto aplikacje zwykle zawierają więcej niż jedną klasę realizującą
+komunikację z bazą danych. W takim przypadku, kod zarządzający transakcjami
+jest w każdej z nich i tworzenie pośredników może stać się kłopotliwe.
+Programowanie aspektowe umożliwia rozwiązanie tego problemu w bardzo wygodny
+sposób, definiując zaledwie jedną radę (definicja rady jest w punkcie
+\ref{rada}). Rozwiązanie zostanie przedstawione w dalszej części
+TODO(odnośnik).
+
+Przykład \ref{z_pamiecia_podreczna} to jeszcze jedna modyfikacja klasy
+\lstinline!DatabaseGateway!.  Tym razem rozpatrujemy jeszcze zagadnienie
+używania pamięci podręcznej w celu optymalizacji połączeń z bazą danych. W
+wyniku można otrzymać dosyć skomplikowany kod realizujący wiele zagadnień.
+Znacznie lepiej byłoby mieć zagadnienia pod kontrolą, mając ich kod w jednym
+miejscu, zamiast rozproszony pomiędzy modułami.  Tak jak kod realizujący
+dodanie produktu znajduje się w metodzie \lstinline!AddProduct!.
+         
+\begin{lstlisting}[float,style=AspectJ,caption=Dwa zagadnienia przecinające, label=z_pamiecia_podreczna]
+
+class DatabaseGateway
+   // ...
+   product_cache: Hashtable[string,Product] = Hashtable()
+   supplier_cache: Hashtable[string,Supplier] = Hashtable()
+
+   public AddProduct(product: Product): void
+      product_cache[product.Name] = null
+      //...
+
+   public AddSupplier(supplier: Supplier): void
+      supplier_cache[supplier.Name] = null
+      //...
+   
+
+   public GetProduct(name: string): Product
+      when (!cache.Contains(name))
+          def product = loadProductFromDatabase(name)
+          product_cache[name] = product
+
+      prodcut_cache[name]
+
+    public GetSupplier(name: string): Supplier
+       when (!cache.Contains(name))
+          def supplier = loadSupplierFromDatabase(name)
+          supplier_cache[name] = supplier
+
+      supplier_cache[name]
+
+    loadProductFromDatabase(name: string): Product
+        //...
+
+    loadSupplierFromDatabase(name: string): Supplier
+        //... 
+
+   //...
+\end{lstlisting}
+	
+\section{Języki aspektowe}
+
+Przeznaczeniem języków aspektowych jest ułatwienie rozdzielania zagadnień;
+przede wszystkim modularyzacja zagadnień przecinających.  To, w jaki sposób
+można dzielić problemy na moduły projektując rozwiązanie, zależy od tego, jakie
+mechanizmy kompozycji są dostępne.  W takim razie, aby zwiększyć możliwości
+modularyzacji, należy dodać nowe sposoby łączenia elementów systemu.  Języki
+aspektowe oferują konstrukcje do zamykania zagadnień przecinających w swoich
+własnych modułach i zapewniają mechanizm kompozycji, który łączy je z resztą
+programu. Ten nowy sposób dekompozycji pozwala na wyraźnie skuteczniejszą
+modularyzację systemów.
+
+Języki aspektowe realizuje się najczęściej jako rozszerzenia języków
+obiektowych. Rozszerzenie w tym sensie, że główny kod pisany jest w
+rozszerzanym języku. Wciąż większość aplikacji to zwykłe klasy (ponad 80\%).
+Aspekty są używane, gdy przychodzi uporać się z zagadnieniem przecinającym .
+
+Termin Aspect-Oriented Programming (\textsc{aop}) pierwszy raz został użyty w
+roku 1995 \cite{hist}. Twórcami tego paradygmatu są naukowcy z laboratorium
+Xerox Palo Alto Research Center kierowani przez Gregora Kiczalesa.  Na początku
+\textsc{aop} rozumiano jako techniki i narzędzia, które miały pomóc w
+modularyzacji paru dobrze znanych problemów niepodatnych na modularyzację za
+pomocą tradycyjnych języków. Uważano że języki aspektowe powinny zawierać
+konstrukcje, które by ułatwiały pracę z tymi zagadnieniami. W efekcie powstała
+rodzina języków dziedzinowych (ang. \emph{domain specific language}) dla
+poszczególnych zagadnień. Dopiero w połowie 1998 zdecydowano się iść w kierunku
+języków aspektowych ogólnego przeznaczenia. Zamiast umieszczać konstrukcje,
+które wspierały konkretne zagadnienie, skoncentrowano się na ogólnym języku,
+który umożliwiłby modularyzację szerokiego zakresu różnych zagadnień
+przecinających.
+         
+Obecnie najbardziej popularnym językiem aspektowym jest język AspectJ
+\cite{AspectJ} zaprojektowany i zaimplementowany właśnie w Xerox \textsc{parc}.
+Jest to rozszerzenie języka Java. Ma on własny kompilator generujący programy
+dla wirtualnej maszyny (\textsc{jvm}).  Program skompilowany kompilatorem
+AspectJ jest w pełni poprawnym programem w kodzie pośrednim (ang.
+\emph{bytecode}), dzięki czemu programy pisane w języku AspectJ działają na
+każdej maszynie wirtualnej Javy.  Pierwsza wersja kompilatora pojawiła się w
+marcu 1998 roku, ale wtedy język AspectJ nie był jeszcze językiem aspektowym
+ogólnego przeznaczenia. Dopiero wersja AspectJ 0.2 z czerwca tegoż roku poszła
+w tym kierunku.
+
+Język AspectJ ma największą rzeszę użytkowników spośród języków aspektowych.
+Niemniej jednak istnieją inne podejścia do programowania aspektowego(np.
+Hyper/J, Cezar), które oferuję nieco inny model programowania.  Przegrywają one
+w porównaniu z językiem AspectJ pod względem bogactwa narzędzi wspierających
+programowanie.
+
+Rozszerzenie aspektowe jest naturalnym zwiększaniem ekspresyjności języków
+programowania.  Pojawienie się języków obiektowych, które podniosły kod na
+wyższy poziom abstrakcji spowodowało pojawienie się głosów by traktować kod
+jako główną dokumentację. Więcej informacji o tym można znaleźć w
+\cite{CodeAsDesign}. Języki aspektowe czynią takie podejście jeszcze bardziej
+zachęcającym czy też wykonalnym. 
+         
+Dodanie konstrukcji aspektowych jest kolejnym krokiem na drodze zmniejszania
+odstępu między modelem rozwiązania w głowach programistów a jego kodem w języku
+programowania.
+
+Wspólnymi cechami języków aspektowych są nieświadomość (ang.
+\emph{obliviousness}) i kwantyfikacja (ang. \emph{quantification}).
+
+
+\subsection{Nieświadomość}
+
+Nieświadomość oznacza, że z kodu bazowego (na przykład z definicji metody) nie
+da się odczytać, czy zostanie wywołany aspekt. Taką wiedzę można uzyskać
+dopiero wiedząć o wszystkich aspektach obecnych w systemie. Nieświadomość jest
+pożądana, gdyż pozwala na lepsze rozdzielanie zagadnień. Zagadnienia są
+rozdzielone nie tylko w głowach programistów, ale także w strukturze systemu.
+
+Nieświadomość może też oczywiście powodować problemy. System może nie
+zachowywać się zgodnie z przewidywaniami z powodu trudno widocznych powiązań z
+aspektami. Bardzo przydatne są narzędzia wizualizujące miejsca wywoływania
+aspektów. Takie narzędzie jest dostępne razem ze standardową dystrybucją
+kompilatora AspectJ i rozwiązuje problem z niepewnością, czy aspekt modyfikuje
+daną klasę bazową.
+
+Nie chodzi tu o to, żeby nigdy nie umieszczać żadnych śladów, które mogłyby
+mówić o tym, że będzie wywołany aspekt. Przyjmuje się na przykład, że
+oznaczanie metod, które mają być transakcjami, przez atrybuty jest jak
+najbardziej dopuszczalne. Przykład \ref{atrybut} przedstawia metodę
+\lstinline!AddProduct! oznaczoną przez atrybut
+\lstinline!RequiresTransaction()!.  Krytyczne tutaj jest, że taki atrybut jest
+tylko deklaracją, że ta metoda potrzebuje transakcji, a nie imperatywne
+wywołanie jakiejś procedury. To jak i czy metoda zostanie opakowana w
+transakcje zależy od aspektu. Zaletą programowania \textsc{aop} jest to, że kod
+może być całkowicie nieświadomy, ale nie musi.
+
+\begin{lstlisting}[style=AspectJ,caption=Oznaczenie atrybutem,label=atrybut]
+[RequiresTransaction()]
+public AddProduct(product: Product): void
+    saveInDatabase(product)
+\end{lstlisting}
+
+\subsection{Kwantyfikacja}
+		
+Słowo kwantyfikacja ma się kojarzyć z zawężaniem zakresu zmiennej w logice.
+Zmiennymi mają być zdarzenia zachodzące w trakcie działania programu (np
+wywołanie metody).  Bezpośrednio chodzi tu o łatwy wybór zdarzeń, w których
+chcielibyśmy, aby został wykonany dodatkowy kod.
+             
+Programując aspektowo pisze się następujące wyrażenia: \\
+
+{\it w miejscach P, jeśli warunek W zachodzi, wykonaj akcję R } \\
+\\
+dotyczące konwencjonalnie napisanych programów. Taka kwantyfikowana instrukcja
+przekłada się na zmiany w wielu miejscach systemu. Własnie dzięki temu możliwe
+jest osiągnięcie modularyzacji przecinających zagadnień.
+
+\subsection{Języki symetryczne i asymetryczne} \label{symiasym} 
+
+Języki aspektowe można podzielić na dwie kategorie, symetryczne i asymetryczne,
+pod względem tego jak aspekty mają się do pozostałej części programu.
+Najpowszechniejsze są języki asymetryczne (język AspectJ), w których występuje
+podział na kod bazowy i aspekty go modyfikujące. Języki symetryczne, których
+kanonicznym przykładem jest HyperJ, komponują program z \emph{równorzędnych}
+części. W przypadku HyperJ są to hiperprzestrzenie.  O HyperJ można poczytać w
+\cite{MultiDim,WieloWym}.
+         
+\section{Podstawowe definicje}
+
+Poniżej przedstawię kilka definicji z dziedziny programowania aspektowego.
+Aby je zilustrować posłużę się przykładami w języku AspectJ. 
+
+\subsection{Aspekt}
+
+Aspekt --- moduł implementujący zagadnienie przecinające. W języku AspectJ
+aspekty są obywatelami pierwszej kategorii.  Definiuje się je podobnie jak
+klasy, korzystając ze słowa kluczowego \lstinline^aspect^. W odróżnieniu od
+klas mają więcej rodzajów składowych. Dodatkowe składowe to rady (patrz par.
+\ref{rada}).
+
+\subsection{Punkt łączenia}
+
+Punkt łączenia (ang. \emph{join point}) --- zdarzenie w czasie wykonania
+programu, które możemy przechwycić wykonując dodatkowy kod (radę). Języki
+aspektowe różnią się pod względem oferowanych rodzajów punktów łączenia.
+Przykładem punktu łączenia jest wywołanie metody obiektu: np. metody
+\lstinline^Czysc^ klasy \lstinline^Konto^.
+
+Największy zasób punktów łączenia oferuje język AspectJ. Punkty łączenia w
+języku AspectJ:
+
+\begin{itemize*}
+\item wykonanie metody (ang. \emph{execution of a method}),
+\item wykonanie konstruktora (ang. \emph{execution of a constructor}),
+\item wywołanie metody (ang. \emph{method call}),
+\item wywołanie konstruktora,
+\item zapis lub odczyt pola,
+\item wykonanie bloku catch,
+\item wykonanie rady (ang. \emph{advice execution}),
+\item statyczna inicjacja klasy,
+\item inicjacja aspektu.
+\end{itemize*}
+
+Punkty łączenia nie są zdarzeniami punktowymi (Zdarzenie punktowe ma tylko
+moment wystąpienia, a nie ma czasu trwania). Zdarzenie wykonanie metody trwa
+przez okres kiedy kod metody jest wykonywany. 
+
+
+\subsection{Przecięcie}
+
+Zanim przejdę do omawiania przecięć (ang. \emph{pointcut}) przedstawię
+definicję klasycznej metody w języku Java z nowej perspektywy.
+
+\begin{lstlisting}[style=AspectJ]
+void setX(int x) { this.x = x; }
+\end{lstlisting}
+
+Powyższy przykład zawiera definicję prostej metody. Ten fragment można
+interpretować jako: kiedykolwiek nastąpi wywołanie metody o sygnaturze
+\lstinline!void setX(int)!, wykonaj \lstinline!thix.x = x!.  Ma to postać
+stwierdzenia: kiedy nastąpi zdarzenie Z, wykonaj akcję A.  Ograniczeniem języka
+Java; jest, że w takich stwierdzeniach Z oznacza jedno zdarzenie.  Wychodząc od
+tego, można myśleć o \textsc{aop} jako o pewnym uogólnieniu tej idei, poprzez
+umożliwienie definiowania akcji dla wielu różnych zdarzeń za pomocą jednego
+stwierdzenia. Zbiór zdarzeń wyznacza się przecięciem.
+
+		
+Przecięcie to wyrażenie definiujące podzbiór punktów łączenia w programie. Za
+jego pomocą określa się, dla których zdarzeń w programie wykonać radę.
+
+         
+\begin{lstlisting}[style=AspectJ,caption=Przecięcie,label=lowered_balance]
+    call( void Account.Clear() ) || 
+    call( void Account.Withdraw(float) );
+\end{lstlisting}
+	
+
+Powyższe przecięcie (patrz przykład \ref{lowered_balance}) składa się z wywołań
+metod \lstinline^Clear^ i \lstinline^Withdraw^ klasy \lstinline^Account^.
+
+Ponadto przecięcia mogą mieć parametry, które eksponują kontekst punktów
+łączenia. W przykładzie \ref{przec_z_parametrem} eksponuje się obiekt, na
+którym wywoływana jest metoda.
+
+\begin{lstlisting}[style=AspectJ,caption=Przecięcie z parametrem,label=przec_z_parametrem]
+pointcut LoweredBalance(Account acc): 
+    (call( void Account.Clear() ) || 
+    call( void Account.Withdraw(float) )) && target(acc);
+\end{lstlisting}
+
+Taka konstrukcja (patrz przykład \ref{przec_z_parametrem}), oprócz eksponowania
+kontekstu, dodatkowo nakłada ograniczenie na punkt łączenia.  W powyższym
+przykładzie \lstinline!acc! jest typu \lstinline!Account!, więc
+\lstinline!target(acc)!  wybiera tylko te punkty łączenia, w których celem jest
+obiekt typu \lstinline!Account!.
+
+
+\subsection{Rada}\label{rada}
+		
+Rada (ang. \emph{advice}) --- definicja akcji, która ma być wykonana w punktach
+łączenia.  W języku AspectJ radom nie nadaje się nazw.  Podaje się natomiast
+przecięcie (zbiór punktów łączenia) na jakim mają działać (zostać wetkane).    
+
+Zwykle rozróżnia się między radami przed (ang. \emph{before}), dookoła(ang.
+\emph{around}) i po (ang. \emph{after}). W języku AspectJ są wszystkie trzy
+rodzaje rad. Rożnica pomiędzy nimi polega na tym kiedy (gdzie) zostanie
+wykonana (wetkana) rada: przed czy po punkcie łączenia. Rada dookołą daje
+więcej możliwości. W takiej radzie ma się kontrolę nad tym kiedy zostanie
+wywołane zdarzenie punktu łączenia. Ponadto można w ogóle go nie wywoływać.
+Chociaż rada dookoła jest bardziej ogólna zaleca się stosowania rad przed i po.
+
+\subsection{Tkanie}\label{tkanie}
+
+Tkanie --- dołączanie w programie kodu rad w miejsca określone przez
+przecięcie. Odbywać się to może statycznie (przed uruchomieniem systemu) lub
+dynamicznie (w czasie uruchomienia, na przykład podczas ładowania klas). W
+przypadku języka AspectJ robi to kompilator. Proces ten może dotyczyć kodu w
+języku lub też kodu pośredniego programu.  Kompilator języka AspectJ tka w
+kodzie pośrednim \textsc{jvm}.
+
+
+
+
+
+
+
+
+% SPOSOBY REALIZACJI JĘZYKÓW ASPEKTOWYCH
+
+\chapter{Sposoby realizacji języków aspektowych}
+
+Język aspektowy umożliwia rozdzielanie zagadnień na moduły, a z drugiej strony
+potrzebne są mechanizmy, które połączą program w działającą całość. W
+literaturze jest opisanych wiele sposobów osiągnięcia tego celu
+\cite{aosd,AspectJ,JVMSupport}. Jak już to było wspomniane, język AspectJ ma
+własny kompilator i tkanie jest jedną z późniejszych faz kompilacji. Pozwala to
+na dużą swobodę, choć o dziwo istnieje technika, która pozwala na tkanie
+większej ilości klas, bo także klas z bibliotek zewnętrznych. Tą techniką jest
+tkanie czasu wczytywania (and. \emph{load-time weaving}), która wykorzystuje
+oferowaną przez \textsc{jvm} możliwość podmiany obiektu ładującego klasy
+(ClassLoader). Bywa to czasem nazywane dynamiczną modyfikacją kodu pośredniego
+(bytecode), w odróżnieniu od statycznej, która polega na modyfikacji całości
+kodu przed uruchomieniem programu. 
+
+Rzadziej wykorzystywane podejścia to modyfikacja wirtualnej maszyny, tkanie kodu
+źródłowego oraz wykorzystanie \textsc{api} do odpluskwiania programów.  Znane
+są także biblioteki do standardowych języków, takich jak Java i C\#, które
+implementują mechanizmy łączenia \textsc{aop} głównie za pomocą refleksji
+\cite{aosd}.
+
+\section{Kompilacja}
+
+Ponieważ język AspectJ rozszerza język Java, jego kompilator jest rozszerzeniem
+kompilatora Javy. Kompilacja jest podzielona na dwa etapy. W pierwszym
+kompilowane są zarówno klasy jak i aspekty. Dopiero podczas drugiego etapu
+następuje tkanie, które polega na odpowiednim zmodyfikowaniu klas w celu
+umieszczenia w nich odwołań do aspektów.
+
+Podczas pierwszej fazy kompilator zamienia definicję rady na zwykłą metodę z
+tymi samymi argumentami jakie ma rada. Treść rady jest zgodna z tym co może
+pojawić się w metodzie, z wyjątkiem słowa kluczowego \lstinline!proceed!, które
+może się pojawić w radach typu \lstinline!around!. Dane dotyczące przecięcia,
+na którym działa rada, są zachowane jako metadane metody do wykorzystania w
+drugiem etapie kompilacji. 
+
+
+Rada z przykładu \ref{rada_w_aspectj} jest tłumaczone do postaci w kodzie
+pośrednim widocznej w przykładzie \ref{rada_w_bytecode}.
+
+\begin{lstlisting}[style=AspectJ,caption=Rada w języku AspectJ,label=rada_w_aspectj]
+before(String s): execution(void A.SomeMethod(*)) && args(s)
+{
+    System.out.println(s);
+}
+\end{lstlisting}
+
+\begin{lstlisting}[style=AspectJ,caption=Kod pośredni rady,label=rada_w_bytecode]
+public void ajc$before$A$A$a9();
+0: getstatic [java/lang/System.out]
+3: aload_1
+4: invokevirtual [java/io/PrintStream.println]
+7: return
+\end{lstlisting}
+
+W czasie drugiej fazy po kolei rozważane są wszystkie cienie punktów łączenia,
+czyli miejsca w kodzie odpowiadające punktom łączenia. Dla każdego takiego
+miejsca jest sprawdzane, dla każdej rady, czy może ona przechwycić ten punkt
+łączenia. Jeśli tak, to w takim miejscu dołączane jest wywołanie metody
+implementującej radę wraz z ewentualnym kodem sprawdzającym w czasie wykonania
+czy punkt łączenia należy do przecięcia rady. Dokładny sposób dołączenia
+wywołania zależy od typu rady (po, przed, dookoła).
+
+Rady są zawsze wykonywane jako metody obiektu klasy implementującej aspekt.
+Zwykle w systemie jest tylko jeden taki obiekt dla aspektu, który programista
+może uzyskać wywołując statyczną metodę \lstinline!aspectOf!.
+
+\section{Transformacja kodu}
+
+Trasformacja kodu jest to przetwarzanie programu w postaci kodu pośredniego lub
+kodu źródłowego.  W pierwszym przypadku wejściem jest kod pośredni po
+kompilacji, a wyjściem poprawny kod pośredni po wetkaniu rad. W drugim
+przypadku, analogicznie, rezultatem jest zmodyfikowany kod programu, gotowy do
+kompilacji.
+
+Pod terminem transformacja statyczna rozumie się przetwarzanie kodu z dostępem
+do całości kodu systemu.  Przetwarzanie jest dwuprzebiegowe. W pierwszym
+przebiegu zbiera się informacje o radach działających w systemie, a w
+drugim przechodzi się cały kod w celu identyfikacji i tkania w punktach
+łączenia wyspecyfikowanych dla rad. Oczywistym jest, że rady mogą zostać
+wetkane tylko do kodu klas przetwarzanego systemu.
+
+\section{Tkanie czasu wczytywania}
+
+Transformacja kodu w czasie wczytywania jest używana między innymi przez
+implementację języka JBossAOP \cite{jbossaop}.  Dużą zaletą wykorzystania tego
+sposobu tkania rad, jest możliwość modyfikacji także klas obcych, których kod
+nie znajduje się w plikach źródłowych systemu. Transformacja kodu może być
+wykorzystana tylko, jeśli wirtualna maszyna pozwala na to. \textsc{Clr}, dla
+przykładu, nie przewiduje takiej możliwości.  \textsc{Jvm} pozwala na podmianę
+definicji klasy (dzięki wymienialnemu modułowi \lstinline!ClassLoader!).
+
+\textsc{Jvm} wczytuje klasę, między innymi wtedy, gdy w kodzie napotka
+wystąpienie jej konstruktora. Wczytywanie jest wykonywane przez moduł
+\lstinline!ClassLoader!. Możliwe jest napisanie własnej implementacji dla
+\lstinline!ClassLoader!, która przed załadowaniem klasy dokona na niej tkania
+zgodnie z definicjami rad. 
+
+Wadą takiego rozwiązanie jest brak dostępu do całości kodu, gdyż klasy ładowane
+są pojedynczo. Drugą sprawą jest spory narzut czasowy przy każdym uruchomieniu
+aplikacji. Jest on spowodowany koniecznością przejrzenia każdej wczytywanej klasy pod
+kątem występowania w niej przechwytywanych przez jakieś rady punktów łączenia.
+
+\section{Wsparcie maszyny wirtualnej dla AOP}
+
+Realizacja programowania \textsc{aop} bezpośrednio w maszynie wirtualnej
+byłoby optymalnym rozwiązaniem. Jedyna wada w takim podejściu, to
+niekompatybilność wynikowego kodu ze zwykłą maszyną wirtualną języka Java.
+Wymaganie, by kod wynikowy działał na zwykłej maszynie wirtualnej języka Java,
+powoduje sporo trudności. Kod dla zmodyfikowanej maszyny języka Java nie
+musiałby być nawet tkany. Maszyna wirtualna mogłaby trzymać strukturę danych,
+która zawierałaby informacje o tym, jakie punkty łączenia są przechwytywane i
+delegować do rad podczas obsługi wywołania metody czy też innych punktów
+łączenia, takich jak obsługa wyjątków. Sprawia to, że nie byłoby kosztownego
+tkania, które stanowi problem w metodzie implementacji \textsc{aop} za pomocą
+transformacji kodu.
+
+Podczas gdy kompilator języka AspectJ jest w stanie dołączać wywołania rad
+tylko do kodu do którego ma dostęp, wirtualna maszyna mogłaby przechwycić
+każde interesujące zdarzenie. Kompilator AspectJ nie może dołączać rad w
+punktach łączenia typu wykonanie w klasach bibliotek.
+
+Niektórzy podchodzą ze sporą dozą sceptycyzmu do transformacji kodu. Nietrudno
+wyobrazić sobie przypadki, kiedy wiele narzędzi transformujących,
+przekształcając kod aplikacji jeden po drugim, w rezultacie da wynik daleki
+od oczekiwań. Wsparcie dla \textsc{aop} na poziomie maszyny wirtualnej
+zapewniałoby większą niezawodność.
+ 
+\section{AOP za pomocą refleksji}
+ 
+Istnieją implementacje aspektów w postaci bibliotek. Nazywa się je
+dynamicznymi, ponieważ rady (a dokładniej ich kod) nie są umieszczane w
+punktach łączenia podczas kompilacji.  Bazują ona na wzorcu Pośrednik. Od
+wersji 1.3 wirtualnej maszyny Javy możliwe jest tworzenie dynamicznych
+pośredników dla interfejsów, które mogą przechwytywać wykonania metod i
+delegować do metod implementujących rady. Ponadto dostępne są biblioteki,
+które pozwalają na tworzenie takich dynamicznych klas wywiedzionych nie
+tylko dla interfejsów, ale też i dla zwykłych klas.
+ 
+Zwykle w takich realizacjach definicje aspektów wczytywane są przez obiekt,
+który według nich tworzy opakowane obiekty (wzorzec Pośrednik). Korzystając z
+niego trzeba opakować każdy obiekt, na którym miałyby działać zdefiniowane
+aspekty.
+
+Zaletą tego podejścia jest prostota realizacji takiej biblioteki i brak
+dodatkowego przetwarzania związanego z tkaniem. Jej wadami są:
+ 
+\begin{itemize*}
+
+    \item  aby na obiekcie działały zdefiniowane aspekty
+         musi on zostać opakowany,
+    \item spektrum punktów łączenia jest ograniczone do wykonań metod wirtualnych.
+\end{itemize*}
+ 
+Metoda, której wywołanie chcemy przechwycić musi być wirtualna.  O ile w języku
+Java nie stanowi to ograniczenia, ponieważ wszystkie metody są tam takie, to w
+\textsc{c++} i \textsc{c\#} nieco przeszkadza. Metody w tych językach muszą być
+oznaczone jako wirtualne. Bardzo utrudnia to działanie aspektów na klasach,
+których kodu nie możemy modyfikować.
+ 
+ Przykład \ref{aspectsharp} pokazuje definicję prostego aspektu w języku aspect\#.
+         
+\begin{lstlisting}[style=AspectJ, caption=Aspekt w języku aspect\#,label=aspectsharp]
+aspect Persistence for Firm
+
+    pointcut propertywrite( * )
+        advice( UpdateFirm )
+    end
+
+end
+\end{lstlisting}
+	
+Aspekt (patry przykład \ref{aspectsharp}) jest zdefiniowany dla klasy
+\lstinline^Firm^. Jego treść można przedstawić jako: dla klasy
+\lstinline^Firm^, dla przecięcia \emph{zapis propercji} wykonaj radę
+\lstinline^UpdateFirm^ (propercje w \textsc{c\#} są składnikami klas, wywołuje
+się je jak pola, a implementuje w postaci dwóch metod get i set, tu chodzi o
+metody \lstinline!set! propercji).  Dodatkowo podana jest nazwa aspektu:
+\lstinline^Persistence^.
+
+AspectSharp jest biblioteką aspektów dynamicznych. Aby na obiekcie działały
+aspekty, trzeba go opakować. Poniżej przedstawiam kod tworzący opakowany obiekt
+typu \lstinline^Firm^.
+
+		 \begin{lstlisting}[style=AspectJ]
+TextReader config = new StreamReader("Persistence.a");
+AspectEngineBuilder builder = 
+   new AspectLanguageEngineBuilder(config);
+
+AspectEngine aspectEngine = builder.Build();
+          
+Firm aFirm = (Firm) aspectEngine.WrapClass(typeof(Firm));
+\end{lstlisting}
+	
+Tworzy się obiekt \lstinline^AspectEngineBuilder^ podając mu definicję aspektu
+(powyższa definicja aspektu \lstinline^Persistence^) zapisaną w pliku. Aby
+otrzymać obiekt opakowany (na którym działają aspekty) wywołuje się metodę
+\lstinline^WrapClass^. Niestety za pomocą AspectSharp nie można opakować
+istniejących obiektów. Można jedynie tworzyć nowe na podstawie klasy.
+
+
+% JĘZYK NEMERLE
+\chapter{Język Nemerle}
+
+
+Ten rozdział zawiera informacje dotyczące języka Nemerle, niezbędne w zrozumieniu
+tej pracy. Nemerle to typowany statycznie język hybrydowy,
+bo jednocześnie zorientowany obiektowo jak i funkcjonalny.  Jego wyróżniającą
+cechą jest wbudowany system metaprogramowania. 
+
+Język Nemerle jest kompilowany do kodu pośredniego dla środowiska
+uruchomieniowego \textsc{.net 2.0} (ten język pośredni zawiera instrukcję
+wywołania ogonowego).  Dzięki temu, pisząc w języku Nemerle, ma się nie tylko
+pełny dostęp do bibliotek dla platformy Microsoft \textsc{.net}, ale także
+biblioteki stworzone w Nemerle można wykorzystywać w programowaniu w innych
+językach (zakładając, że są kompilowane do \textsc{.net}).
+
+Jego składnia jest rozszerzeniem składni języka C\# z małymi zmianami. Jedną 
+z różnic jest podawanie typów po dwukropku. Proszę zwrócić uwagę na
+definicję pola \lstinline!temperature! w przykładzie \ref{refrigerator}. Ta
+sama konwencja jest zachowana dla parametrów, a także przy podawaniu typu
+zwracanego wyniku przez metodę.  Metoda \lstinline!IncreaseTemperature! zwraca
+\lstinline!void!. Tajemniczo wyglądająca metoda o nazwie \lstinline!this!,
+która nie ma typu zwracanego wyniku, to w istocie konstruktor klasy
+\lstinline!Refrigerator!. Oznaczanie konstruktorów słowem kluczowym
+\lstinline!this! okazuje się szczególnie wygodne, gdy chce się zmienić nazwę
+klasy.
+
+\begin{lstlisting}[style=AspectJ,caption=Składnia klas w języku Nemerle,label=refrigerator]
+using System;
+namespace Company.Whitegoods {
+ class Refrigerator {
+    mutable temperature: float;
+
+    public this(temp: float) {
+        this.temperature = temp;
+    }
+
+    public IncreaseTemperature(value: float): void {
+        temperature += value;
+    }
+ }
+}
+\end{lstlisting}
+
+Słowo kluczowe \lstinline!namespace! służy do specyfikowania przestrzeni nazw.
+Zgodnie z kodem w przykładzie \ref{refrigerator} klasa \lstinline!Refrigerator!
+jest zdefiniowana w przestrzeni nazw \lstinline!Company.Whitegoods!. Przestrzeń
+nazw jest odpowiednikiem pakietu z języka Java. Przestrzeń nazw otwiera się
+słowem kluczowym \lstinline!using! (odpowiednik 
+\lstinline!import pakiet.*! z języka Java).
+
+
+\section{Odtwarzanie typów}
+
+Cechą charakterystyczna języka Nemerle jest brak typów przy deklaracjach
+zmiennych. Niewątpliwą zaletą język Nemerle jest to, że ma zaimplementowany
+algorytm odtwarzania typów (ang. \emph{type inference}). Programista jest
+praktycznie zwolniony z konieczności podawania typów dla deklarowanych
+zmiennych. Ich typ jest wnioskowany z kontekstu użycia. Deklaracja zmiennej
+całkowitej wygląda tak: \lstinline!mutable i = 1;!. Ponieważ język Nemerle jest
+językiem funkcjonalnym, preferuje się używanie stałych, które definiuje się za
+pomocą słowa kluczowego \lstinline!def!. 
+Na przykład \lstinline!def n = "napis";!.
+
+Odtwarzanie typów jest przeprowadzane tylko w ciałach metod i konstruktorów.
+Programista jest zobowiązanych podawać typy w sygnaturach składników klas.
+
+
+\section{System typów}
+
+W języku Nemerle oprócz klas wyróżnia się jeszcze dwa rodzaje typów złożonych: iloczyn
+kartezjański i typ funkcyjny.  Iloczyn kartezjański tworzy się za pomocą
+operatora \lstinline!*!. Wartościami iloczynu kartezjańskiego są krotki. Na
+przykład: \\
+\lstinline!(1,2,3): int*int*int!, a \lstinline!(1,(2,3)): int*(int*int)!.\\
+Operator \lstinline!*!, tworzący iloczyn kartezjański, nie jest łączny.
+
+Typ funkcyjny tworzy się za pomocą operatora \lstinline!->!. Funkcja
+konwertująca \lstinline!int! do \lstinline!float! ma typ
+\lstinline!int->float!.
+
+Funkcje można definiować wewnątrz metod, korzystając ze słowa kluczowego
+\lstinline!def!. Przyklad \ref{lokalna} przedstawia definicję funkcji
+lokalnej. Kompilator przyporządkuje jej typ \lstinline!int->int!, ponieważ
+zauważy, że \lstinline!arg! jest dodawany do wartoście typu \lstinline!int!.
+
+\begin{lstlisting}[style=AspectJ,caption=Funkcja lokalna,label=lokalna]
+    def successor(arg) {
+        arg+1
+    }
+\end{lstlisting}
+
+\subsection{Polimorfizm parametryczny}\label{polim_parametryczny}
+
+Polimorfizm parametryczny pozwala na parametryzowanie klas i metod typami. W
+języku Nemerle zdefiniowana jest klasa parametryzowalna \lstinline!list!, która
+reprezentuje listę elementów. Wyrażenie określające typ listy napisów to:
+\lstinline!list[string]!.
+
+
+\begin{lstlisting}[style=AspectJ,caption=Klasa parametryzowalna,label=polimorfizm_parametryczny]
+interface Set[E] where T: IComparable[E] {
+  Add(e: E): void;
+  Remove(e: E): void;
+  Contains(e: E): bool;
+}
+\end{lstlisting}
+
+Przykład \ref{polimorfizm_parametryczny} przedstawia parametryzowalny
+interfejs. Zmienna \lstinline!T! to parametr typowy. Na typy, którymi można
+sparametryzować interfejs \lstinline!Set!, nałożono tylko taki warunek, że
+implementują interfejs \lstinline!IComparable[E]! (\lstinline!where E: IComparable[E]!). 
+Dzięki temu \lstinline!Compare! z \lstinline!IComparable! można użyć w implementacjach operacji
+\lstinline!Remove! i \lstinline!Contains!.
+
+Także operacja może mieć parametry typowe. Przykład \ref{operacja_parametryzowalna}
+wprowadza nową operację do interfejsu \lstinline!Set!. 
+
+\begin{lstlisting}[style=AspectJ,caption=Operacja parametryzowalna,label=operacja_parametryzowalna]
+interface Set[E] where E: IComparable[E] {
+    ...
+    AddAll[T](xs: list[T]) where T:E;
+}
+\end{lstlisting}
+
+\subsubsection{Kowariancja}\label{nemerle.kowariancja}
+
+Typ parametryzowalny \lstinline!K[]! jest \emph{kowarianty} względem swojego
+argumentu typowego wtedy i tylko wtedy, gdy
+dla każdego \lstinline!A! i \lstinline!B!  jeżeli \lstinline!A <: B!, to 
+\lstinline!K[A] <: K[B]!, gdzie \lstinline!<:! oznacza
+relację bycia podtypem.
+
+Gdyby klasa \lstinline!list! była kowariantna względem typu swoich elmentów,
+obiektu typu \lstinline!list[A]! można byłoby użyć wszędzie tam gdzie obiektu
+typu \lstinline!list[B]! pod warunkiem, że \lstinline!A! jest podtypem
+\lstinline!B!. Niestety klasa \lstinline!list!, podobnie jak prawie wszystkie
+typy w języku Nemerle, nie jest kowariantna. Wyjątkiem są, interfejsy, które
+można tak zdefiniować, żeby były kowariantne.
+
+
+\section{Blok}
+
+Blok to ciąg wyrażeń oddzielonych od siebie średnikami, otoczony
+nawiasami klamrowymi. Ciało funkcji w przykładzie \ref{lokalna} to blok.
+Wartością zwracaną z bloku jest wartość ostatniego wyrażenia; w języku Nemerle
+nie ma instrukcji \lstinline!return!.
+
+\section{Propercja}\label{propercja}
+
+Przykład \ref{propercje} przedstawia propercję \lstinline!Age!, składnik klasy 
+\lstinline!Person!. Propercja to nic innego tylko lukier syntaktyczny dla
+często używanych w innych językach metod get i set, dających dostęp do pól klas.
+
+\begin{lstlisting}[style=AspectJ,caption=Propercja w języku Nemerle,label=propercje]
+class Person {
+    mutable age: int;
+    public Age: int {       // propercja Age
+        get { age }
+        set { age = value }
+    }
+}
+\end{lstlisting}
+
+Zapis i odczyt propercji wygląda jak dostęp do pola: 
+\begin{lstlisting}[style=AspectJ]
+person.Age = 2.
+\end{lstlisting}
+Taka instrukcja powoduje wywołanie części set propercji, z niejawnym argumentem, \lstinline!value!,
+równym 2. Kompilator zamienia definicję \lstinline!set! na metodę:
+\begin{lstlisting}[style=AspectJ]
+public set_Age(value: int): void {age = value},
+\end{lstlisting}
+a definicję get na metodę bezargumentową:
+\begin{lstlisting}[style=AspectJ]
+public get_Age(): int {age}.
+\end{lstlisting}
+
+Propercja może zawierać oba
+składniki, \lstinline!get! i \lstinline!set!, bądź tylko jeden z dwóch.
+
+
+
+
+
+
+
+
+
+% OPIS ROZSZERZENIA
+
+\chapter{Opis rozszerzenia}
+
+Język Nemerle.Aop jest asymetrycznym językiem zorientowanym aspektowo (patrz
+par. \ref{symiasym}) rozszerzającym język Nemerle. Składnia języka została tak
+zaprojektowana, aby jego konstrukcje w maksymalnym stopniu przypominały
+analogiczne konstrukcje z języka AspectJ. Z tego powodu choćby pobieżna
+znajomość języka AspectJ jest pomocna do zrozumienia poniższego opisu języka
+Nemerle.Aop. 
+
+Na ostateczny kształt składni miała też wpływ chęć utrzymania spójności z
+językiem Nemerle. Dla przykładu, w języku Nemerle stosuje się konwencję
+podawania typu po obiekcie (\lstinline!obiekt: typ!) i taką konwencję zachowano
+w rozszerzeniu.
+
+Składnia rozszerzenia zdefiniowana jest gramatyką bezkontekstową. Do tego celu
+wykorzystana jest rozszerzona notacja \textsc{bnf}. Symbole nieterminalne są
+otoczone nawiasami kątowymi, a symbole terminalne apostrofami. Otoczenie
+symbolów nawiasami klamrowymi \lstinline!{}! oznacza powtórzenie conajmniej
+raz, natomiast otoczenie nawiasami kwadratowymi \lstinline![]! oznacza
+powtórzenie co najwyżej raz.
+
+W tym rozdziale składnia wprowadzana jest przyrostowo, w miarę omawiania
+kolejnych konstrukcji języka. Pełna gramatyka została umieszczona w 
+dodatku A.
+
+Przykład \ref{nemerle_aspect_example} przedstawia definicję aspektu w języku
+Nemerle. Aspekt to klasa z atrybutem \lstinline!aspect!. Programista może
+korzystać z języka Nemerle.Aop po otworzeniu przestrzeni nazw
+\lstinline!Nemerle.Aop!.
+
+\begin{lstlisting}[style=AspectJ,caption=Przykład aspektu w języku Nemerle,label=nemerle_aspect_example]
+using Nemerle.Aop;
+[aspect] public class ExampleAspect {
+
+  before(s:string):execution(A.SomeMethod():void)&&args(s) 
+  {
+      System.Console.WriteLine(s);
+  }
+
+  after() returning(result:string):execution(B.?(..):string) 
+  {
+      System.Console.WriteLine(result);
+  }
+}
+\end{lstlisting}
+
+
+Składnia języka Nemerle na potrzeby programowania aspektowego została
+rozszerzona o nieterminal \lstinline!advice_definition!. Rada może się pojawić
+jako składnik klasy reprezentującej aspekt. W gramatyce języka Nemerle
+\cite{nemerle} zdefiniowany jest symbol nieterminalny \lstinline!type_member!,
+który reprezentuje składniki klas. Jego definicja jest następująca:
+
+\lstdefinestyle{grammar} {basicstyle=\tt,showstringspaces=false}
+\begin{lstlisting}[style=grammar]
+<type_member> ::=
+    <field_definition>
+  | <property_definition>
+  | <event_definition>
+  | <method_definition>
+  | <type_declaration> 
+\end{lstlisting}
+
+Rozszerzając gramatykę języka Nemerle, dodajemy następującą produkcję\\
+\lstinline!<type_member> ::= <advice_definition>!,\\ gdzie symbol
+\lstinline!advice_definition! reprezentuje definicję rady.
+
+Zanim jednak przejdę do omawiania definicji rady, omówię
+bardziej podstawowe elementy języka.
+
+\section{Punkty łączenia}
+
+Język aspektowy pozwala definiować moduły implementujące przecinające
+zagadnienia -- aspekty. Aspekt może modyfikować zachowanie programu tylko w
+dostępnych w języku punktach łączenia.
+
+W języku Nemerle.Aop są cztery rodzaje punktów łączenia:
+\begin{itemize*}
+    \item wykonanie metody,
+    \item wykonanie konstruktora,
+    \item odczyt propercji,
+    \item zapis propercji.
+\end{itemize*}
+Wszystkie odpowiadają fragmentom kodu w programie. Odczyt i zapis propercji
+dotyczy specjalnego składnika klas występującego w języku Nemerle (patrz par. \ref{propercja}). 
+
+Aspekty mogą modyfikować program tylko w punktach łączenia odpowiadającym
+fragmentom programu kompilowanych do tego samego podzespołu. Podzespół to plik
+wykonywalny lub biblioteka będący wynikiem kompilacji. Konsekwencją tego jest,
+że wykonania metod z bibliotek wykorzystywanych przez program nie są dostępne
+jako punkty łączenia w języku Nemerle.Aop. Dotyczy to zarówno bibliotek
+standardowych jak i własnych. Ograniczenie to wynika ze sposobu łączenia
+aspektów z kodem klas bazowych. Podczas tego procesu moduł tkający modyfikuje
+kod bazowy, umieszczając w nim odwołania do aspektów. Dokładne omówienie
+znajduje się w kolejnym rozdziale.
+
+Wykonanie konstruktora nie dotyczy konstruktorów domyślnych. Jeżeli w klasie
+nie zdefiniowano konstruktora, to, z definicji języka, klasa ta ma domyślny
+konstruktor bezparametrowy.  Niemniej jednak, ten konstruktor nie występuje w
+kodzie pośrednim, więc nie ma gdzie wetkać odwołań do aspektów.
+
+Z każdym punktem łączenia związana jest sygnatura. Sygnatura wykonania metody składa się
+z: \begin{itemize*}
+    \item nazwy klasy,
+    \item nazwy metody,
+    \item typów parametrów,
+    \item typu zwracanego wyniku,
+    \item modyfikatorów zakresu widzialności (\lstinline!public!, 
+        \lstinline!internal!, \lstinline!private!, \lstinline!protected!, 
+        \lstinline!static!),
+    \item typów atrybutów.
+\end{itemize*}
+
+Punkty łączenia wykonania konstruktora nie zawierają w swoich sygnaturach nazwy
+metody ani zwracanego wyniku.  Zapis propercji ma te same elementy w sygnaturze
+co metoda, oprócz tego, że ma tylko jeden typ parametru (typ zapisywanej
+wartości), a typ zwracanego wyniku to zawsze \lstinline!void!. Odczyt propercji ma typ zwracanego
+wyniku, ale nie ma żadnych parametrów. Tabela \ref{sygnatury} podsumowuje
+różnice pomiędzy sygnaturami rodzajów punktów łączenia.
+
+\begin{table}
+\begin{tabular}{|l|c|c|c|c|}
+\hline
+Element sygnatury & Wyk. metody & Wyk. konstr. & Zapis prop. & Odczyt prop.\\
+\hline
+Nazwa klasy     & tak & tak & tak & tak \\\hline
+Nazwa składnika & tak &     & tak & tak \\\hline
+Typy parametrów & tak & tak & tak & ()  \\\hline
+Typ wyniku      & tak &     & void& tak \\\hline
+Modyfikatory    & tak & tak & tak & tak \\\hline
+Atrybuty        & tak & tak & tak & tak \\\hline
+\end{tabular}
+\caption{\label{sygnatury}Sygnatury punktów łączenia}
+\end{table}
+
+%%%%%%%%%%%%%%%%% KONIEC PUNKTU ŁĄCZENIA %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{Przecięcie}
+
+Przecięcie ma dwie funkcje. Po pierwsze, wyznacza zbiór
+punktów łączenia.  Pod tym względem jest predykatem na zbiorze punktów
+łączenia. Po drugie, definiuje wiązanie parametrów formalnych rady z
+wartościami w kontekście wykonania punktu łączenia. 
+
+Wyrażenia określające przecięcia buduje się, składając przecięcia pierwotne. 
+W języku Nemerle.Aop dostępne są następujące przecięcia pierwotne:
+\begin{itemize*}
+    \item \lstinline!execution(!wzorzec sygnatury punktu łączenia\lstinline!)!,
+    \item \lstinline!args(!wzorce typów lub nazwy parametrów formalnych rady\lstinline!)!,
+    \item \lstinline!target(!wzorzec typu lub nazwa parametru formalnego rady\lstinline!)!.
+\end{itemize*}
+
+\begin{lstlisting}[style=grammar] 
+<primitive_pointcut> ::= 
+    <execution_pointcut>
+  | <args_pointcut>
+  | <target_pointcut>
+\end{lstlisting}
+
+Konstruktor \lstinline!execution! jest wyłącznie predykatem; podczas gdy
+\lstinline!args! i \lstinline!target! mogą także definiować wiązanie parametrów
+rady z wartościami w kontekście wykonania punktu łączenia, na przykład argumentami metod.
+
+\subsection{Przecięcie pierwotne \lstinline!execution!}
+
+\begin{lstlisting}[style=grammar]
+<execution_pointcut> ::=
+    'execution' '(' <signature_pattern> ')'
+\end{lstlisting}
+
+Punkty łączenia w przypadku przecięcia execution wyznaczane są na podstawie
+wzorca sygnatury. Są trzy rodzaje wzorców sygnatury:
+\begin{itemize*}
+    \item wzorzec sygnatury metody,
+    \item wzorzec sygnatury propercji,
+    \item wzorzec sygnatury konstruktora.
+\end{itemize*}
+
+Podział ten, w gramatyce, wyrażony jest przez produkcje z nieterminala \lstinline!member_pattern!.
+
+\begin{lstlisting}[style=grammar]
+<signature_pattern> ::=
+    ['[' <attributes_pattern>']'] [<modifiers_pattern>] 
+    ['static'] <class_in_signature> <member_pattern>
+\end{lstlisting}
+
+\begin{lstlisting}[style=grammar]
+<member_pattern> ::=
+    <method_pattern>
+  | <property_pattern>
+  | <constructor_pattern>
+\end{lstlisting}
+
+Przecięcie \lstinline!execution! ze wzorcem sygnatury metody wyznacza jedynie
+wykonania metod, a ze wzorcem sygnatury konstruktora wykonania konstruktorów.
+Zgodnie ze składnią, nie jest możliwe podanie wzorca sygnatury, która może się
+dopasować do metody i konstruktora.
+
+
+Składniki wzorca sygnatury dla metody odpowiadają składnikom sygnatury punktu
+łączenia wykonanie metody: \begin{itemize*} 
+    \item wzorzec nazwy klasy, 
+    \item wzorzec nazwy metody, 
+    \item wzorzec typów parametrów, 
+    \item wzorzec typu zwracanego wyniku, 
+    \item wzorce modyfikatorów zakresu widzialności, 
+    \item wzorce typów atrybutów.  
+\end{itemize*}
+
+Wzorzec sygnatury dopasowuje się do sygnatury punktu łączenia, jeżeli wszystkie
+składniki wzorca dopasowują się do odpowiadających im składników sygnatury
+punktu łączenia.
+
+\subsubsection{Wzorzec nazwy klasy}\label{wzorzec_nazwy_klasy}
+
+\begin{lstlisting}[style=grammar]
+<class_in_signature> ::=
+  [{<id_pattern> ('.' | '..')}][<id_pattern> '+' '.']
+\end{lstlisting}
+
+Mimo, że z nieterminala \lstinline!class_in_signature! można wyprowadzić napis
+pusty, kompilator go nie zaakceptuje.
+
+
+Operator \lstinline!..! zastępuje zero lub więcej członów nazwy klasy.
+Następująca nazwa \lstinline!A.B.Klasa! składa się z trzech członów:
+\lstinline!A! \lstinline!B! i \lstinline!Klasa!.
+
+Znak \lstinline!+! służy do konstruowania wzorców podklas. Dokładny opis 
+jest w paragrafie \ref{wzorzec_podtypu}.
+
+Jeżeli wzorzec klasy nie zawiera symboli specjalnych
+(\lstinline!..! i \lstinline!?!), traktowany jest jako dokładna nazwa. Klasa
+jej odpowiadająca szukana jest wśród otwartych przestrzeni nazw. Oznacza to, że
+jeżeli istnieje klasa \lstinline!A.B.Klasa! i otwarta jest przestrzeń nazw
+\lstinline!A.B!, to wzorzec \lstinline!Klasa! zostanie rozpoznany jako
+\lstinline!A.B.Klasa!.
+
+W języku Nemerle można definiować klasy jako składniki innych klas. Tego typu
+klasy też można specyfikować w sygnaturze. Dla przykładu niech klasa
+\lstinline!Contained! będzie zdefiniowana jako składnik klasy
+\lstinline!A.B.Container!. Przykładowy wzorzec może być taki:
+\lstinline!A.B.Container.Contained! lub \lstinline!A..Contained!.  Klasa
+\lstinline!Contained! dopasuje się do obu, jednak do drugiego wzorca dopasuje
+się także na przykład klasa \lstinline!A.Contained!.
+
+\subsubsection{Wzorzec nazwy metody}
+
+\begin{lstlisting}[style=grammar]
+<method_pattern> ::=
+  <id_pattern>'('<parameters_pattern>')'':'<type_pattern>
+\end{lstlisting}
+
+Wzorzec dla nazwy metody może być albo nazwą dokładną albo symbolem
+specjalnych \lstinline!?!, który dopasowuje się do dowolnej nazwy.
+
+\subsubsection{Wzorzec parametrów}
+
+\begin{lstlisting}[style=grammar]
+<parameters_pattern> ::=
+    [<parameter_pattern> [{',' <parameter_pattern>}]]
+
+<parameter_pattern> ::=
+    <type_pattern>
+  | '..'
+\end{lstlisting}
+
+Wzorzec typów parametrów to lista wzorców typów, w której mogą występować
+przerwy. Przykładowy wzorzec dla parametrów: \lstinline!(?,..,float)! zawiera
+symbol specjalny \lstinline!..!, oznaczający przerwę.  Do przerwy może się dopasować 
+dowolny ciąg typów. Do podanego wzorca dopasowuje się zarówno
+\lstinline!(string,float)! jak i \lstinline!(int,int,float)!.
+
+\subsubsection{Wzorzec modyfikatorów}
+
+\begin{lstlisting}[style=grammar]
+<modifiers_pattern> ::=
+    [{ ['!'] <modifier> }]
+
+<modifier> ::=
+    'public'
+  | 'protected'
+  | 'internal'
+  | 'private'
+  | 'static'
+\end{lstlisting}
+
+Wzorce modyfikatorów zakresu widzialności składa się z listy wzorców dla
+modyfikatorów. Dostępne są następujące modyfikatory:
+\begin{itemize*}
+			\item \lstinline!public!,
+			\item \lstinline!internal!,
+			\item \lstinline!protected!,
+			\item \lstinline!private!,
+			\item \lstinline!static!.
+\end{itemize*}
+Każdy z nich może być zaprzeczony. Obecność wzorca \lstinline!public! oznacza,
+że sygnatura punktu łączenia musi zawierać ten modyfikator, aby się dopasowała.
+W przypadku wzorca negatywnego \lstinline*!public* sygnatura punktu łączenia
+nie może zawierać tego modyfikatora.
+
+\subsubsection{Wzorzec atrybutów}
+
+\begin{lstlisting}[style=grammar]
+<attributes_pattern> ::=
+    <type_pattern> [{',' <type_pattern>}]    
+\end{lstlisting}
+
+Wzorzec sygnatury zawiera także listę wzorców dla typów atrybutów. Kolejność
+wzorców typów nie ma znaczenia.  Dopasowanie następuje, gdy każdy ze wzorców
+dopasowuje się do jakiegoś typu atrybutu w sygnaturze punktu łączenia.
+
+Powyższy opis semantyki dopasowywania sygnatury jest dla wzorca sygnatury
+metody, jednak z pewnymi zastrzeżeniami stosuje się także do pozostałych typów
+wzorców sygnatury. 
+
+\subsubsection{Wzorzec sygnatury konstruktora}
+
+\begin{lstlisting}[style=grammar]
+<constructor_pattern> ::=
+    'this' '(' <parameters_pattern> ')'
+\end{lstlisting}
+
+Ponieważ w języku Nemerle konstruktory klas definiuje się za pomocą słowa
+kluczowego \lstinline!this!, tak też oznacza się je we wzorcu.
+
+Wzorzec dla sygnatury konstruktora, z oczywistych względów
+nie zawiera wzorca dla nazwy metody, jak również wzorca dla typu wyniku. 
+
+\subsubsection{Wzorzec sygnatury propercji}
+
+\begin{lstlisting}[style=grammar]
+<property_pattern> ::=
+  <id_pattern> '{' ['get' ';'] ['set' ';'] '}'
+     ':' <type_pattern>
+\end{lstlisting}
+
+Sygnatura propercji zawiera w sobie
+informację, które składniki propercji (chodzi o części \lstinline!get! i
+\lstinline!set!, patrz par. \ref{propercja}) mają być wybrane.  Należy zauważyć, że
+dla części \lstinline!get! propercji typ zwracanego wyniku jest identyczny z
+typem parametru dla składnika \lstinline!set!. Przykład \ref{wzorzec_propercji}
+w pierwszym wierszu przedstawia definicję z sygnaturą dla obu składników
+propercji, a w drugim wierszu tylko ze składnikiem \lstinline!set!. 
+
+\begin{lstlisting}[style=AspectJ,caption=Wzorzec sygnatury propercji,label=wzorzec_propercji]
+execution(public Person.Age {get;set}: int)
+execution(public Person.Age {set}: int)
+\end{lstlisting}
+
+Semantyka wzorca sygnatury propercji jest podobna do semantyki wzorca sygnatury
+metody. Zamiast wzorca dla zwracanego typu i parametrów zawiera jeden wzorzec
+typu -- wzorzec typu propercji. W przykładzie \ref{propercja} ma typ \lstinline!int!. Dodatkowo
+propercja zawiera informację, które składniki (\lstinline!get!,
+\lstinline!set!) mogą być dopasowane. Przy dopasowywaniu do sygnatury zapisu
+propercji sprawdzane jest czy wzorzec zawiera składnik \lstinline!set! i czy
+typ wyniku dopasowuje się do wzorca typu propercji.  Przy dopasowywaniu do
+sygnatury odczytu propercji, sprawdzane jest czy wzorzec zawiera składnik
+\lstinline!get!  i czy typ parametru dopasowuje się do wzorca typu propercji.
+
+
+\subsection{Przecięcie pierwotne \lstinline!args!}\label{ppargs}
+
+\begin{lstlisting}[style=grammar]
+<args_pointcut> ::=
+    'args' '(' <args_parameters> ')'
+
+<args_parameters> ::=
+    [<args_parameter> [{',' <args_parameter>}]]
+
+<args_parameter> ::=
+    <type_pattern>
+  | '..'
+  | <identifier>
+\end{lstlisting}
+
+Parametrem konstruktora \lstinline!args! może być identyfikator tożsamy z
+jednym z parametrów formalnych rady.
+
+Przecięcie pierwotne \lstinline!args! w odróżnieniu od \lstinline!execution!,
+może, oprócz wyznaczania zbioru punktów łaczenia, łączyć parametry formalne z
+wartościami w kontekście punktu łączenia. Przykład \ref{args_example}
+przedstawia użycie samego przecięcia \lstinline!args!.
+
+\begin{lstlisting}[style=AspectJ,caption=Args,label=args_example]
+using Nemerle.Aop;
+[aspect] public class SomeAspect {
+    before(s: string): args(int,s) {
+        System.Console.WriteLine(s);
+    }
+}
+\end{lstlisting}
+
+Jeżeli \lstinline!args! nie zawiera wystąpień parametrów formalnych rady, to
+semantyka jest taka jak dla wzorca parametrów opisanego przy okazji omawiania
+semantyki dla wzorca sygnatury metody.  Jeżeli, natomiast, we wzorcu jest
+wystąpienie któregoś parametru formalnego, to traktuje się je jako specjalny
+wzorzec typu. 
+
+Każdy parametr formalny musi mieć podany typ (tak jak każdy
+parametr formalny metody w języku Nemerle); w przykładzie \ref{args_example}
+parametr \lstinline!s! ma typ \lstinline!string!.  Wzorzec, który odpowiada
+wystąpieniu \lstinline!s! to \lstinline!string+!. Ogólnie jest to wzorzec
+podtypu typu parametru formalnego.
+
+Parametr, którego typ dopasowuje się do wzorca odpowiadającego parametrowi
+formalnemu rady, jest przekazywany z kontekstu wykonania punktu łączenia do
+rady. W ten sposób odbywa się ekspozycja kontekstu punktu łączenia.
+
+
+\subsection{Przecięcie pierwotne \lstinline!target!}\label{pptarget}
+
+\begin{lstlisting}[style=grammar]
+<target_pointcut> ::=
+    'target' '(' <target_parameter> ')'
+
+<target_parameter> ::=
+    <type_pattern>
+  | <identifier>
+\end{lstlisting}
+
+Parametrem konstruktora \lstinline!target!, tak jak konstruktora
+\lstinline!args!, może być identyfikator tożsamy z jednym z parametrów
+formalnych rady.
+
+\subsection{Przecięcia złożone}
+
+Wyrażenia można składać za pomocą trzech operatorów \lstinline!||!, \lstinline!&&! i 
+\lstinline*!*, wymienionych w kolejności
+rosnących priorytetów. Można także używać nawiasów okrągłych \lstinline!()!.
+
+\begin{lstlisting}[style=grammar]
+<pointcut> ::= 
+    <and_pointcut> 
+  | <and_pointcut> '||' <pointcut>
+
+<and_pointcut> ::= 
+    <neg_pointcut> 
+  | <neg_pointcut> '&&' <and_pointcut>
+
+<neg_pointcut> ::=
+    <primitive_pointcut>
+  | '!' <primitive_pointcut>
+\end{lstlisting}
+
+Dodatkowa produkcja z nieterminala \lstinline!primitive_pointcut!
+\begin{lstlisting}[style=grammar]
+<primitive_pointcut> ::= '(' <pointcut> ')'
+\end{lstlisting}
+wprowadza nawiasy do języka.
+
+
+
+
+\section{Wzorce typów}\label{wzorce_typow}
+
+Każde wyrażenie określające typ jest poprawnym wzorcem typu. Do takiego
+wzorca dopasuje się tylko jeden typ, dokładnie ten, który jest określany
+przez wyrażenie. Dodatkowe symbole, symbol \lstinline!?! i znak \lstinline!+!,
+pozwalają na definiowanie wzorców, do których dopasowuje się więcej
+niż jeden typ.
+
+\begin{lstlisting}[style=grammar]
+<type_pattern> ::=
+    <tuple_pattern>
+  | <tuple_pattern> '->' <type_pattern>
+\end{lstlisting}
+
+Operator \lstinline!->! łączy w prawo.
+
+\begin{lstlisting}[style=grammar]
+<tuple_pattern> ::=
+    <simpletype_pattern> [{'*' <simpletype_pattern>}]
+\end{lstlisting}
+
+Operator \lstinline!*! jest niełączny. Oznacza to, że każdy ze wzorców w
+przykładzie \ref{inty} oznacza inny typ.
+
+\begin{lstlisting}[style=AspectJ,label=inty,caption=Operator * jest niełączny]
+int * int * int
+(int * int) * int
+int * (int * int)
+\end{lstlisting}
+
+
+\begin{lstlisting}[style=grammar]
+<simpletype_pattern> ::=
+    <blank>
+  | <array_pattern>
+  | <class_pattern>
+  | 'void'
+  | '(' <type_pattern> ')'
+
+<blank> ::=
+    '?'
+\end{lstlisting}
+
+Symbol znaku zapytania \lstinline!?! oznacza dowolny typ.
+
+\begin{lstlisting}[style=grammar]
+    
+<array_pattern> ::=
+  'array' '[' [<nat_number_literal>',']<type_pattern>']'
+
+<nat_number_literal> ::=
+    { <digit> }
+
+\end{lstlisting}
+
+Definiując wzorzec dla typu tablicowego podaje się wymiar tablicy. W przypadku
+jego pominięcia przyjmuje się domyślną wartość 1. Przykład wzorca dla tablicy
+dwuwymiarowej: \lstinline!array[2,int]!.
+
+\subsection{Wzorzec klasy}
+
+\begin{lstlisting}[style=grammar]
+<class_pattern> ::=
+    <qualified_name_pattern> [<type_params>] ['+']
+\end{lstlisting}
+
+Wzorzec dla klasy składa się ze wzorca nazwy i opcjonalnie wzorców dla
+parametrów typowych klasy. W przeciwieństwie do wzorców klas z sygnatury (patrz
+par. \ref{wzorzec_nazwy_klasy}), wzorzec wyprowadzony z nieterminala
+\lstinline!class_pattern! może specyfikować parametry typowe dla klasy, na
+przykład \lstinline!list[string]!.
+
+\begin{lstlisting}[style=grammar]
+
+<qualified_name_pattern> ::=
+    <identifier> ['.' <qualified_name_pattern>]
+
+<type_params> ::=
+    '[' <type_pattern> [{',' <type_pattern>}] ']'
+\end{lstlisting}
+
+Wzorzec nazwy klasy składa się ze wzorca na identyfikator złożony i listy wzorców dla
+parametrów typowych klasy. Wzorzec
+\lstinline!System.Collections.Generic.List[?]! składa się ze wzorca
+identyfikatora złożonego \lstinline!System.Collections.Generic.List! i
+jednoelementowej list wzorców dla parametrów typowych \lstinline![?]!.  Gdy
+lista wzorców dla parametrów typowych jest pusta, ignoruje się typy parametrów
+klas podczas dopasowywania. Jest to zachowanie zgodne z semantyką AspectJ. Dla
+przykładu \lstinline!System.Collections.Generic.List! dopasuje się do typu
+\lstinline!System.Collections.Generic.List[string]!.
+
+Każdy człon wzorca identyfikatora złożonego może być albo dokładną nazwą
+członu, albo symbolem \lstinline!?!, który dopasowuje się do dowolnego członu.
+Symbol specjalny \lstinline!..! dopasowuje się do zera lub więcej członów.
+
+\subsection{Wzorzec podtypu}\label{wzorzec_podtypu}
+
+Programista dodając na końcu wzorca dla klasy znak \lstinline!+!, oznacza, że
+chodzi mu o podklasy. Do wzorca \lstinline!C+!, gdzie \lstinline!C! jest klasą,
+dopasowują się wszystkie podklasy \lstinline!C! jak i sama klasa \lstinline!C!.
+
+Ogólnie do wzorca \lstinline!W+! dopasowuje się typ \lstinline!T! wtedy i
+tylko wtedy, gdy istnieje typ \lstinline!S! taki, że \lstinline!T! jest
+podtypem \lstinline!S! i \lstinline!T! dopasowuje się do \lstinline!W!.
+
+
+\section{Rady}
+
+
+\begin{lstlisting}[style=grammar]
+<type_member> ::= 
+    <advice_definition>
+
+<advice_definition> ::= 
+    <advice_header> <advice_body>
+
+<advice_header> ::=
+    <before_advice> 
+  | <around_advice> 
+  | <after_advice>
+\end{lstlisting}
+
+\begin{lstlisting}[style=grammar]
+<advice_body> ::=
+    <nemerle_method_body>
+
+<formal_parameters> ::= 
+    [<formal_parameter> [{',' <formal_parameter>}]]
+
+<formal_parameter> ::=
+    <identifier> ':' <type_pattern>
+\end{lstlisting}
+
+Z nieterminala \lstinline!identifier! można wyprowadzić niepusty ciąg znaków
+zawierających litery alfabetu, cyfry, podkreślniki i apostrofy, ale nie
+zaczynających się od cyfry. Kategorie syntaktyczne
+\lstinline!nemerle_method_body!  i \lstinline!nemerle_type! zawierają
+odpowiednio dopuszczalne składniowo przez język Nemerle ciała metod i wyrażenia
+typowe. Ich dokładne definicje można znaleźć w dokumentacji języka Nemerle
+\cite{nemerle}.
+
+Dla każdej rady można podać parametry formalne.  Parametry formalne oprócz
+tego, że są dostępne w ciele rady (jak parametry formalne metody), dostępne są
+także dla wyrażenia przecięcia. Przecięcie definiuje ich wiązanie z wartościami
+w kontekście punktu łączenia. Robi się to za pomocą przecięć pierwotnych
+\lstinline!args()! (par. \ref{ppargs}) i \lstinline!target()! (par. \ref{pptarget}). 
+
+
+Rada implementuje akcję, która ma być wykonana w punkcie łączenia. Zbiór
+punktów łączenia wyznaczany jest przez przecięcie, które towarzyszy każdej
+radzie. Można wyróżnić trzy rodzaje rad pod względem tego, jak dodawana jest
+akcja do punktu łączenia. Rada przed dodaje akcję przed wykonaniem punktu
+łączenia, rada \emph{po} po wykonaniu punktu łączenia, a w przypadku rady
+dookoła programista ma kontrolę kiedy a nawet czy punkt łączenia, na przykład
+wykonanie metody, będzie wykonany.
+
+\subsection{Rada przed}
+\begin{lstlisting}[style=grammar]
+<before_advice> ::= 
+  'before' '(' <formal_parameters> ')' ':'<pointcut>
+\end{lstlisting}
+
+Rada przed jest najprostszym typem rady. Nagłówek podzielony jest na dwie
+części: słowo kluczowe \lstinline!before! z listą parametrów formalnych i
+przecięcie występujące po dwukropku.  Przykład \ref{before_advice} przedstawia
+radę, która wykona się przed każdym wykonaniem metody \lstinline!AddItem! w
+klasie \lstinline!Refrigerator!. Akcją jest wypisanie na ekran informacji o tym
+co zostanie dodane do jakiej lodówki. Parametry formalne \lstinline!item! i
+\lstinline!refrigerator! są eksponowane przez przecięcie, dzięki czemu możliwe
+jest wypisanie co dokładnie jest dodawane do lodówki.
+
+\begin{lstlisting}[style=AspectJ,caption=Rada przed,label=before_advice]
+before(item: Food, refrigerator: Refrigerator): 
+    execution(Refrigerator.AddItem(Food):void) 
+    && args(item) && target(refrigerator) 
+{
+    print(item.ToString() 
+        + " is about to be added to " 
+        + refrigerator.ToString());
+}
+\end{lstlisting}
+
+
+\subsection{Rada po}
+
+\begin{lstlisting}[style=grammar]
+<after_advice> ::= 
+    'after' '(' <formal_parameters> ')' ':' <pointcut>
+  | 'after' '(' <formal_parameters> ')' 'returning' 
+    '(' <formal_parameter> ')' ':' <pointcut>
+  | 'after' '(' <formal_parameters> ')' 'throwing' 
+    '(' <formal_parameter> ')' ':' <pointcut>
+\end{lstlisting}
+
+Rada po definiowana jest za pomocą słowa kluczowego \lstinline!after!. Wyróżnia
+się trzy rodzaje rady po. Podział wynika ze sposobu w jaki mogą zakończyć się
+punkty łączenia, na przykład wykonanie metody.  Metoda może zakończyć się w
+trybie normalnym, bądź zgłosić wyjątek. Ten sam podział stosuje się także do
+pozostałych typów punktów łączenia.
+
+
+Rada typu po ma dostęp jedynie do referencji
+do wyniku zwróconego przez przechwycone zdarzenie, ale nie może tej referencji
+zmienić (referencja jest przekazana przez wartość, oczywiście można zmienić
+stan obiektu, na który ta referencja wskazuje). Analogicznie jest z
+wariantem rady po zgłoszeniu wyjątku (after throwing). W tym przypadku
+dostępna jest referencja do zgłoszonego wyjątku.
+
+Rada \lstinline!after() returning! wykona się tylko po punktach łączenia, które
+zakończyły się poprawnie -- bez zgłoszenia wyjątku. Przykład
+\ref{after_returning_advice} zawiera radę tego typu, która wypisze informacje
+tylko i pomyślnie dodanych artykułach do lodówki.
+
+\begin{lstlisting}[style=AspectJ,caption=Rada after returning,label=after_returning_advice]
+after(item: Food, refrigerator: Refrigerator) returning: 
+    execution(Refrigerator.AddItem(Food):void) 
+    && args(item) && target(refrigerator) 
+{
+    print("added " + item.ToString() 
+        + " to " + refrigerator.ToString());
+}
+\end{lstlisting}
+
+Drugim typem rady po jest rada after() throwing. Akcja tej rady wykonywana jest
+tylko wtedy, gdy w punkcie łączenia zostaje zgłoszony wyjątek. Rada w
+przykładzie \ref{after_throwing_advice} wypisze informacje o nieudanej próbie
+dodania artykułu do lodówki.
+
+\begin{lstlisting}[style=AspectJ,caption=Rada after throwing,label=after_throwing_advice]
+after(item: Food, refrigerator: Refrigerator) throwing: 
+    execution(Refrigerator.AddItem(Food):void) 
+    && args(item) && target(refrigerator) 
+{
+    print("failed to add " + item.ToString() 
+        + " to " + refrigerator.ToString());
+}
+\end{lstlisting}
+
+Trzecim typem rady po jest rada, która wykonuje się bez względu na to czy
+zgłoszono wyjątek.  W przykładzie \ref{semantic_after} rada wypisuje, że
+próbowano dodać artykuł do lodówki, bo nie wiadomo czy operacja zakończyła się
+pomyślnie -- bez zgłoszenia wyjątku.
+
+\begin{lstlisting}[style=AspectJ,caption=Rada after,label=after_throwing_advice]
+after(item: Food, refrigerator: Refrigerator): 
+    execution(Refrigerator.AddItem(Food):void) 
+    && args(item) && target(refrigerator) 
+{
+    print("tried to add " + item.ToString() 
+        + " to " + refrigerator.ToString());
+}
+\end{lstlisting}
+
+Rada \lstinline!after()! (bez \lstinline!returning! ani \lstinline!throwing!)
+nie daje dostępu do zwróconego wyniku ani do ewentualnego wyjątku. Dostęp do
+zwróconego wyniku w punkcie łączenia, na przykład wynik wykonania metody, można
+uzyskać za pomocą rady po: \lstinline!after() returning(result: Type)!.
+
+\begin{lstlisting}[style=AspectJ,caption=Dostęp do wyniku metody,label=after_returning_result]
+after(item: Food, refrigerator: Refrigerator) 
+returning(removed:bool): 
+    execution(Refrigerator.Remove(Food):bool) 
+    && args(item) && target(refrigerator) 
+{
+    when(removed)
+        print(item.ToString() + " was removed from " 
+        + refrigerator.ToString());
+}
+\end{lstlisting}
+
+W przykładzie \ref{after_returning_result} rada wypisze informacje tylko wtedy,
+gdy artykuł zostanie rzeczywiście usunięty; wynik operacji \lstinline!Remove!
+jest \lstinline!true! o ile artykuł był w lodówce i \lstinline!false! w
+przeciwnym wypadku.
+
+Wynik przekazywany jest do rady przez wartość; rada w przykładzie
+\ref{after_returning_result} nie mogłaby go zmienić (np. z \lstinline!false! na
+\lstinline!true!).
+
+Deklaracja \lstinline!after() returning(id: Type)! dodaje dodatkowe
+ograniczenie na punkty łączenia wybrane przez przecięcie. Typ zwracanego wyniku
+w sygnaturze punktu łączenia musi być podtypem typu w części
+\lstinline!returning()!. W konsekwencji ten typ rady po nie wybierze wykonań
+konstruktorów, bo nie mają typu zwracanego wyniku w sygnaturze.
+
+W radzie \lstinline!after() throwing! można wyspecyfikować konkretny typ
+wyjątku i otrzymać go jako parametr.  Rada w przykładzie
+\ref{after_throwing_with_param} zostanie wykonana tylko w przypadku zgłoszenia
+w metodzie \lstinline!Add! wyjątku typu \lstinline!FullException!. Rada ta nie
+zostałaby wywołana w przypadku zgłoszenia \lstinline!System.Exception!
+(\lstinline!System.Exception! to klasa z biblioteki standardowej i na pewno nie
+jest podtypem \lstinline!FullException!).
+
+\begin{lstlisting}[style=AspectJ,caption=Dostęp do wyjątku,label=after_throwing_with_param]
+after(item: Food, refrigerator: Refrigerator) 
+throwing(ex:FullException):
+    execution(Refrigerator.AddItem(Food):void) 
+    && args(item) && target(refrigerator) 
+{
+    print(item.ToString() + " was not added because " 
+    + refrigerator.ToString() +
+    " was already full " + ex.ToString() );
+}
+\end{lstlisting}
+
+Rada \lstinline!after() throwing! nie przechwytuje wyjątku w sensie obsługi. Po
+wykonaniu rady wyjatek wędruje dalej w górę stosu. Aby obsłużyć wyjątek,
+należałoby skorzystać z rady dookoła.
+
+
+\subsection{Rada dookoła}
+
+\begin{lstlisting}[style=grammar]
+
+<around_advice> ::=
+  'around' '(' <formal_parameters> ')' ':'<ret_type> 
+    ':' <pointcut>
+
+  <ret_type> ::= <type_pattern>
+\end{lstlisting}
+
+Ostatnim i najogólniejszym rodzajem rady jest rada dookoła. Za pomocą tej rady
+można zrobić wszystko to, co za pomocą innych rad, a ponadto zmienić wynik
+zwrócony z punktu łączenia albo obsłużyć wyjątek.
+
+Definicja rady dookoła musi zawierać typ zwracanego wyniku. To
+jest jedyny rodzaj rady, który może zmienić wartość wyniku modyfikowanego
+punktu łączenia. Rady przed i po nie mogą zmienić zwróconego wyniku i typ zwracanego
+wyniku w ciele to \lstinline!void!. 
+
+\begin{lstlisting}[style=AspectJ,caption=Rada dookoła,label=around_power]
+around(item: Food, refrigerator: Refrigerator): void :
+    execution(Refrigerator.AddItem(Food):void) 
+    && args(item) && target(refrigerator) 
+{
+    print("before\n")
+    try{
+        def res = proceed(item,refrigerator);
+        print("after returning\n");
+        res
+    } catch {
+        | ex is FullException =>
+            print("after throwing " + ex.ToString())
+        | _ =>
+            print("after throwing")
+    } finally {
+        print ("after (returning or throwing)\n")
+    }
+}
+\end{lstlisting}
+
+Najważniejszą cechą wyróżniającą radę dookoła od pozostałych jest możliwość
+użycia instrukcji \lstinline!proceed!, która wykonuje punkt łączenia. Typy
+parametrów do proceed są dokładnie takie same jak typy parametrów formalnych
+rady. W przykładzie \ref{around_power} są to \lstinline!Food! i
+\lstinline!Refrigerator!. Nic nie stoi na przeszkodzie, żeby zmodyfikować
+argumenty przed przekazaniem do punktu łączenia (np. metody). Wynikiem
+wywołania \lstinline!proceed! jest wynik punktu łączenia.  Metoda Add zwraca
+\lstinline!void!, więc w tym przypadku rezultatem jest jedyna wartość tego typu
+-- \lstinline!()!. Ogólnie, rada może zwrócić wynik wywołania
+\lstinline!proceed!, zmodyfikować go przed zwróceniem lub zwrócić zupełnie inna
+wartość.
+
+Rada dookoła musi specyfikować typ zwracanego wyniku. W przykładzie
+\ref{around_power} jest to \lstinline!void!. Zbiór punktów łączenia, na których
+działa rada, jest ograniczany do tych, w których sygnaturach typ wyniku jest
+równy typowi rady. W konsekwencji rada \lstinline!around! nie działa na
+wykonaniach konstruktorów, które nie mają zwracanego typu w sygnaturze.
+Zapewnia to także, że wynik \lstinline!proceed! jest zawsze zgodny z typem wyniku
+zwracanego przez radę.
+
+\subsection{Rady parametryzowane typami}
+
+Język Nemerle implementuje polimorfizm parametryczny (par. \ref{polim_parametryczny}),
+czyli pozwala na definiowanie klas i metod parametryzowanych typami. Żeby modyfikować
+zachowanie takich metod, nie trzeba od razu korzystywać z parametrozowanych rad. Przypomnę
+definicję interfejsu \lstinline!Set! z paragrafu \ref{polim_parametryczny}.
+
+
+\begin{lstlisting}[style=AspectJ,caption=Interfejs parametryzowalny,label=polim_interfejs]
+interface Set[E] where E: IComparable {
+  Add(e: E): void;
+  Remove(e: E): void;
+  Contains(e: E): bool;
+  AddAll[T](xs: list[T]) where T:E;
+}
+\end{lstlisting}
+
+W celu wypisania informacji, jaki element jest dodawany do zbioru za pomocą 
+operacji \lstinline!Add!, można skorzystać ze
+zwykłej rady. O parametrze metody \lstinline!Add! wiadomo tyle, że jest to podtyp
+\lstinline!IComparable!. \lstinline!Add! dopasowuje się do przecięcia
+\lstinline!args(e)! z przykładu \ref{r.non_polym_advice}, ponieważ \lstinline!object! jest nadtypem
+\lstinline!IComparable! (przypominam, że wystąpienie \lstinline!e! traktowane jest jako wzorzec \lstinline!object+!).
+
+\begin{lstlisting}[style=AspectJ,caption=Rada modyfikująca parametryzowalną metodę,label=r.non_polym_advice]
+after(e:object) returning:execution(Set+.Add(..))&&args(e)
+{
+    print(e.ToString() + " added to set.\n");
+}
+\end{lstlisting}
+
+Gdyby potrzebny był dostęp do operacji interfejsu IComparable, można
+posłużyć się takim nagłówkiem rady:
+
+\begin{lstlisting}[style=AspectJ]
+after(e:IComparable) returning: ...
+\end{lstlisting}
+
+Przechwycenie metody \lstinline!AddAll! (patrz przykład
+\ref{polim_interfejs}) z jednoczesnym dostępem do jej argumentu jest trudniejsze. Typem parametru operacji
+\lstinline!AddAll! jest \lstinline!list[T]! gdzie \lstinline!T! jest podtypem
+\lstinline!E!. Z nagłówka klasy wiadomo, że \lstinline!E! jest podtypem
+\lstinline!IComparable!, co daje pewność, że \lstinline!T! jest podtypem
+\lstinline!IComparable!.  Niemniej jednak, przecięcie
+\lstinline!args(list[IComparable]+)! nie wyznacza punku łączenia wykonanie metody \lstinline!AddAll!, bo
+\lstinline!list[IComparable]! nie jest nadtypem \lstinline!list[T]!, gdzie \lstinline!T! 
+jest pdotypem \lstinline!IComparable!;
+klasa \lstinline!list[T]! nie jest kowariantna (patrz par. \ref{nemerle.kowariancja}).
+
+Rozwiązaniem jest użycie wzorca typu. 
+\begin{lstlisting}[style=AspectJ]
+after(e:list[IComparable+]) returning: ...
+\end{lstlisting}
+
+Jeżeli nie ma potrzeby używania operacji z \lstinline!IComparable! wystarczy:
+\begin{lstlisting}[style=AspectJ]
+after(e:list[?]) returning: ...
+\end{lstlisting}
+
+Rozważmy jeszcze jeden problem. Załużmy, że chcemy zastąpić wykonanie
+metody \lstinline!Copy! z przykładu \ref{util.copy}.
+
+\begin{lstlisting}[style=AspectJ,caption=Polimorficzna metoda,label=util.copy]
+Util {
+  static public Copy[E](src: array[E], dst: List[E]): void {
+    ...
+  }
+}
+\end{lstlisting}
+
+\begin{lstlisting}[style=AspectJ,caption=Naiwna implementacja,label=naive]
+around(src: array[?],dst: List[?]):void
+:execution(Util.Copy(..):void)&&args(src,dst)
+{
+ ... 
+}
+\end{lstlisting}
+
+Przykład \ref{naive} przedstawia naiwną implementację rady zastępującej \lstinline!Copy!.
+Przecięcie tej rady zawiera wykonanie metody \lstinline!Copy!, jednak typy
+parametrów nie pozwolą na kopiowanie elementów z tablicy do listy. Przy tak
+zdefiniowanych parametrach formalnych \lstinline!src! to tablica elementów
+jakiegoś typu, a \lstinline!dst! to lista elementów jakiegoś innego typu. Nie
+ma tu żadnej informacji, że oba obiekty przechowują elementy tego samego typu,
+więc próba zapisania elementu wyjętego z \lstinline!src! do \lstinline!dst!
+spowoduje błąd kompilacji. Poprawne rozwiązanie przedstawione jest w przykładzie
+\ref{polymorphic_around}.
+
+\begin{lstlisting}[style=AspectJ,caption=Rada z parametrami typowymi,label=polymorphic_around]
+around[T](src: array[T],dst: List[T]):void
+:execution(Util.Copy(..):void)&&args(src,dst)
+{
+ ... 
+}
+\end{lstlisting}
+
+Użycie we wzorcach dla parametrów formalnych zmiennej typowej \lstinline!T! pozwala
+na kopiowania z \lstinline!src! do \lstinline!dst!, bo kompilator wie, że oba obiekty przechowują elementy
+tego samego typu. 
+
+Pondadto, przecięcie \lstinline!args(src,dst)! zawierać może tylko
+takie metody, które mają typy parametrów \lstinline!array[]! i \lstinline!List[]! oraz takie same typy elementów.
+Na przykład, \lstinline!args(src,dst)! nie zawiera wykonania metod o sygnaturze:
+\begin{lstlisting}[style=AspectJ]
+Copy(src: array[int], dst: List[float]): void {
+\end{lstlisting}
+gdyż \lstinline!src! i \lstinline!dst! przechowują elementy różnych typów.
+
+Składnia specyfikowania parametrów typowych dla rady dookoła zdefiniowana
+jest przez poniższą dodatkową produkcję z nieterminala \lstinline!around_advice!.
+
+\begin{lstlisting}[style=AspectJ]
+<around_advice> ::=
+    'around' <type_parameters> '(' <formal_parameters> ')' 
+      ':' <ret_type> ':' <pointcut> <where_constraints>
+
+\end{lstlisting}
+
+Uważny czytelnik zauważył nowy element produkcji poza \lstinline!<type_parametrs>!, 
+a mianowicie \lstinline!where_constraints!. Z tego nieterminala można wyprowadzić
+ograniczenia dla zminnych typowych. Użycie zademonstruję na lekko zmienionej metodzie
+\lstinline!Copy!.
+
+\begin{lstlisting}[style=AspectJ,caption=Polimorficzna metoda Copy,label=util.copy.modified]
+Util {
+  static public Copy[E](src: array[E], dst: List[E]): void
+  where E : IComparable {
+    ...
+  }
+}
+\end{lstlisting}
+
+Metoda \lstinline!Copy! z przykładu \ref{util.copy.modified} nakłada
+warunek na zmienną, że \lstinline!E! jest podtypem \lstinline!IComparable!.
+Do rady dookoła można dodać taki sam warunek i uzyskać dostęp do metod z
+interfejsu \lstinline!IComprarable!. Przedstawia to przykład \ref{polymorphic_around_with_where}.
+
+\begin{lstlisting}[style=AspectJ,caption=Rada polimorficzna,label=polymorphic_around_with_where]
+around[T](src: array[T],dst: List[T]):void
+:execution(Util.Copy(..):void)&&args(src,dst)
+where T: IComparable
+{
+ ... 
+}
+\end{lstlisting}
+
+Definicje składni dodawania parametrów typowych dla pozostałych rad
+znajdują się w dodatku A.
+
+
+
+% REALIZACJA
+\chapter{Realizacja} 
+
+Język Nemerle został rozszerzony o konstrukcje programowania aspektowego za
+pomocą systemu metaprogramowania wbudowanego w język. W efekcie kod źródłowy
+kompilatora nie zawiera fragmentów implementujących programowanie \textsc{aop}. Kod
+implementujący język Nemerle.Aop jest kompilowany do biblioteki
+Nemerle.Aop.dll. Aby korzystać z aspektów w języku Nemerle wystarczy dołączyć
+tę bibliotekę podczas kompilacji (patrz przykład \ref{compilation}).
+\begin{lstlisting}[style=AspectJ,caption=Kompilacja programu z aspektami,label=compilation]
+    ncc Plik1.n Plik2.n -r Nemerle.Aop.dll
+\end{lstlisting}
+
+
+\section{Analiza składniowa}
+
+Do budowy analizatora składniowego wykorzystałem metodę kombinatorów
+\cite{FunParsers,FunParsing}.  Kod analizatora składniowego wokananego tą
+metodą przypomina gramatykę języka w rozszerzonej notacji \textsc{bnf}.
+
+\chapter{Przykłady}
+
+\section{Zarządzanie transakcjami}
+
+
+
+
+\appendix
+
+\chapter{Gramatyka języka Nemerle.Aop}
+
+\section{Składnia rady}
+
+\begin{lstlisting}[style=grammar]
+<type_member> ::= 
+    <advice_definition>
+
+<advice_definition> ::= 
+    <advice_header> <advice_body>
+
+<advice_header> ::=
+    <before_advice> 
+  | <around_advice> 
+  | <after_advice>
+
+<before_advice> ::= 
+    'before' '(' <formal_parameters> ')' ':' <pointcut>
+  | 'before' <type_parameters> '(' <formal_parameters> ')' 
+    ':' <pointcut> <where_constraints>
+
+<around_advice> ::=
+    'around' '(' <formal_parameters> ')' ':' <ret_type> 
+    ':' <pointcut>
+  | 'around' <type_parameters> '(' <formal_parameters> ')' 
+    ':' <ret_type> ':' <pointcut> <where_constraints>
+
+<after_advice> ::= 
+    'after' '(' <formal_parameters> ')' ':' <pointcut>
+  | 'after' '(' <formal_parameters> ')' 'returning' 
+    '(' <formal_parameter> ')' ':' <pointcut>
+  | 'after' '(' <formal_parameters> ')' 'throwing' 
+    '(' <formal_parameter> ')' ':' <pointcut>
+  | 'after' <type_parameters> '(' <formal_parameters> ')' 
+    ':' <pointcut> <where_constraints>
+  | 'after' <type_parameters> '(' <formal_parameters> ')' 
+    'returning' '(' <formal_parameter> ')' ':' <pointcut>
+    <where_constraints>
+  | 'after' <type_parameters> '(' <formal_parameters> ')' 
+    'throwing' '(' <formal_parameter> ')' ':' <pointcut>
+    <where_constraints>
+\end{lstlisting}
+
+Nieterminale \lstinline!type_parameters! i \lstinline!where_constraints!
+są zdefiniowane w gramatyce języka Nemerle \cite{nemerle}.
+
+\begin{lstlisting}[style=grammar]
+<advice_body> ::=
+    <nemerle_method_body>
+
+<formal_parameters> ::= 
+    [<formal_parameter> [{',' <formal_parameter>}]]
+
+<formal_parameter> ::=
+    <identifier> ':' <type_pattern>
+
+<ret_type> ::= <type_pattern>
+\end{lstlisting}
+
+Kategoria syntaktyczna \lstinline!identifier! składa się z niepustych ciągów
+znaków zawierających litery alfabetu, cyfry, podkreślniki i apostrofy, ale nie
+zaczynających się od cyfry. Kategorie syntaktyczne
+\lstinline!nemerle_method_body!  i \lstinline!nemerle_type! zawierają
+odpowiednio dopuszczalne składniowo przez język Nemerle ciała metod i wyrażenia
+typowe. Ich dokładne definicje można znaleźć w dokumentacji języka Nemerle
+\cite{nemerle}.
+
+\section{Składnia definicji przecięcia}
+
+
+\begin{lstlisting}[style=grammar]
+<pointcut> ::= 
+    <and_pointcut> 
+  | <and_pointcut> '||' <pointcut>
+
+<and_pointcut> ::= 
+    <neg_pointcut> 
+  | <neg_pointcut> '&&' <and_pointcut>
+
+<neg_pointcut> ::=
+    <primitive_pointcut>
+  | '!' <primitive_pointcut>
+\end{lstlisting}
+
+\begin{lstlisting}[style=grammar]
+<primitive_pointcut> ::=
+    '(' <pointcut> ')'
+  | <execution_pointcut>
+  | <args_pointcut>
+  | <target_pointcut>
+\end{lstlisting}
+
+
+\subsection{Składnia dla konstruktora \lstinline!execution!}\label{class_in_signature_syntax}
+
+\begin{lstlisting}[style=grammar]
+<execution_pointcut> ::=
+    'execution' '(' <signature_pattern> ')'
+
+<signature_pattern> ::=
+    ['[' <attributes_pattern>']'] [<modifiers_pattern>] 
+    ['static'] <class_in_signature> <member_pattern>
+
+<class_in_signature> ::=
+    [{<id_pattern> ('.' | '..')}]  [<id_pattern> '+' '.']
+\end{lstlisting}
+
+\begin{lstlisting}[style=grammar]
+<member_pattern> ::=
+    <method_pattern>
+  | <property_pattern>
+  | <constructor_pattern>
+\end{lstlisting}
+
+
+\begin{lstlisting}[style=grammar]
+<method_pattern> ::=
+    <id_pattern> '(' <parameters_pattern> ')' ':' <type_pattern>
+
+<property_pattern> ::=
+    <id_pattern> '{' ['get' ';'] ['set' ';'] '}' 
+    ':' <type_pattern>
+
+<constructor_pattern> ::=
+    'this' '(' <parameters_pattern> ')'
+\end{lstlisting}
+
+
+\begin{lstlisting}[style=grammar]
+<attributes_pattern> ::=
+    <type_pattern> [{',' <type_pattern>}]    
+
+<modifiers_pattern> ::=
+    [{['!'] <modifier>}]
+
+<modifier> ::=
+    'public'
+  | 'protected'
+  | 'internal'
+  | 'private'
+  | 'static'
+
+<parameters_pattern> ::=
+    [<parameter_pattern> [{',' <parameter_pattern>}]]
+
+<parameter_pattern> ::=
+    <type_pattern>
+  | '..'
+\end{lstlisting}
+
+
+\subsection{Składnia dla konstruktora \lstinline!args!}
+
+\begin{lstlisting}[style=grammar]
+<args_pointcut> ::=
+    'args' '(' <args_parameters> ')'
+
+<args_parameters> ::=
+    [<args_parameter> [{',' <args_parameter>}]]
+
+<args_parameter> ::=
+    <type_pattern>
+  | '..'
+  | <identifier>
+\end{lstlisting}
+
+Parametrem konstruktora \lstinline!args! może być identyfikator tożsamy z
+jednym z parametrów formalnych rady (\lstinline!formal_parameter! zdefiniowany
+wyżej).
+
+\subsection{Składnia dla konstruktora \lstinline!target!}
+
+\begin{lstlisting}[style=grammar]
+<target_pointcut> ::=
+    'target' '(' <target_parameter> ')'
+
+<target_parameter> ::=
+    <type_pattern>
+  | <identifier>
+\end{lstlisting}
+
+Parametrem konstruktora \lstinline!target!, tak jak konstruktora
+\lstinline!args!, może być identyfikator tożsamy z jednym z parametrów
+formalnych rady.
+
+\section{Składnia wzorców typów}
+
+\begin{lstlisting}[style=grammar]
+<type_pattern> ::=
+    <tuple_pattern>
+  | <tuple_pattern> '->' <type_pattern>
+\end{lstlisting}
+
+
+\begin{lstlisting}[style=grammar]
+<tuple_pattern> ::=
+    <simpletype_pattern> [{'*' <simpletype_pattern>}]
+\end{lstlisting}
+
+Operator \lstinline!*! jest niełączny. Oznacza to, że każdy ze wzorców w
+przykładzie \ref{inty} oznacza inny typ.
+
+\begin{lstlisting}[style=AspectJ,label=inty,caption=Operator * jest niełączny]
+int * int * int
+(int * int) * int
+int * (int * int)
+\end{lstlisting}
+
+
+\begin{lstlisting}[style=grammar]
+<simpletype_pattern> ::=
+    <blank>
+  | <array_pattern>
+  | <class_pattern>
+  | 'void'
+  | '(' <type_pattern> ')'
+
+<blank> ::=
+    '?'
+\end{lstlisting}
+
+\begin{lstlisting}[style=grammar]
+<class_pattern> ::=
+    <qualified_name_pattern> [<type_params>] ['+']
+\end{lstlisting}
+
+
+\begin{lstlisting}[style=grammar]
+
+<qualified_name_pattern> ::=
+    <identifier> ['.' <qualified_name_pattern>]
+\end{lstlisting}
+
+
+\begin{lstlisting}[style=grammar]
+
+<type_params> ::=
+    '[' <type_pattern> [{',' <type_pattern>}] ']'
+    
+<array_pattern> ::=
+    'array' '[' [<nat_number_literal> ','] <type_pattern> ']'
+
+<nat_number_literal> ::=
+    { <digit> }
+
+
+\end{lstlisting}
+
+Definiując wzorzec dla typu tablicowego podaje się wymiar tablicy. W przypadku
+jego pominięcia przyjmuje się domyślną wartość 1. Przykład wzorca dla tablicy
+dwuwymiarowej: \lstinline!array[2,int]!.
+
+\chapter{Zawartość dołączonej płyty CD}
+
+todo
+
+\begin{thebibliography}{99}
+		 
+\bibitem{aosd}
+Robert E. Filman, Tzilla Elrad, Siobhan Clarke, Mehmet Aksit: {\it Aspect-Oriented Software Development}, Addison-Wesley 2005
+  
+\bibitem{AspectPatterns}
+Jan Honnemann, Gregor Kiczales: {\it Design Pattern Implementation in Java and AspectJ}, OOPSLA 2002
+  
+\bibitem{CodeAsDesign}
+Jack W. Reeves: {\it What Is Software Design?}, http://www.bleading-edge.com/Publications/C++Journal/abstract.htm (był dostępny w czasie pisania pracy)
+
+\bibitem{MultiDim}
+P Tarr, H Ossher, W Harrison and SM Sutton, Jr.: {\it N degrees of Separation: Multidimensional separation of concerns}, Proc. ICSE 99
+
+\bibitem{WieloWym}
+Andrzej Krzywda, Tomasz Nazar, Ewa Gurbiel: {\it Wielowymiarowe rozdzielanie zagadnień, a podejście komponentowe}, KKIO 2004
+
+\bibitem{AdviceWeaving}
+Erik Hilsdale, Jim Hugunin: {\it Advice weaving in AspectJ}, Procidings of 3rd International AOSD Conference
+
+\bibitem{JVMSupport}
+Alexandre Vasseur, Joakim Dahlstedt: {\it Java Virtual Machine support for Aspect-Oriented Programming}, AOSD 2006
+
+\bibitem{GoF}
+Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides: {\it Design Patterns: Elements of Reusable Object-Oriented Software}, Addison-Wesley 1995
+
+\bibitem{hist}
+Cristina Videira Lopes: {\it Aspect-Oriented Programming: An Historical Perspective (What's in a Name?)}, ISR Technical Report \# UCI-ISR-02-5
+
+\bibitem{FunParsers}
+Jeroen Fokker. Functional Parsers: {\it Advanced functional programming}, strony 1-24. Springer-Verlag, 1995. 
+
+\bibitem{FunParsing}
+Graham Hutton: {\it Higher-Order Functions for Parsing}, Journal of Functional Programming, lipiec 1992.
+
+\bibitem{skalski}
+Kamil Skalski: {\it Syntax-extending and type-reflecting macros in an object-oriented language}
+Praca magisterska, Instytut Informatyki Uniwersytetu Wrocławskiego, Wrocław 2005
+
+\bibitem{moskal}
+Michał Moskal: {\it Type inference with deferral}
+Praca magisterska, Instytut Informatyki Uniwersytetu Wrocławskiego, Wrocław 2005
+
+\bibitem{AspectJ}
+Strona domowa projektu AspectJ: {\it http://eclipse.org/aspectj}
+
+\bibitem{nemerle}
+Strona domowa projektu Nemerle: {\it http://nemerle.org}
+
+\bibitem{jbossaop}
+Strona domowa projektu JBoss AOP: {\it http://labs.jboss.com/jbossaop}
+
+\end{thebibliography}
+\end{document}	

Added: nemerle/trunk/snippets/aop/src/dev_macros/parser_operators.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/aop/src/dev_macros/parser_operators.n	Sun Jul  1 15:23:10 2007
@@ -0,0 +1,30 @@
+#pragma indent
+
+// right priority < (left(=>) = 145) to allow: parser <@ x => M
+[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Aop.DevMacros", "<@", false, 145, 144)] 
+[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Aop.DevMacros", "<%", false, 142, 142)] 
+
+[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Aop.DevMacros", "<|>", false, 147, 146)]
+[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Aop.DevMacros", "<*>", false, 148, 147)] 
+[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Aop.DevMacros", "*>", false, 148, 147)] 
+[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Aop.DevMacros", "<*", false, 148, 147)] 
+
+using Nemerle.Compiler
+using Nemerle.IO
+
+namespace Nemerle.Aop.DevMacros
+
+    [Nemerle.MacroUsage(Nemerle.MacroPhase.BeforeTypedMembers, Nemerle.MacroTargets.Method)]\
+    macro Reversed(_: TypeBuilder, mb: ParsedMethod) 
+        mb.Body = match (mb.Body)
+            | <[{..$sequence}]> => 
+                def reversed = sequence.Rev()
+                <[{..$reversed}]>
+            | x => x
+
+    macro ReversedSequence(body) syntax ("reversed", body) 
+        match (body)
+            | <[{..$sequence}]> => 
+                def reved = sequence.Rev()
+                <[{..$reved}]>
+            | x => x

Added: nemerle/trunk/snippets/aop/src/ftests/2_aspects_positive.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/aop/src/ftests/2_aspects_positive.n	Sun Jul  1 15:23:10 2007
@@ -0,0 +1,33 @@
+using Nemerle.Aop;
+using Nemerle.IO;
+
+public class Foo {
+
+	public MethodOfFoo(): void {
+		print("From base method\n");
+	}
+
+	public static Main(): void {
+		Foo().MethodOfFoo();
+	}
+
+}
+
+[aspect()]
+public class Aspect {
+
+	after() returning: execution(Foo.MethodOfFoo(): void) {
+		print("From advice\n");
+	}
+}
+
+[aspect()]
+public class SomeOtherAspect {
+}
+
+/*
+BEGIN-OUTPUT
+From base method
+From advice
+END-OUTPUT
+*/

Added: nemerle/trunk/snippets/aop/src/ftests/Target_positive.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/aop/src/ftests/Target_positive.n	Sun Jul  1 15:23:10 2007
@@ -0,0 +1,37 @@
+/* This tests getting reference to target from an Invocation
+   parameter of an advice. */
+
+using Nemerle.Aop;
+using Nemerle.IO;
+
+public class C {
+    public mutable F: int;
+    public this() { F = 0; }
+    public Method(): void {print("method\n")}
+}
+
+[aspect] class Aspecto {
+
+    after(inv: Nemerle.Aop.Invocation) returning: execution(C.Method(): void) {
+        (inv.Target:> C).F = 1;
+        print("advice\n");
+    }
+}
+
+public class Main {
+    public static Main(): void {
+        def o = C();
+        print(o.F.ToString() + "\n");
+        o.Method();
+        print(o.F.ToString() + "\n");
+    }
+}
+
+/*
+BEGIN-OUTPUT
+0
+method
+advice
+1
+END-OUTPUT
+*/

Added: nemerle/trunk/snippets/aop/src/ftests/after/after_positive.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/aop/src/ftests/after/after_positive.n	Sun Jul  1 15:23:10 2007
@@ -0,0 +1,29 @@
+using Nemerle.Aop;
+using Nemerle.IO;
+
+public class Foo {
+
+	public MethodOfFoo(): void {
+		print("From base method\n");
+	}
+
+	public static Main(): void {
+		Foo().MethodOfFoo();
+	}
+
+}
+
+[aspect()]
+public class Aspect {
+
+	after() returning: execution(Foo.MethodOfFoo(): void) {
+		print("From advice\n");
+	}
+}
+
+/*
+BEGIN-OUTPUT
+From base method
+From advice
+END-OUTPUT
+*/

Added: nemerle/trunk/snippets/aop/src/ftests/after/returning_positive.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/aop/src/ftests/after/returning_positive.n	Sun Jul  1 15:23:10 2007
@@ -0,0 +1,29 @@
+// testing returning part of the after() returning(x:int): pointcut 
+using Nemerle.Aop;
+using Nemerle.IO;
+
+public class Foo {
+	public Meth(): int {
+		print("I am returning 2\n");
+        2
+	}
+
+	public static Main(): void {
+		_=Foo().Meth();
+	}
+}
+
+[aspect()]
+public class Aspect {
+
+	after() returning(x: int): execution(Foo.Meth(): int) {
+		print("method has returned $x\n");
+	}
+}
+
+/*
+BEGIN-OUTPUT
+I am returning 2
+method has returned 2
+END-OUTPUT
+*/

Added: nemerle/trunk/snippets/aop/src/ftests/after/throwing_positive.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/aop/src/ftests/after/throwing_positive.n	Sun Jul  1 15:23:10 2007
@@ -0,0 +1,42 @@
+// test after() throwing
+using Nemerle.Aop;
+using Nemerle.IO;
+
+public class Foo {
+	public Meth(): int {
+		print("I will just throw an exception\n");
+        throw System.Exception();
+	}
+
+
+	public Meth2(): int {
+		print("I will not throw any exception\n");
+        1
+	}
+
+	public static Main(): void {
+        try {
+            _=Foo().Meth2();
+            _=Foo().Meth();
+        } catch {
+            | _ => print("an exception was caught\n");
+        }
+	}
+}
+
+[aspect()]
+public class Aspect {
+
+	after() throwing : execution(Foo.?(): int) {
+		print("advice\n");
+	}
+}
+
+/*
+BEGIN-OUTPUT
+I will not throw any exception
+I will just throw an exception
+advice
+an exception was caught
+END-OUTPUT
+*/

Added: nemerle/trunk/snippets/aop/src/ftests/after/throwing_with_parm_positive.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/aop/src/ftests/after/throwing_with_parm_positive.n	Sun Jul  1 15:23:10 2007
@@ -0,0 +1,45 @@
+// test after() throwing(e: type_of_an_exception)
+using Nemerle.Aop;
+using Nemerle.IO;
+
+public class Foo {
+	public Meth(): int {
+		print("I will just throw an exception\n");
+        throw System.Exception();
+	}
+
+
+	public Meth2(): int {
+		print("I will not throw any exception\n");
+        1
+	}
+
+	public static Main(): void {
+        try {
+            _=Foo().Meth2();
+            _=Foo().Meth();
+        } catch {
+            | _ => print("an exception was caught\n");
+        }
+	}
+}
+
+[aspect()]
+public class Aspect {
+
+	after() throwing(e: System.Exception) : execution(Foo.?(): int) {
+		if (e != null )
+            print("advice\n");
+        else
+            print("")
+	}
+}
+
+/*
+BEGIN-OUTPUT
+I will not throw any exception
+I will just throw an exception
+advice
+an exception was caught
+END-OUTPUT
+*/

Added: nemerle/trunk/snippets/aop/src/ftests/after/without_returning_positive.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/aop/src/ftests/after/without_returning_positive.n	Sun Jul  1 15:23:10 2007
@@ -0,0 +1,34 @@
+// after() without returning, covers also the case when method throws exception
+using Nemerle.Aop;
+using Nemerle.IO;
+
+public class Foo {
+	public Meth(): int {
+		print("I will just throw an exception\n");
+        throw System.Exception();
+	}
+
+	public static Main(): void {
+        try {
+            _=Foo().Meth();
+        } catch {
+            | _ => print("an exception was caught\n");
+        }
+	}
+}
+
+[aspect()]
+public class Aspect {
+
+	after(): execution(Foo.Meth(): int) {
+		print("advice\n");
+	}
+}
+
+/*
+BEGIN-OUTPUT
+I will just throw an exception
+advice
+an exception was caught
+END-OUTPUT
+*/

Added: nemerle/trunk/snippets/aop/src/ftests/args/args_positive.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/aop/src/ftests/args/args_positive.n	Sun Jul  1 15:23:10 2007
@@ -0,0 +1,44 @@
+using Nemerle.Aop;
+using Nemerle.IO;
+
+public class Foo {
+
+	public MethodOfFoo1(_i: int): void {
+		print("Foo1\n");
+	}
+
+	public MethodOfFoo2(_k: float): void {
+		print("Foo2\n");
+	}
+
+    public MethodOfFoo3(): void {
+		print("Foo3\n");
+	}
+
+	public static Main(): void {
+		Foo().MethodOfFoo1(0);
+        Foo().MethodOfFoo2(0.0f);
+        Foo().MethodOfFoo3();
+	}
+}
+
+[aspect()]
+public class Aspect {
+
+	after() returning: execution(Foo.?(..): void ) && args(float,..)  {
+		print("advice\n");
+	}
+}
+
+[aspect()]
+public class SomeOtherAspect {
+}
+
+/*
+BEGIN-OUTPUT
+Foo1
+Foo2
+advice
+Foo3
+END-OUTPUT
+*/

Added: nemerle/trunk/snippets/aop/src/ftests/args/elipsis_positive.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/aop/src/ftests/args/elipsis_positive.n	Sun Jul  1 15:23:10 2007
@@ -0,0 +1,46 @@
+using Nemerle.Aop;
+using Nemerle.IO;
+
+public class Foo {
+
+	public MethodOfFoo1(_i: int): void {
+		print("Foo1\n");
+	}
+
+	public MethodOfFoo2(_k: float): void {
+		print("Foo2\n");
+	}
+
+    public MethodOfFoo3(): void {
+		print("Foo3\n");
+	}
+
+	public static Main(): void {
+		Foo().MethodOfFoo1(0);
+        Foo().MethodOfFoo2(0.0f);
+        Foo().MethodOfFoo3();
+	}
+}
+
+[aspect()]
+public class Aspect {
+
+	after() returning: execution(Foo.?(..,int): void )  {
+		print("advice1\n");
+	}
+
+	after() returning: execution(Foo.?(float,..): void ) {
+		print("advice2\n");
+	}
+}
+
+/*
+BEGIN-OUTPUT
+Foo1
+advice1
+Foo2
+advice2
+Foo3
+END-OUTPUT
+*/
+

Added: nemerle/trunk/snippets/aop/src/ftests/args/just_args_positive.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/aop/src/ftests/args/just_args_positive.n	Sun Jul  1 15:23:10 2007
@@ -0,0 +1,40 @@
+using Nemerle.Aop;
+using Nemerle.IO;
+
+public class Foo {
+
+	public MethodOfFoo1(_i: int): void {
+		print("Foo1\n");
+	}
+
+	public MethodOfFoo2(_k: float): void {
+		print("Foo2\n");
+	}
+
+    public MethodOfFoo3(): void {
+		print("Foo3\n");
+	}
+
+	public static Main(): void {
+		Foo().MethodOfFoo1(0);
+        Foo().MethodOfFoo2(0.0f);
+        Foo().MethodOfFoo3();
+	}
+}
+
+[aspect()]
+public class Aspect {
+
+	after() returning: args(int) {
+		print("advice\n");
+	}
+}
+
+/*
+BEGIN-OUTPUT
+Foo1
+advice
+Foo2
+Foo3
+END-OUTPUT
+*/

Added: nemerle/trunk/snippets/aop/src/ftests/args/property_setter_positive.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/aop/src/ftests/args/property_setter_positive.n	Sun Jul  1 15:23:10 2007
@@ -0,0 +1,33 @@
+using Nemerle.Aop;
+using Nemerle.IO;
+
+public class Foo {
+
+    mutable _property_val: int;
+
+    public Property: int {
+        set { 
+            _property_val = value;
+            print("Property\n");
+        }        
+    }
+
+	public static Main(): void {
+        Foo().Property = 1;
+	}
+}
+
+[aspect()]
+public class Aspect {
+
+	after(parm: int) returning: execution(Foo.?{set;}: int ) && args(parm) {
+        print("advice: $parm\n");
+	}
+}
+
+/*
+BEGIN-OUTPUT
+Property
+advice: 1
+END-OUTPUT
+*/

Added: nemerle/trunk/snippets/aop/src/ftests/args/var_binding_and_invocation_positive.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/aop/src/ftests/args/var_binding_and_invocation_positive.n	Sun Jul  1 15:23:10 2007
@@ -0,0 +1,42 @@
+/*
+This is to test variable bindings combined with using special
+invocation parameter in advice, namely, the Nemerle.Aop.Invocation.
+*/
+
+// REFERENCE: Nemerle.Aop.dll
+
+using Nemerle.Aop;
+using Nemerle.IO;
+
+
+public class C {
+    public mutable F: int;
+    public this() { F = 0; }
+    public Method(param: int): void {print("method invoked with $param\n")}
+}
+
+[aspect()] public class Aspecto {
+
+    after( inv: Nemerle.Aop.Invocation, var: int ) returning: execution(C.Method(..): void) && args(var) {
+        (inv.Target:> C).F = 1;
+        print("advice intercepted $var\n");
+    }
+}
+
+public class Main {
+    public static Main(): void {
+        def o = C();
+        print(o.F.ToString() + "\n");
+        o.Method(3);
+        print(o.F.ToString() + "\n");
+    }
+}
+
+/*
+BEGIN-OUTPUT
+0
+method invoked with 3
+advice intercepted 3
+1
+END-OUTPUT
+*/

Added: nemerle/trunk/snippets/aop/src/ftests/args/var_binding_positive.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/aop/src/ftests/args/var_binding_positive.n	Sun Jul  1 15:23:10 2007
@@ -0,0 +1,47 @@
+using Nemerle.Aop;
+using Nemerle.IO;
+
+public class Foo {
+
+	public MethodOfFoo1(_i: int): void {
+		print("Foo1\n");
+	}
+
+	public MethodOfFoo2(_k: float): void {
+		print("Foo2\n");
+	}
+
+    public MethodOfFoo3(): void {
+		print("Foo3\n");
+	}
+
+	public static Main(): void {
+		Foo().MethodOfFoo1(0);
+        Foo().MethodOfFoo2(1.0f);
+        Foo().MethodOfFoo3();
+	}
+}
+
+[aspect()]
+public class Aspect {
+
+	after(parm: float) returning: execution(Foo.?(..): void ) && args(parm,..) {
+        if (parm == 1.0f)
+            print("advice\n");
+        else
+            print("error");
+	}
+}
+
+[aspect()]
+public class SomeOtherAspect {
+}
+
+/*
+BEGIN-OUTPUT
+Foo1
+Foo2
+advice
+Foo3
+END-OUTPUT
+*/

Added: nemerle/trunk/snippets/aop/src/ftests/around/around_positive.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/aop/src/ftests/around/around_positive.n	Sun Jul  1 15:23:10 2007
@@ -0,0 +1,33 @@
+// around without proceed
+using Nemerle.Aop;
+using Nemerle.IO;
+
+public class Foo {
+
+	public MethodOfFoo(): int {
+		print("From base method\n");
+        0
+	}
+
+	public static Main(): void {
+		print(Foo().MethodOfFoo());
+	}
+}
+
+[aspect()]
+public class Aspect {
+
+#pragma warning disable 
+	around():int : execution(Foo.MethodOfFoo(): int)  {
+		print("From advice\n");
+        3
+	}
+#pragma warning restore
+}
+
+/*
+BEGIN-OUTPUT
+From advice
+3