/// <summary> /// 与えられたコードを共通コードオブジェクトとして生成します。 /// </summary> /// <param name = "language">対象言語</param> /// <param name = "code">コード断片</param> /// <returns></returns> public static UnifiedBlock CreateAdvice(string language, string code) { XElement ast; UnifiedBlock actual; /* * 与えられたコード断片をブロックとして統合コードオブジェクトに変換します * これにより、シンタックス上では安全なオブジェクトの挿入を実現します * (カスタムポイントカットは除く) * * 部分的なコードを統合コードオブジェクトに変換する機能が提供されている言語の場合: * (Java, JavaScript, C) * コード断片全体を中括弧で括ることでブロックとしてのパースができるようにします * したがって、ブロック内に記述できないプログラムはアドバイスとして記述できません * * 上記の機能が提供されていない言語の場合: * (CSharp, Python) * 専用のメソッドを使用します * 具体的には、コード断片に対して、それが1プログラムとしてパースできるまで最小限のコード補完を行い、 * 統合コードオブジェクトに変換後、元のコードに該当する部分だけを抽出します */ switch (language) { case "Java": code = "{ " + code + " }"; ast = JavaCodeToXml.Instance.Generate(code, p => p.block()); actual = JavaProgramGeneratorHelper.CreateBlock(ast); break; case "JavaScript": code = "{ " + code + " }"; ast = JavaScriptCodeToXml.Instance.Generate(code, p => p.statementBlock()); actual = JavaScriptProgramGeneratorHelper.CreateStatementBlock(ast); break; case "C": code = "{ " + code + " }"; ast = CCodeToXml.Instance.Generate(code, p => p.compound_statement()); actual = CProgramGeneratorHelper.CreateCompoundStatement(ast); break; case "CSharp": actual = CreateAdviceForCSharp(code); break; case "Python": actual = CreateAdviceForPython(code); break; default: //Ruby, VB // TODO Ruby言語の対応 throw new InvalidOperationException("対応していない言語が指定されました"); } actual.Normalize(); return(actual); }
public void DescendantUntil() { var ast = JavaCodeToXml.Instance .Generate( "{ {int j = 0;} { j = 1; } }", p => p.block()); var codeObject = JavaProgramGeneratorHelper.CreateBlock(ast); Assert.That( codeObject.DescendantsUntil(e => e is UnifiedBlock).Count(), Is.EqualTo(0)); }
public void 直前の変数定義オブジェクトを取得できる() { var ast = JavaCodeToXml.Instance.Generate( "{ int i; i = 1; }", p => p.block()); var codeObject = JavaProgramGeneratorHelper.CreateBlock(ast); var variable = codeObject.Descendants <UnifiedIdentifier>().Last(); var definition = SemanticAnalyzer.FindDefinition(variable); var expected = codeObject.Descendants <UnifiedVariableDefinition>().First(); Assert.That(definition, Is.EqualTo(expected)); }
public void 後方の変数定義を無視して変数定義オブジェクトを取得できる() { var ast = JavaCodeToXml.Instance .Generate( "{ j = 0; { j = 1; } int j; }", p => p.block()); var codeObject = JavaProgramGeneratorHelper.CreateBlock(ast); var variable = codeObject.Descendants <UnifiedIdentifier>().ElementAt(1); var definition = SemanticAnalyzer.FindDefinition(variable); Assert.That(definition, Is.EqualTo(null)); }
public void IgnoreSliblingScope() { var ast = JavaCodeToXml.Instance .Generate( "{ {int j = 0;} {j = 1;} }", p => p.block()); var codeObject = JavaProgramGeneratorHelper.CreateBlock(ast); var variable = codeObject.Descendants <UnifiedIdentifier>().ElementAt(2); var definition = SemanticAnalyzer.FindDefinition(variable); Assert.That(definition, Is.EqualTo(null)); }