public void JavaScript言語向けコード片を正しくモデル化できる() { const string code = "alert(\"This is a test!\");"; var advice = UcoGenerator.CreateAdvice("JavaScript", code); Assert.That(advice.GetType(), Is.EqualTo(typeof(UnifiedBlock))); }
public void Java言語向けコード片を正しくモデル化できる() { const string code = "System.out.println(JOINPOINT_NAME + \"This is a test!\");"; var advice = UcoGenerator.CreateAdvice("Java", code); Assert.That(advice.GetType(), Is.EqualTo(typeof(UnifiedBlock))); }
public void Python言語向けコード片を正しくモデル化できる() { const string code = "print \"test\""; var advice = UcoGenerator.CreateAdvice("Python", code); Assert.That(advice.GetType(), Is.EqualTo(typeof(UnifiedBlock))); }
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("Java", ".java", "System.out.println(\"Inserted after.\");")] // [TestCase("JavaScript", ".js", "Console.log(\"Inserted after.\");")] // [TestCase("C", ".c", "printf(\"Inserted after.\");")] // [TestCase("CSharp", ".cs", "Console.WriteLine(\"Inserted after.\");")] // [TestCase("Python", ".py", "print \"Inserted after.\"")] public void SetAfterが正しく動作することを検証します(string language, string ext, string code) { var model = UnifiedGenerators.GenerateProgramFromFile( FixtureUtil.GetInputPath("Aspect", "Set", "Fibonacci" + ext)); var actual = UnifiedGenerators.GenerateProgramFromFile( FixtureUtil.GetInputPath("Aspect", "Set", "Fibonacci_expectation_after" + ext)); Set.InsertAtAfterSetByName( model, "fibonacci", UcoGenerator.CreateAdvice(language, code)); Assert.That(model, Is.EqualTo(actual).Using(StructuralEqualityComparer.Instance)); }
public void WeavingAtBeforeCallAll() { var model = UnifiedGenerators.GenerateProgramFromFile(_studentPath); var actual = UnifiedGenerators.GenerateProgramFromFile(FixtureUtil.GetAopExpectationPath("Java", "Student_callBefore.java")); Call.InsertAtBeforeCallAll( model, UcoGenerator.CreateAdvice("Java", "Console.Write();")); 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 void 特殊文字を含むアドバイス内の変数を指定された文字列に置き換えられる() { var code = "System.out.println(JOINPOINT_NAME + \" is executed!\");"; var advice = UcoGenerator.CreateAdvice("Java", code); //アドバイス内の特殊文字を置き換える Execution.ReplaceSpecialToken(advice, "test"); code = "System.out.println(\"test\" + \" is executed!\");"; var actual = UcoGenerator.CreateAdvice("Java", code); var gen = new JavaCodeGenerator(); Console.WriteLine(gen.Generate(advice)); Assert.That(gen.Generate(advice), Is.EqualTo(gen.Generate(actual))); }
public void Setポイントカットを用いて初期化子つき変数宣言の直前にアスペクトを合成できる() { const string code = @"class A{ public void M() { int a = 10; int b = a; } }"; //モデル化 var model = CreateProgramFromCode(".java", code); var beforeNumBlock = model.Descendants().OfType <UnifiedBlock>().Count(); //アスペクトの合成 Set.InsertAtBeforeSet(model, new Regex("b"), UcoGenerator.CreateAdvice("Java", "System.out.println();")); var afterNumBlock = model.Descendants().OfType <UnifiedBlock>().Count(); //for debug var gen = new JavaCodeGenerator(); Console.Write(gen.Generate(model)); //アスペクトが合成されるためブロックの数が1つ増える Assert.That(afterNumBlock, Is.EqualTo(beforeNumBlock + 1)); }
// 統合コードオブジェクトに対してアスペクトの合成処理を行います 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(); } } }