private static IEnumerable <UnifiedElement> GetProperties( UnifiedElement element) { var elements = element as IEnumerable <UnifiedElement>; if (elements != null) { foreach (var e in elements) { yield return(e); } } var props = element.GetType().GetProperties() .Where(prop => prop.Name != "Parent") .Where(prop => prop.GetIndexParameters().Length == 0) .Where( prop => typeof(UnifiedElement).IsAssignableFrom( prop.PropertyType)); if (element is UnifiedWrapType) { props = props.Where(prop => prop.Name != "BasicTypeName"); } foreach (var prop in props) { yield return((UnifiedElement)prop.GetValue(element, null)); } }
private static string GetOutersString(UnifiedElement target) { var result = "::"; foreach (var e in target.AncestorsAndSelf()) { var name = GetOutersName(e); if (name == null) { continue; } result = "::" + name + result; } //var outerName = target.Ancestors() // .Select( // e => { // var klass = e as UnifiedClassLikeDefinition; // if (klass != null) // return klass.Name; // var method = e as UnifiedFunctionDefinition; // if (method != null) // return method.Name; // return null; // }) // .Where(e => e != null) // .FirstOrDefault(); //if (outerName != null) { // result = JavaFactory.GenerateCode(outerName); //} else { // result = ""; //} return(result); }
/// <summary> /// 指定された関数ブロックの先頭に、指定されたコードを共通コードモデルとして挿入します。 /// </summary> /// <param name = "root">コードを追加するモデルのルートノード</param> /// <param name = "regex">対象関数を指定する正規表現</param> /// <param name = "advice">挿入するコード断片</param> public static void InsertAtBeforeExecution( UnifiedElement root, Regex regex, UnifiedBlock advice) { //get function list var functions = root.Descendants <UnifiedFunctionDefinition>(); foreach (var function in functions) { //関数の定義元がインターフェースまたは抽象クラスの場合はアドバイスを合成しない if (function.Body == null) { continue; } //weave given advice, when function's name matches given Regex var m = regex.Match(function.Name.Name); if (m.Success) { //アドバイス内の特定の変数を、現在の対象関数名で置き換える var copy = ReplaceSpecialToken(advice.DeepCopy(), function.Name.Name); //アドバイスを対象関数に合成する function.Body.Insert(0, copy); } } }
/// <summary> /// 指定された関数呼び出しの後に、指定されたコードを共通コードモデルとして挿入します。 /// </summary> /// <param name = "root">コードを追加するモデルのルートノード</param> /// <param name = "regex">対象関数を指定する正規表現</param> /// <param name = "advice">挿入するコード断片</param> public static void InsertAtAfterCall( UnifiedElement root, Regex regex, UnifiedBlock advice) { //get cass list var calls = root.Descendants <UnifiedCall>().ToList(); //親要素がUnifiedBlockの場合に、その関数呼び出しは単項式であると判断する。 foreach (var call in calls) { //プロパティでない関数呼び出しのみを扱う //e.g. write()はOK. Math.max()はNG. var functionName = call.Function as UnifiedIdentifier; if (functionName == null) { continue; } var m = regex.Match(functionName.Name); if (!m.Success) { continue; } //(Javaにおいて)関数呼び出しの親ノードがブロックの場合、それは単独である //(JavaScriptにおいて)関数呼び出しの親ノードがブロックの場合、それは単独である var block = call.Parent as UnifiedBlock; if (block != null) { block.Insert(block.IndexOf(call, 0) + 1, advice.DeepCopy()); } } }
public string Generate(UnifiedElement codeObject) { var writer = new StringWriter(); Generate(codeObject, writer); return(writer.ToString()); }
public override void Generate( UnifiedElement codeObject, TextWriter writer, string indentSign) { codeObject.Accept( new Python2CodeFactoryVisitor(writer, indentSign), new VisitorArgument()); }
/// <summary> /// 指定された関数ブロックの先頭に、指定されたコードを共通コードモデルとして挿入します。 /// </summary> /// <param name = "root">コードを追加するモデルのルートノード</param> /// <param name = "regex">対象関数を指定する正規表現</param> /// <param name="element"></param> /// <param name = "advice">挿入するコード断片</param> public static void InsertAtBeforeExecution( UnifiedElement root, Regex regex, Type element, UnifiedBlock advice) { //関数の一覧を取得 var functions = root.Descendants <UnifiedFunctionDefinition>(); foreach (var function in functions) { //関数の定義元がインターフェースまたは抽象クラスの場合はアドバイスを合成しない if (function.Body == null) { continue; } //関数内部に指定された要素があるかどうかを判定 var specifiedElements = ModelSweeper.Descendants(function.Body).Where(e => e.GetType().Equals(element)); if (specifiedElements.Count() == 0) { continue; } //関数名が与えられた正規表現にマッチする場合はアドバイスを合成する var m = regex.Match(function.Name.Name); if (m.Success) { //アドバイス内の特定の変数を、現在の対象関数名で置き換える var copy = ReplaceSpecialToken(advice.DeepCopy(), function.Name.Name); function.Body.Insert(0, copy); } } }
/// <summary> /// レシーバーがnullでも動作するParentプロパティです. /// </summary> /// <param name="element"> </param> /// <returns> </returns> public static UnifiedElement SafeParent(this UnifiedElement element) { if (element == null) { return(null); } return(element.Parent); }
public static IEnumerable <UnifiedElement> GetTargetElements( UnifiedElement codeObject) { return (codeObject.Descendants <UnifiedIf, UnifiedFor, UnifiedWhile, UnifiedDoWhile , UnifiedCase>()); }
/// <summary> /// 指定された変数参照の直後に、指定されたコードを共通コードモデルとして挿入します。 /// </summary> /// <param name="root">コードを追加するモデルのルートノード</param> /// <param name="regex">対象変数を指定する正規表現</param> /// <param name="advice">挿入するコード断片</param> public static void InsertAtAfterGet(UnifiedElement root, Regex regex, UnifiedBlock advice) { //a = b;のb //TODO とりえあずAssignのみ +=,-=などについてはおいおい var assignmentExpressions = root.Descendants <UnifiedBinaryExpression>().Where(e => e.Operator.Kind == UnifiedBinaryOperatorKind.Assign).ToList(); foreach (var exp in assignmentExpressions) { var parent = exp.Parent as UnifiedBlock; var rhs = exp.RightHandSide as UnifiedVariableIdentifier; //親がブロック かつ 右辺がUnifiedVariableIdentifier でない場合は次の要素へ if (parent == null || rhs == null) { continue; } //変数名が与えられた正規表現にマッチするか確認する var m = regex.Match(rhs.Name); if (!m.Success) { continue; } //アドバイスの合成 parent.Insert(parent.IndexOf(exp, 0) + 1, advice.DeepCopy()); } //int a = b;のb var variableDefinitions = root.Descendants <UnifiedVariableDefinition>().ToList(); foreach (var definition in variableDefinitions) { //初期化子を変数として取得 var identifier = definition.InitialValue as UnifiedVariableIdentifier; var block = definition.Parent.Parent as UnifiedBlock; //初期化子が変数でない場合は次の要素へ if (block == null || identifier == null) { continue; } //変数名が与えられた正規表現にマッチするか確認する var m = regex.Match(identifier.Name); if (!m.Success) { continue; } //アドバイスの合成 var parent = definition.Parent as UnifiedVariableDefinitionList; block.Insert(block.IndexOf(parent, 0) + 1, advice.DeepCopy()); } }
/// <summary> /// 指定された関数ブロックの後に、指定されたコードを共通コードモデルとして挿入します。 /// </summary> /// <param name = "root">コードを追加するモデルのルートノード</param> /// <param name = "regex">対象関数を指定する正規表現</param> /// <param name="statementNum">対象関数に含まれるstatement数の下限を指定する閾値</param> /// <param name = "advice">挿入するコード断片</param> public static void InsertAtAfterExecution( UnifiedElement root, Regex regex, int statementNum, UnifiedBlock advice) { //get function list var functions = root.Descendants <UnifiedFunctionDefinition>(); foreach (var function in functions) { //関数の定義元がインターフェースまたは抽象クラスの場合はアドバイスを合成しない if (function.Body == null) { continue; } //関数内部のStatementの一覧を取得し、閾値より多いかどうかを判定 var innerStatements = ModelSweeper.Descendants(function.Body).Where(e => e.Parent.GetType().Equals(typeof(UnifiedBlock))); if (innerStatements.Count() < statementNum) { continue; } //when function's name doesn't match given Regex, ignore current functionDefinition var m = regex.Match(function.Name.Name); if (!m.Success) { continue; } /*ToList()を呼び出しておかないと例外を吐く * 【例外】 * C# エラーメッセージ:コレクションが変更されました。 * 列挙操作は実行されない可能性があります。 */ var returns = function.Descendants <UnifiedReturn>().ToList(); if (returns.Count() == 0) { //case function don't have return statement function.Body.Add(advice.DeepCopy()); } else { foreach (var returnStmt in returns) { var block = returnStmt.Parent as UnifiedBlock; if (block == null) { continue; } block.Insert(block.IndexOf(returnStmt, 0), advice.DeepCopy()); } } } }
public string GenerateOrEmpty(UnifiedElement model) { if (model == null) { return(string.Empty); } var writer = new StringWriter(); Generate(model, writer); return(writer.ToString()); }
public static Dictionary <string, int> Measure( UnifiedElement codeObject, Func <UnifiedElement, IEnumerable <UnifiedElement> > getTargetElementsFunc) { var counts = new Dictionary <string, int>(); InitializeCounter(codeObject, counts); CountElements(getTargetElementsFunc(codeObject), counts); return(counts); }
protected string GetString(UnifiedElement element, VisitorArgument arg) { var oldWriter = Writer; Writer = new StringWriter(); element.TryAccept(this, arg); var ret = Writer.ToString(); Writer = oldWriter; return(ret); }
protected static bool GetRequiredParen(UnifiedElement element) { var parent = element.Parent; return(parent is UnifiedFunctionDefinition || parent is UnifiedIndexer || parent is UnifiedProperty || parent is UnifiedCast || parent is UnifiedUnaryExpression || parent is UnifiedBinaryExpression || parent is UnifiedTernaryExpression); }
/// <summary> /// 親要素に不適切な要素がないかソースコードを指定して検査します。 /// </summary> /// <param name="codeObject"> 検査対象のモデル </param> /// <param name="message"> アサーションに違反した際のエラーメッセージ </param> private static void AssertParentProperty( UnifiedElement codeObject, string message) { foreach (var element in codeObject.Elements()) { if (element != null) { Assert.That(element.Parent, Is.SameAs(codeObject), message); AssertParentProperty(element, message); } } }
private static Tuple <string, string> GetRequiredParen( UnifiedElement element) { var parent = element.Parent; if (parent is UnifiedUnaryExpression || parent is UnifiedBinaryExpression || parent is UnifiedTernaryExpression) { return(Tuple.Create("(", ")")); } return(Tuple.Create("", "")); }
private static void InitializeCounter( UnifiedElement model, IDictionary <string, int> counter) { var outers = model.Elements() .Where( e => e is UnifiedClassLikeDefinition || e is UnifiedFunctionDefinition); foreach (var e in outers) { var outerStr = GetOutersString(e); counter[outerStr] = 0; } }
private static string GetOutersName(UnifiedElement element) { var klass = element as UnifiedClassLikeDefinition; if (klass != null) { return("[class] " + JavaFactory.GenerateCode(klass.Name)); } var method = element as UnifiedFunctionDefinition; if (method != null) { return("[method] " + JavaFactory.GenerateCode(method.Name)); } return(null); }
public override void Before(UnifiedElement model, AspectElement.Pointcut target, UnifiedBlock advice) { var exceptions = model.Descendants <UnifiedCatch>(); foreach (var e in exceptions) { var regex = new Regex("^" + target.GetTargetName().ElementAt(1) + "$"); var type = e.Types[0].BasicTypeName as UnifiedIdentifier; if (type == null) { continue; } var m = regex.Match(type.Name); if (m.Success) { //アドバイスを対象関数に合成する e.Body.Insert(0, advice.DeepCopy()); } } }
public static UnifiedVariableDefinition FindDefinition( UnifiedIdentifier variable) { var scopes = variable.Ancestors <UnifiedBlock>(); var name = variable.Name; UnifiedElement searched = variable; foreach (var scope in scopes) { var definition = scope .DescendantsUntil(e2 => e2 is UnifiedBlock) .TakeWhile(e => e != searched) .OfType <UnifiedVariableDefinition>() .FirstOrDefault(e => e.Name.Name == name); if (definition != null) { return(definition); } searched = scope; } return(null); }
public abstract void Generate( UnifiedElement codeObject, TextWriter writer, string indentSign);
public static IEnumerable <UnifiedElement> GetTargetElements( UnifiedElement codeObject) { return(codeObject.Descendants <UnifiedExpression>() .Where(e => e.Parent is UnifiedBlock)); }
/// <summary> /// すべての関数呼び出しの直前に、指定されたコードを共通コードモデルとして挿入します。 /// </summary> /// <param name = "root">コードを追加するモデルのルートノード</param> /// <param name = "advice">挿入するコード断片</param> public static void InsertAtBeforeCallAll( UnifiedElement root, UnifiedBlock advice) { InsertAtBeforeCall(root, new Regex(".*"), advice); }
public abstract void Generate( UnifiedElement codeObject, TextWriter writer);
ProtectedGetTargetElements( UnifiedElement codeObject) { return(GetTargetElements(codeObject)); }
public override void Around(UnifiedElement model) { throw new NotImplementedException(); }
public override void After(UnifiedElement model, AspectElement.Pointcut target, UnifiedBlock advice) { InsertAtAfterCallByName(model, target.GetTargetName().ElementAt(1), advice); }
/// <summary> /// 指定された関数呼び出しの後に、指定されたコードを共通コードモデルとして挿入します。 /// </summary> /// <param name = "root">コードを追加するモデルのルードノード</param> /// <param name = "name">対象関数の名前</param> /// <param name = "advice">挿入するコード断片</param> public static void InsertAtAfterCallByName( UnifiedElement root, string name, UnifiedBlock advice) { InsertAtAfterCall(root, new Regex("^" + name + "$"), advice); }
public static string GenerateCode(UnifiedElement model) { return(CodeGenerator.Generate(model)); }