public void 例外ポイントカットを作成してcatch節の中にコードを追加する() { // オリジナルのソースコードのUCOとアスペクト合成後に期待されるソースコードのUCOを生成する var model = UnifiedGenerators.GenerateProgramFromFile(_sourcePath); var actual = UnifiedGenerators.GenerateProgramFromFile(_expectationSourcePath); var pointcut = new Pointcut(); pointcut.SetTarget("*"); pointcut.SetTarget("Exception"); // オリジナルのUCOに対して、アスペクトを合成する CodeProcessorProvider.WeavingBefore("exception", model, pointcut, UcoGenerator.CreateAdvice("Java", "System.out.println(\"test\");")); model.Normalize(); var gen = UnifiedGenerators.GetCodeGeneratorByExtension(".java"); Console.WriteLine(gen.Generate(model)); Console.WriteLine(gen.Generate(actual)); // 両者の構造を比較する Assert.That(model, Is.EqualTo(actual).Using(StructuralEqualityComparer.Instance)); }
// [TestCase("Python", ".py", "print \"Inserted after.\"")] public void ExecutionAfterが正しく動作することを検証します(string language, string ext, string code) { var model = UnifiedGenerators.GenerateProgramFromFile( FixtureUtil.GetInputPath("Aspect", "Execution", "Fibonacci" + ext)); var actual = UnifiedGenerators.GenerateProgramFromFile( FixtureUtil.GetInputPath("Aspect", "Execution", "Fibonacci_expectation_after" + ext)); var pointcut = new Pointcut(); pointcut.SetTarget("*"); pointcut.SetTarget("fibonacci"); CodeProcessorProvider.WeavingAfter("execution", model, pointcut, UcoGenerator.CreateAdvice(language, code)); Assert.That(model, Is.EqualTo(actual).Using(StructuralEqualityComparer.Instance)); }
// 統合コードオブジェクトに対してアスペクトの合成処理を行います public static void Weave(string language, UnifiedProgram model) { //以前のアスペクトファイルの情報を消去するために辞書の内容を初期化する Pointcuts.Clear(); //与えられたモデルに対してインタータイプを合成する foreach (var intertype in _visitor.Intertypes) { if (intertype.GetLanguageType() != language) { continue; } var members = UcoGenerator.CreateIntertype( intertype.GetLanguageType(), intertype.GetContents()); InterType.AddIntertypeDeclaration(model, intertype.GetTarget(), members); } //ポイントカットを登録する foreach (var pointcut in _visitor.Pointcuts) { var name = pointcut.GetName(); //同じ名前のポイントカットがある場合にはエラーとする if (Pointcuts.ContainsKey(name)) { throw new InvalidOperationException( "同名のポイントカットがすでに宣言されています: " + name); } //ポイントカットを自身の名前で登録 Pointcuts.Add(name, pointcut); } //アドバイスの適用 foreach (var advice in _visitor.Advices) { //アドバイスのターゲットがポイントカット宣言されていない場合はエラーとする if (!Pointcuts.ContainsKey(advice.GetTarget())) { throw new InvalidOperationException( "指定されたポイントカットは宣言されていません"); } //アドバイスのターゲットが登録されていれば、それに対応するポイントカットを取得する Pointcut target; Pointcuts.TryGetValue(advice.GetTarget(), out target); //指定された言語のアドバイスがあればそれをモデルに変換する UnifiedBlock code = null; foreach (var languageDependBlock in advice.GetFragments()) { // if (languageDependBlock.GetLanguageType().Equals(language)) { code = UcoGenerator.CreateAdvice( language, languageDependBlock.GetContents()); break; } } //現在の対象ファイルの言語向けアドバイスが定義されていない場合は次のアドバイス処理に移る if (code == null) { continue; } //ポイントカットの指定に応じて適切なアドバイスの合成処理を行う //TODO ワイルドカードなどへの対応 //TODO 複数のターゲットを持つポイントカットへの対応(これはそもそもパーサを改良する必要あり) var methodName = target.GetTargetName().ElementAt(1); // アドバイスの合成 // リフレクション(MEF)を用いて、対応するメソッドが呼び出されます switch (advice.GetAdviceType()) { case "before": CodeProcessorProvider.WeavingBefore(target.GetPointcutType(), model, target.DeepCopy(), code); break; case "after": CodeProcessorProvider.WeavingAfter(target.GetPointcutType(), model, target.DeepCopy(), code); break; default: throw new InvalidOperationException(); } } }