From 493e7c6a2ba2d1a1773eb6d63f7491f8b3a1993d Mon Sep 17 00:00:00 2001 From: Ryo Arima Date: Tue, 13 Nov 2018 21:47:19 +0900 Subject: [PATCH 1/4] =?UTF-8?q?ASTStream=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kgenprog/project/jdt/ASTStream.java | 559 ++++++++++++++++++ .../kgenprog/project/jdt/ASTStreamTest.java | 40 ++ 2 files changed, 599 insertions(+) create mode 100644 src/main/java/jp/kusumotolab/kgenprog/project/jdt/ASTStream.java create mode 100644 src/test/java/jp/kusumotolab/kgenprog/project/jdt/ASTStreamTest.java diff --git a/src/main/java/jp/kusumotolab/kgenprog/project/jdt/ASTStream.java b/src/main/java/jp/kusumotolab/kgenprog/project/jdt/ASTStream.java new file mode 100644 index 000000000..2c2ba3e92 --- /dev/null +++ b/src/main/java/jp/kusumotolab/kgenprog/project/jdt/ASTStream.java @@ -0,0 +1,559 @@ +package jp.kusumotolab.kgenprog.project.jdt; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.Iterator; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; +import org.eclipse.jdt.core.dom.*; + +public class ASTStream extends ASTVisitor implements Iterator { + + public static Iterator iterator(final ASTNode node) { + return new ASTStream(node); + } + + public static Stream stream(final ASTNode node) { + final Spliterator spliterator = + Spliterators.spliteratorUnknownSize(iterator(node), Spliterator.NONNULL); + return StreamSupport.stream(spliterator, false); + } + + private final Deque globalStack; + private final Deque stepStack; + private boolean alreadyConsumed; + + public ASTStream(final ASTNode node) { + globalStack = new ArrayDeque<>(); + stepStack = new ArrayDeque<>(); + + globalStack.push(node); + } + + @Override + public boolean hasNext() { + return !globalStack.isEmpty(); + } + + @Override + public ASTNode next() { + final ASTNode node = globalStack.pop(); + + alreadyConsumed = false; + node.accept(this); + + while (!stepStack.isEmpty()) { + globalStack.push(stepStack.pop()); + } + + return node; + } + + private boolean consume(final ASTNode node) { + if (alreadyConsumed) { + stepStack.push(node); + return false; + } + alreadyConsumed = true; + return true; + } + + @Override + public boolean visit(final AnnotationTypeDeclaration node) { + return consume(node); + } + + @Override + public boolean visit(final AnnotationTypeMemberDeclaration node) { + return consume(node); + } + + @Override + public boolean visit(final AnonymousClassDeclaration node) { + return consume(node); + } + + @Override + public boolean visit(final ArrayAccess node) { + return consume(node); + } + + @Override + public boolean visit(final ArrayCreation node) { + + return consume(node); + } + + @Override + public boolean visit(final ArrayInitializer node) { + return consume(node); + } + + @Override + public boolean visit(final ArrayType node) { + return consume(node); + } + + @Override + public boolean visit(final AssertStatement node) { + return consume(node); + } + + @Override + public boolean visit(final Assignment node) { + return consume(node); + } + + @Override + public boolean visit(final Block node) { + return consume(node); + } + + @Override + public boolean visit(final BlockComment node) { + return consume(node); + } + + @Override + public boolean visit(final BooleanLiteral node) { + return consume(node); + } + + @Override + public boolean visit(final BreakStatement node) { + return consume(node); + } + + @Override + public boolean visit(final CastExpression node) { + return consume(node); + } + + @Override + public boolean visit(final CatchClause node) { + return consume(node); + } + + @Override + public boolean visit(final CharacterLiteral node) { + return consume(node); + } + + @Override + public boolean visit(final ClassInstanceCreation node) { + return consume(node); + } + + @Override + public boolean visit(final CompilationUnit node) { + return consume(node); + } + + @Override + public boolean visit(final ConditionalExpression node) { + return consume(node); + } + + @Override + public boolean visit(final ConstructorInvocation node) { + return consume(node); + } + + @Override + public boolean visit(final ContinueStatement node) { + return consume(node); + } + + @Override + public boolean visit(final CreationReference node) { + return consume(node); + } + + @Override + public boolean visit(final Dimension node) { + return consume(node); + } + + @Override + public boolean visit(final DoStatement node) { + return consume(node); + } + + @Override + public boolean visit(final EmptyStatement node) { + return consume(node); + } + + @Override + public boolean visit(final EnhancedForStatement node) { + return consume(node); + } + + @Override + public boolean visit(final EnumConstantDeclaration node) { + return consume(node); + } + + @Override + public boolean visit(final EnumDeclaration node) { + return consume(node); + } + + @Override + public boolean visit(final ExportsDirective node) { + return consume(node); + } + + @Override + public boolean visit(final ExpressionMethodReference node) { + return consume(node); + } + + @Override + public boolean visit(final ExpressionStatement node) { + return consume(node); + } + + @Override + public boolean visit(final FieldAccess node) { + return consume(node); + } + + @Override + public boolean visit(final FieldDeclaration node) { + return consume(node); + } + + @Override + public boolean visit(final ForStatement node) { + return consume(node); + } + + @Override + public boolean visit(final IfStatement node) { + return consume(node); + } + + @Override + public boolean visit(final ImportDeclaration node) { + return consume(node); + } + + @Override + public boolean visit(final InfixExpression node) { + return consume(node); + } + + @Override + public boolean visit(final Initializer node) { + return consume(node); + } + + @Override + public boolean visit(final InstanceofExpression node) { + return consume(node); + } + + @Override + public boolean visit(final IntersectionType node) { + return consume(node); + } + + @Override + public boolean visit(final Javadoc node) { + return consume(node); + } + + @Override + public boolean visit(final LabeledStatement node) { + return consume(node); + } + + @Override + public boolean visit(final LambdaExpression node) { + return consume(node); + } + + @Override + public boolean visit(final LineComment node) { + return consume(node); + } + + @Override + public boolean visit(final MarkerAnnotation node) { + return consume(node); + } + + @Override + public boolean visit(final MemberRef node) { + return consume(node); + } + + @Override + public boolean visit(final MemberValuePair node) { + return consume(node); + } + + @Override + public boolean visit(final MethodRef node) { + return consume(node); + } + + @Override + public boolean visit(final MethodRefParameter node) { + return consume(node); + } + + @Override + public boolean visit(final MethodDeclaration node) { + return consume(node); + } + + @Override + public boolean visit(final MethodInvocation node) { + return consume(node); + } + + @Override + public boolean visit(final Modifier node) { + return consume(node); + } + + @Override + public boolean visit(final ModuleDeclaration node) { + return consume(node); + } + + @Override + public boolean visit(final ModuleModifier node) { + return consume(node); + } + + @Override + public boolean visit(final NameQualifiedType node) { + return consume(node); + } + + @Override + public boolean visit(final NormalAnnotation node) { + return consume(node); + } + + @Override + public boolean visit(final NullLiteral node) { + return consume(node); + } + + @Override + public boolean visit(final NumberLiteral node) { + return consume(node); + } + + @Override + public boolean visit(final OpensDirective node) { + return consume(node); + } + + @Override + public boolean visit(final PackageDeclaration node) { + return consume(node); + } + + @Override + public boolean visit(final ParameterizedType node) { + return consume(node); + } + + @Override + public boolean visit(final ParenthesizedExpression node) { + return consume(node); + } + + @Override + public boolean visit(final PostfixExpression node) { + return consume(node); + } + + @Override + public boolean visit(final PrefixExpression node) { + return consume(node); + } + + @Override + public boolean visit(final ProvidesDirective node) { + return consume(node); + } + + @Override + public boolean visit(final PrimitiveType node) { + return consume(node); + } + + @Override + public boolean visit(final QualifiedName node) { + return consume(node); + } + + @Override + public boolean visit(final QualifiedType node) { + return consume(node); + } + + @Override + public boolean visit(final RequiresDirective node) { + return consume(node); + } + + @Override + public boolean visit(final ReturnStatement node) { + return consume(node); + } + + @Override + public boolean visit(final SimpleName node) { + return consume(node); + } + + @Override + public boolean visit(final SimpleType node) { + return consume(node); + } + + @Override + public boolean visit(final SingleMemberAnnotation node) { + return consume(node); + } + + @Override + public boolean visit(final SingleVariableDeclaration node) { + return consume(node); + } + + @Override + public boolean visit(final StringLiteral node) { + return consume(node); + } + + @Override + public boolean visit(final SuperConstructorInvocation node) { + return consume(node); + } + + @Override + public boolean visit(final SuperFieldAccess node) { + return consume(node); + } + + @Override + public boolean visit(final SuperMethodInvocation node) { + return consume(node); + } + + @Override + public boolean visit(final SuperMethodReference node) { + return consume(node); + } + + @Override + public boolean visit(final SwitchCase node) { + return consume(node); + } + + @Override + public boolean visit(final SwitchStatement node) { + return consume(node); + } + + @Override + public boolean visit(final SynchronizedStatement node) { + return consume(node); + } + + @Override + public boolean visit(final TagElement node) { + return consume(node); + } + + @Override + public boolean visit(final TextElement node) { + return consume(node); + } + + @Override + public boolean visit(final ThisExpression node) { + return consume(node); + } + + @Override + public boolean visit(final ThrowStatement node) { + return consume(node); + } + + @Override + public boolean visit(final TryStatement node) { + return consume(node); + } + + @Override + public boolean visit(final TypeDeclaration node) { + return consume(node); + } + + @Override + public boolean visit(final TypeDeclarationStatement node) { + return consume(node); + } + + @Override + public boolean visit(final TypeLiteral node) { + return consume(node); + } + + @Override + public boolean visit(final TypeMethodReference node) { + return consume(node); + } + + @Override + public boolean visit(final TypeParameter node) { + return consume(node); + } + + @Override + public boolean visit(final UnionType node) { + return consume(node); + } + + @Override + public boolean visit(final UsesDirective node) { + return consume(node); + } + + @Override + public boolean visit(final VariableDeclarationExpression node) { + return consume(node); + } + + @Override + public boolean visit(final VariableDeclarationStatement node) { + return consume(node); + } + + @Override + public boolean visit(final VariableDeclarationFragment node) { + return consume(node); + } + + @Override + public boolean visit(final WhileStatement node) { + return consume(node); + } + + @Override + public boolean visit(final WildcardType node) { + return consume(node); + } + +} diff --git a/src/test/java/jp/kusumotolab/kgenprog/project/jdt/ASTStreamTest.java b/src/test/java/jp/kusumotolab/kgenprog/project/jdt/ASTStreamTest.java new file mode 100644 index 000000000..36469af8a --- /dev/null +++ b/src/test/java/jp/kusumotolab/kgenprog/project/jdt/ASTStreamTest.java @@ -0,0 +1,40 @@ +package jp.kusumotolab.kgenprog.project.jdt; + +import static org.assertj.core.api.Assertions.assertThat; +import java.nio.file.Paths; +import java.util.List; +import java.util.stream.Collectors; +import org.eclipse.jdt.core.dom.ASTNode; +import org.junit.Test; +import jp.kusumotolab.kgenprog.project.ProductSourcePath; + + +public class ASTStreamTest { + + @Test + public void test() { + final String source = new StringBuilder().append("") + .append("class A {\n") + .append(" public int a() {\n") + .append(" int v;\n") + .append(" return v + 1;\n") + .append(" }\n") + .append("}") + .toString(); + + final ProductSourcePath sourcePath = new ProductSourcePath(Paths.get("A.java")); + final JDTASTConstruction constructor = new JDTASTConstruction(); + final GeneratedJDTAST ast = constructor.constructAST(sourcePath, source); + + final List actual = ASTStream.stream(ast.getRoot()) + .collect(Collectors.toList()); + + assertThat(actual).extracting(e -> e.getClass() + .getSimpleName()) + .containsExactly("CompilationUnit", "TypeDeclaration", "SimpleName", "MethodDeclaration", + "Modifier", "PrimitiveType", "SimpleName", "Block", "VariableDeclarationStatement", + "PrimitiveType", "VariableDeclarationFragment", "SimpleName", "ReturnStatement", + "InfixExpression", "SimpleName", "NumberLiteral");; + } + +} From 1097c9cb739dd6f731a0246fa7098fce62c749f7 Mon Sep 17 00:00:00 2001 From: Ryo Arima Date: Tue, 13 Nov 2018 21:48:33 +0900 Subject: [PATCH 2/4] =?UTF-8?q?Timeout=20Rule=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=81=AEField=E3=82=92=E3=83=86=E3=82=B9=E3=83=88=E3=82=AF?= =?UTF-8?q?=E3=83=A9=E3=82=B9=E3=81=AB=E8=BF=BD=E5=8A=A0=E3=81=99=E3=82=8B?= =?UTF-8?q?Operation=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jdt/InsertTimeoutRuleFieldOperation.java | 140 ++++++++++++++++++ .../project/jdt/JDTASTConstruction.java | 2 +- .../InsertTimeoutRuleFieldOperationTest.java | 83 +++++++++++ 3 files changed, 224 insertions(+), 1 deletion(-) create mode 100644 src/main/java/jp/kusumotolab/kgenprog/project/jdt/InsertTimeoutRuleFieldOperation.java create mode 100644 src/test/java/jp/kusumotolab/kgenprog/project/jdt/InsertTimeoutRuleFieldOperationTest.java diff --git a/src/main/java/jp/kusumotolab/kgenprog/project/jdt/InsertTimeoutRuleFieldOperation.java b/src/main/java/jp/kusumotolab/kgenprog/project/jdt/InsertTimeoutRuleFieldOperation.java new file mode 100644 index 000000000..934477003 --- /dev/null +++ b/src/main/java/jp/kusumotolab/kgenprog/project/jdt/InsertTimeoutRuleFieldOperation.java @@ -0,0 +1,140 @@ +package jp.kusumotolab.kgenprog.project.jdt; + +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.ASTParser; +import org.eclipse.jdt.core.dom.FieldDeclaration; +import org.eclipse.jdt.core.dom.SimpleName; +import org.eclipse.jdt.core.dom.TypeDeclaration; +import org.eclipse.jdt.core.dom.VariableDeclarationFragment; +import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; +import org.eclipse.jdt.core.dom.rewrite.ListRewrite; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.Document; +import org.eclipse.text.edits.MalformedTreeException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import jp.kusumotolab.kgenprog.project.ASTLocation; +import jp.kusumotolab.kgenprog.project.GeneratedAST; +import jp.kusumotolab.kgenprog.project.GeneratedSourceCode; +import jp.kusumotolab.kgenprog.project.Operation; +import jp.kusumotolab.kgenprog.project.TestSourcePath; + + +public class InsertTimeoutRuleFieldOperation implements Operation { + + private static final Logger log = LoggerFactory.getLogger(InsertTimeoutRuleFieldOperation.class); + + private static final String INSERT_FIELD_NAME = "globalTimeout"; + private final int timeoutSeconds; + + public InsertTimeoutRuleFieldOperation(final int timeoutSeconds) { + this.timeoutSeconds = timeoutSeconds; + } + + @Override + public GeneratedSourceCode apply(final GeneratedSourceCode generatedSourceCode, + final ASTLocation location) { + + try { + final List> newTestAsts = generatedSourceCode.getTestAsts() + .stream() + .map(ast -> applyEachAST(ast)) + .collect(Collectors.toList()); + return new GeneratedSourceCode(generatedSourceCode.getProductAsts(), newTestAsts); + } catch (final Exception e) { + log.warn("Inserting timeout rule is failed: {}", e.getMessage()); + log.trace("Trace:", e); + return generatedSourceCode; + } + } + + private GeneratedAST applyEachAST(final GeneratedAST ast) { + final GeneratedJDTAST jdtast = (GeneratedJDTAST) ast; + final ASTRewrite astRewrite = ASTRewrite.create(jdtast.getRoot() + .getAST()); + + ASTStream.stream(jdtast.getRoot()) + .filter(TypeDeclaration.class::isInstance) + .map(TypeDeclaration.class::cast) + .forEach(d -> insertField(astRewrite, d)); + + final Document document = new Document(jdtast.getSourceCode()); + try { + astRewrite.rewriteAST(document, null) + .apply(document); + } catch (MalformedTreeException | BadLocationException e) { + throw new RuntimeException(e); + } + + return jdtast.getConstruction() + .constructAST(ast.getSourcePath(), document.get()); + } + + /** + * クラスにフィールドを追加する + * + * @param astRewrite ASTRewrite + * @param target 追加対象 + */ + private void insertField(final ASTRewrite astRewrite, final TypeDeclaration target) { + final String fieldName = createFieldName(target); + + final ListRewrite listRewrite = + astRewrite.getListRewrite(target, TypeDeclaration.BODY_DECLARATIONS_PROPERTY); + + final ASTNode astNode = ASTNode.copySubtree(astRewrite.getAST(), createInsertField(fieldName)); + listRewrite.insertFirst(astNode, null); + } + + + /** + * 重複しない変数名を生成する + * + * @param typeDeclaration 重複チェックをするクラス + * @return 生成された変数名 + */ + @SuppressWarnings("unchecked") + private String createFieldName(final TypeDeclaration typeDeclaration) { + final FieldDeclaration[] fields = typeDeclaration.getFields(); + final Set fieldNames = Arrays.stream(fields) + .flatMap(f -> ((List) (f.fragments())).stream()) + .map(VariableDeclarationFragment::getName) + .map(SimpleName::getIdentifier) + .collect(Collectors.toSet()); + + String insertFieldName = INSERT_FIELD_NAME; + while (fieldNames.contains(insertFieldName)) { + insertFieldName = "_" + insertFieldName; + } + + return insertFieldName; + } + + /** + * 挿入対象のFieldDeclarationを生成する + * + * @param fieldName 生成するフィールドの変数名 + * @return 生成されたFieldDeclaration + */ + private FieldDeclaration createInsertField(final String fieldName) { + final char[] insertSourceCode = new StringBuilder().append("") + .append("@org.junit.Rule\n") + .append("public final org.junit.rules.Timeout ") + .append(fieldName) + .append(" = org.junit.rules.Timeout.seconds(") + .append(timeoutSeconds) + .append(");") + .toString() + .toCharArray(); + + final ASTParser parser = JDTASTConstruction.createNewParser(); + parser.setKind(ASTParser.K_CLASS_BODY_DECLARATIONS); + parser.setSource(insertSourceCode); + final TypeDeclaration typeDeclaration = (TypeDeclaration) parser.createAST(null); + return typeDeclaration.getFields()[0]; + } +} diff --git a/src/main/java/jp/kusumotolab/kgenprog/project/jdt/JDTASTConstruction.java b/src/main/java/jp/kusumotolab/kgenprog/project/jdt/JDTASTConstruction.java index d1fa21329..d7d364a3c 100644 --- a/src/main/java/jp/kusumotolab/kgenprog/project/jdt/JDTASTConstruction.java +++ b/src/main/java/jp/kusumotolab/kgenprog/project/jdt/JDTASTConstruction.java @@ -86,7 +86,7 @@ public GeneratedJDTAST constructAST(final T sourcePath return new GeneratedJDTAST<>(this, sourcePath, (CompilationUnit) parser.createAST(null), data); } - private ASTParser createNewParser() { + public static ASTParser createNewParser() { final ASTParser parser = ASTParser.newParser(AST.JLS10); @SuppressWarnings("unchecked") diff --git a/src/test/java/jp/kusumotolab/kgenprog/project/jdt/InsertTimeoutRuleFieldOperationTest.java b/src/test/java/jp/kusumotolab/kgenprog/project/jdt/InsertTimeoutRuleFieldOperationTest.java new file mode 100644 index 000000000..5b6b2b448 --- /dev/null +++ b/src/test/java/jp/kusumotolab/kgenprog/project/jdt/InsertTimeoutRuleFieldOperationTest.java @@ -0,0 +1,83 @@ +package jp.kusumotolab.kgenprog.project.jdt; + +import static jp.kusumotolab.kgenprog.project.jdt.ASTNodeAssert.assertThat; +import java.nio.file.Paths; +import java.util.Collections; +import org.junit.Test; +import jp.kusumotolab.kgenprog.project.GeneratedSourceCode; +import jp.kusumotolab.kgenprog.project.TestSourcePath; + + +public class InsertTimeoutRuleFieldOperationTest { + + @Test + public void testInsert() { + final String source = new StringBuilder().append("") + .append("class A {") + .append(" public void a() {") + .append(" }") + .append("}") + .toString(); + + final TestSourcePath sourcePath = new TestSourcePath(Paths.get("A.java")); + final JDTASTConstruction constructor = new JDTASTConstruction(); + final GeneratedJDTAST ast = constructor.constructAST(sourcePath, source); + final GeneratedSourceCode sourceCode = + new GeneratedSourceCode(Collections.emptyList(), Collections.singletonList(ast)); + final InsertTimeoutRuleFieldOperation operation = new InsertTimeoutRuleFieldOperation(10); + final GeneratedSourceCode applyiedSourceCode = operation.apply(sourceCode, null); + + final String expected = new StringBuilder().append("") + .append("class A {") + .append(" @org.junit.Rule") + .append( + " public final org.junit.rules.Timeout globalTimeout = org.junit.rules.Timeout.seconds(10);") + .append(" public void a() {") + .append(" }") + .append("}") + .toString(); + + final GeneratedJDTAST newAST = + (GeneratedJDTAST) applyiedSourceCode.getTestAsts() + .get(0); + + assertThat(newAST.getRoot()).isSameSourceCodeAs(expected); + } + + @Test + public void testInsertDuplicateName() { + final String source = new StringBuilder().append("") + .append("class A {") + .append(" private int globalTimeout;") + .append(" public void a() {") + .append(" }") + .append("}") + .toString(); + + final TestSourcePath sourcePath = new TestSourcePath(Paths.get("A.java")); + final JDTASTConstruction constructor = new JDTASTConstruction(); + final GeneratedJDTAST ast = constructor.constructAST(sourcePath, source); + final GeneratedSourceCode sourceCode = + new GeneratedSourceCode(Collections.emptyList(), Collections.singletonList(ast)); + final InsertTimeoutRuleFieldOperation operation = new InsertTimeoutRuleFieldOperation(10); + final GeneratedSourceCode applyiedSourceCode = operation.apply(sourceCode, null); + + final String expected = new StringBuilder().append("") + .append("class A {") + .append(" @org.junit.Rule") + .append( + " public final org.junit.rules.Timeout _globalTimeout = org.junit.rules.Timeout.seconds(10);") + .append(" private int globalTimeout;") + .append(" public void a() {") + .append(" }") + .append("}") + .toString(); + + final GeneratedJDTAST newAST = + (GeneratedJDTAST) applyiedSourceCode.getTestAsts() + .get(0); + + assertThat(newAST.getRoot()).isSameSourceCodeAs(expected); + } + +} From 8a47e30779fdc1d2031f3c146d0ebe6ed05801c1 Mon Sep 17 00:00:00 2001 From: Ryo Arima Date: Tue, 13 Nov 2018 21:49:01 +0900 Subject: [PATCH 3/4] =?UTF-8?q?initialVariant=E7=94=9F=E6=88=90=E6=99=82?= =?UTF-8?q?=E3=81=AB=E3=82=BF=E3=82=A4=E3=83=A0=E3=82=A2=E3=82=A6=E3=83=88?= =?UTF-8?q?=E8=A8=AD=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/jp/kusumotolab/kgenprog/ga/VariantStore.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/jp/kusumotolab/kgenprog/ga/VariantStore.java b/src/main/java/jp/kusumotolab/kgenprog/ga/VariantStore.java index 3e6b8a9e9..6cdf712ac 100644 --- a/src/main/java/jp/kusumotolab/kgenprog/ga/VariantStore.java +++ b/src/main/java/jp/kusumotolab/kgenprog/ga/VariantStore.java @@ -9,7 +9,9 @@ import jp.kusumotolab.kgenprog.Strategies; import jp.kusumotolab.kgenprog.fl.Suspiciousness; import jp.kusumotolab.kgenprog.project.GeneratedSourceCode; +import jp.kusumotolab.kgenprog.project.Operation; import jp.kusumotolab.kgenprog.project.factory.TargetProject; +import jp.kusumotolab.kgenprog.project.jdt.InsertTimeoutRuleFieldOperation; import jp.kusumotolab.kgenprog.project.test.TestResults; public class VariantStore { @@ -136,7 +138,9 @@ public void changeGeneration() { private Variant createInitialVariant() { final GeneratedSourceCode sourceCode = strategies.execASTConstruction(targetProject); - return createVariant(new Gene(Collections.emptyList()), sourceCode, + final Operation operation = new InsertTimeoutRuleFieldOperation(10); + final GeneratedSourceCode appliedSourceCode = operation.apply(sourceCode, null); + return createVariant(new Gene(Collections.emptyList()), appliedSourceCode, new OriginalHistoricalElement()); } From 1f3a0c69a36716af1669817923cbf3ee844ce68b Mon Sep 17 00:00:00 2001 From: Ryo Arima Date: Wed, 14 Nov 2018 20:52:43 +0900 Subject: [PATCH 4/4] =?UTF-8?q?Configuration=E3=81=8B=E3=82=89Timeout?= =?UTF-8?q?=E7=A7=92=E6=95=B0=E3=82=92=E5=8F=96=E3=82=8A=E5=87=BA=E3=81=99?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jp/kusumotolab/kgenprog/KGenProgMain.java | 2 +- .../kusumotolab/kgenprog/ga/VariantStore.java | 16 ++++++----- .../jdt/InsertTimeoutRuleFieldOperation.java | 4 +-- .../kgenprog/ga/VariantStoreTest.java | 28 +++++++++++++------ 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java b/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java index 68e28c21c..dd1865864 100644 --- a/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java +++ b/src/main/java/jp/kusumotolab/kgenprog/KGenProgMain.java @@ -53,7 +53,7 @@ public KGenProgMain(final Configuration config, final FaultLocalization faultLoc public List run() { final Strategies strategies = new Strategies(faultLocalization, astConstruction, sourceCodeGeneration, sourceCodeValidation, testExecutor, variantSelection); - final VariantStore variantStore = new VariantStore(config.getTargetProject(), strategies); + final VariantStore variantStore = new VariantStore(config, strategies); final Variant initialVariant = variantStore.getInitialVariant(); sourceCodeGeneration.initialize(initialVariant); diff --git a/src/main/java/jp/kusumotolab/kgenprog/ga/VariantStore.java b/src/main/java/jp/kusumotolab/kgenprog/ga/VariantStore.java index 6cdf712ac..04a53aa62 100644 --- a/src/main/java/jp/kusumotolab/kgenprog/ga/VariantStore.java +++ b/src/main/java/jp/kusumotolab/kgenprog/ga/VariantStore.java @@ -5,18 +5,18 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import jp.kusumotolab.kgenprog.Configuration; import jp.kusumotolab.kgenprog.OrdinalNumber; import jp.kusumotolab.kgenprog.Strategies; import jp.kusumotolab.kgenprog.fl.Suspiciousness; import jp.kusumotolab.kgenprog.project.GeneratedSourceCode; import jp.kusumotolab.kgenprog.project.Operation; -import jp.kusumotolab.kgenprog.project.factory.TargetProject; import jp.kusumotolab.kgenprog.project.jdt.InsertTimeoutRuleFieldOperation; import jp.kusumotolab.kgenprog.project.test.TestResults; public class VariantStore { - private final TargetProject targetProject; + private final Configuration config; private final Strategies strategies; private final Variant initialVariant; private List currentVariants; @@ -24,8 +24,8 @@ public class VariantStore { private final List foundSolutions; private final OrdinalNumber generation; - public VariantStore(final TargetProject targetProject, final Strategies strategies) { - this.targetProject = targetProject; + public VariantStore(final Configuration config, final Strategies strategies) { + this.config = config; this.strategies = strategies; generation = new OrdinalNumber(0); @@ -41,7 +41,7 @@ public VariantStore(final TargetProject targetProject, final Strategies strategi */ @Deprecated public VariantStore(final Variant initialVariant) { - this.targetProject = null; + this.config = null; this.strategies = null; this.initialVariant = initialVariant; @@ -137,8 +137,10 @@ public void changeGeneration() { } private Variant createInitialVariant() { - final GeneratedSourceCode sourceCode = strategies.execASTConstruction(targetProject); - final Operation operation = new InsertTimeoutRuleFieldOperation(10); + final GeneratedSourceCode sourceCode = + strategies.execASTConstruction(config.getTargetProject()); + final Operation operation = + new InsertTimeoutRuleFieldOperation(config.getTestTimeLimitSeconds()); final GeneratedSourceCode appliedSourceCode = operation.apply(sourceCode, null); return createVariant(new Gene(Collections.emptyList()), appliedSourceCode, new OriginalHistoricalElement()); diff --git a/src/main/java/jp/kusumotolab/kgenprog/project/jdt/InsertTimeoutRuleFieldOperation.java b/src/main/java/jp/kusumotolab/kgenprog/project/jdt/InsertTimeoutRuleFieldOperation.java index 934477003..a41f8cc89 100644 --- a/src/main/java/jp/kusumotolab/kgenprog/project/jdt/InsertTimeoutRuleFieldOperation.java +++ b/src/main/java/jp/kusumotolab/kgenprog/project/jdt/InsertTimeoutRuleFieldOperation.java @@ -29,9 +29,9 @@ public class InsertTimeoutRuleFieldOperation implements Operation { private static final Logger log = LoggerFactory.getLogger(InsertTimeoutRuleFieldOperation.class); private static final String INSERT_FIELD_NAME = "globalTimeout"; - private final int timeoutSeconds; + private final long timeoutSeconds; - public InsertTimeoutRuleFieldOperation(final int timeoutSeconds) { + public InsertTimeoutRuleFieldOperation(final long timeoutSeconds) { this.timeoutSeconds = timeoutSeconds; } diff --git a/src/test/java/jp/kusumotolab/kgenprog/ga/VariantStoreTest.java b/src/test/java/jp/kusumotolab/kgenprog/ga/VariantStoreTest.java index f965eea0a..6b7317d76 100644 --- a/src/test/java/jp/kusumotolab/kgenprog/ga/VariantStoreTest.java +++ b/src/test/java/jp/kusumotolab/kgenprog/ga/VariantStoreTest.java @@ -11,6 +11,7 @@ import java.util.Collections; import java.util.List; import org.junit.Test; +import jp.kusumotolab.kgenprog.Configuration; import jp.kusumotolab.kgenprog.Strategies; import jp.kusumotolab.kgenprog.fl.Suspiciousness; import jp.kusumotolab.kgenprog.project.GeneratedSourceCode; @@ -24,7 +25,7 @@ public class VariantStoreTest { @Test public void testCreateVariant() { final Path basePath = Paths.get("example/BuildSuccess01"); - final TargetProject project = TargetProjectFactory.create(basePath); + final Configuration config = createMockConfiguration(basePath); final List faultLocalizationResult = new ArrayList<>(); final GeneratedSourceCode sourceCodeGenerationResult = @@ -41,7 +42,7 @@ public void testCreateVariant() { when(strategies.execASTConstruction(any())).thenReturn(astConstructionResult); when(strategies.execVariantSelection(any(), any())).thenReturn(Collections.emptyList()); - final VariantStore variantStore = new VariantStore(project, strategies); + final VariantStore variantStore = new VariantStore(config, strategies); final Variant initialVariant = variantStore.getInitialVariant(); assertThat(initialVariant.getGenerationNumber()).hasValue(0); @@ -70,11 +71,11 @@ public void testCreateVariant() { @Test public void testGetGenerationNumber() { final Path basePath = Paths.get("example/BuildSuccess01"); - final TargetProject project = TargetProjectFactory.create(basePath); + final Configuration config = createMockConfiguration(basePath); final Strategies strategies = mock(Strategies.class); when(strategies.execVariantSelection(any(), any())).thenReturn(Collections.emptyList()); - final VariantStore variantStore = new VariantStore(project, strategies); + final VariantStore variantStore = new VariantStore(config, strategies); // 初期世代番号は1 assertThat(variantStore.getGenerationNumber() @@ -94,11 +95,11 @@ public void testGetGenerationNumber() { @Test public void testGetGeneratedVariants() { final Path basePath = Paths.get("example/BuildSuccess01"); - final TargetProject project = TargetProjectFactory.create(basePath); + final Configuration config = createMockConfiguration(basePath); final Strategies strategies = mock(Strategies.class); when(strategies.execVariantSelection(any(), any())).then(v -> v.getArgument(1)); - final VariantStore variantStore = new VariantStore(project, strategies); + final VariantStore variantStore = new VariantStore(config, strategies); final Variant success1 = createMockVariant(true); final Variant success2 = createMockVariant(true); @@ -128,9 +129,9 @@ public void testGetGeneratedVariants() { @Test public void testGetFoundSolutions() { final Path basePath = Paths.get("example/BuildSuccess01"); - final TargetProject project = TargetProjectFactory.create(basePath); + final Configuration config = createMockConfiguration(basePath); final Strategies strategies = mock(Strategies.class); - final VariantStore variantStore = new VariantStore(project, strategies); + final VariantStore variantStore = new VariantStore(config, strategies); final Variant success1 = createMockVariant(true); final Variant success2 = createMockVariant(true); @@ -153,4 +154,15 @@ private Variant createMockVariant(final boolean isCompleted) { when(variant.isCompleted()).thenReturn(isCompleted); return variant; } + + private Configuration createMockConfiguration(final Path basePath) { + final TargetProject project = TargetProjectFactory.create(basePath); + final Configuration config = mock(Configuration.class); + + when(config.getTargetProject()).thenReturn(project); + when(config.getTimeLimitSeconds()) + .thenReturn(Configuration.DEFAULT_TEST_TIME_LIMIT.getSeconds()); + + return config; + } }