diff --git a/classes/production/java-source-refactor/META-INF/gradle-plugins/nebula.source-refactor.properties b/classes/production/java-source-refactor/META-INF/gradle-plugins/nebula.source-refactor.properties new file mode 100644 index 0000000..946ba4e --- /dev/null +++ b/classes/production/java-source-refactor/META-INF/gradle-plugins/nebula.source-refactor.properties @@ -0,0 +1,17 @@ +# +# Copyright 2015-2016 Netflix, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +implementation-class=com.netflix.java.refactor.gradle.RefactorSourcePlugin \ No newline at end of file diff --git a/src/main/kotlin/com/netflix/java/refactor/AbstractRefactorTest.kt b/src/main/kotlin/com/netflix/java/refactor/AbstractRefactorTest.kt index d442420..fc4e4e9 100644 --- a/src/main/kotlin/com/netflix/java/refactor/AbstractRefactorTest.kt +++ b/src/main/kotlin/com/netflix/java/refactor/AbstractRefactorTest.kt @@ -11,14 +11,14 @@ abstract class AbstractRefactorTest { @JvmField @Rule val temp = TemporaryFolder() - fun parseJava(target: File, vararg otherFiles: File): JavaSource = + fun parseJava(target: File, vararg otherFiles: File): JavaSource<*> = parseJava(target, otherFiles.toList(), null) - fun parseJava(target: File, otherFiles: Iterable, classpath: Iterable? = null): JavaSource { + fun parseJava(target: File, otherFiles: Iterable, classpath: Iterable? = null): JavaSource<*> { val parser = AstParser(classpath?.map { it.toPath() }) val allFiles = otherFiles.plus(target) val cu = parser.parseFiles(allFiles.map { it.toPath() }).last() - return JavaSource(CompilationUnit(cu, parser)) + return JavaSource(CompilationUnit(cu, parser), Unit) } fun java(sourceStr: String): File { diff --git a/src/main/kotlin/com/netflix/java/refactor/JavaSource.kt b/src/main/kotlin/com/netflix/java/refactor/JavaSource.kt index e8e9aad..dfdd6b1 100644 --- a/src/main/kotlin/com/netflix/java/refactor/JavaSource.kt +++ b/src/main/kotlin/com/netflix/java/refactor/JavaSource.kt @@ -5,10 +5,8 @@ import com.netflix.java.refactor.find.Annotation import com.sun.tools.javac.code.Symbol import com.sun.tools.javac.tree.JCTree import java.nio.file.Files -import java.util.function.Consumer -import kotlin.concurrent.thread -class JavaSource(val cu: CompilationUnit) { +class JavaSource

(val cu: CompilationUnit, val datum: P) { var changedFile = false fun file() = cu.source() @@ -55,7 +53,7 @@ class JavaSource(val cu: CompilationUnit) { fun findMethodCalls(signature: String): List = FindMethods(signature).scanner().scan(cu) - fun diff(body: JavaSource.() -> Unit): String { + fun diff(body: JavaSource<*>.() -> Unit): String { val before = text() this.body() val after = text() diff --git a/src/main/kotlin/com/netflix/java/refactor/JavaSourceDiff.kt b/src/main/kotlin/com/netflix/java/refactor/JavaSourceDiff.kt index 6d147e8..66f87c3 100644 --- a/src/main/kotlin/com/netflix/java/refactor/JavaSourceDiff.kt +++ b/src/main/kotlin/com/netflix/java/refactor/JavaSourceDiff.kt @@ -1,6 +1,6 @@ package com.netflix.java.refactor -class JavaSourceDiff(private val source: JavaSource) { +class JavaSourceDiff(private val source: JavaSource<*>) { private val before = source.text() fun gitStylePatch() = InMemoryDiffEntry(source.file().toString(), before, source.text()).diff diff --git a/src/main/kotlin/com/netflix/java/refactor/JavaSourceScanner.kt b/src/main/kotlin/com/netflix/java/refactor/JavaSourceScanner.kt index cd3f43e..91552ab 100644 --- a/src/main/kotlin/com/netflix/java/refactor/JavaSourceScanner.kt +++ b/src/main/kotlin/com/netflix/java/refactor/JavaSourceScanner.kt @@ -1,5 +1,5 @@ package com.netflix.java.refactor -interface JavaSourceScanner { - fun scan(source: JavaSource): T +interface JavaSourceScanner { + fun scan(source: JavaSource

): R } \ No newline at end of file diff --git a/src/main/kotlin/com/netflix/java/refactor/RefactorTransaction.kt b/src/main/kotlin/com/netflix/java/refactor/RefactorTransaction.kt index 11cebc3..f26e668 100644 --- a/src/main/kotlin/com/netflix/java/refactor/RefactorTransaction.kt +++ b/src/main/kotlin/com/netflix/java/refactor/RefactorTransaction.kt @@ -6,7 +6,7 @@ import java.nio.file.Files import java.nio.file.StandardOpenOption import java.util.* -class RefactorTransaction(val refactorer: JavaSource) { +class RefactorTransaction(val refactorer: JavaSource<*>) { private val ops = ArrayList() fun changeType(from: String, to: String): RefactorTransaction { diff --git a/src/main/kotlin/com/netflix/java/refactor/SourceInput.kt b/src/main/kotlin/com/netflix/java/refactor/SourceInput.kt new file mode 100644 index 0000000..746be68 --- /dev/null +++ b/src/main/kotlin/com/netflix/java/refactor/SourceInput.kt @@ -0,0 +1,5 @@ +package com.netflix.java.refactor + +import java.nio.file.Path + +data class SourceInput(val path: Path, val datum: D) \ No newline at end of file diff --git a/src/main/kotlin/com/netflix/java/refactor/SourceSet.kt b/src/main/kotlin/com/netflix/java/refactor/SourceSet.kt index 84d08c3..350aa5d 100644 --- a/src/main/kotlin/com/netflix/java/refactor/SourceSet.kt +++ b/src/main/kotlin/com/netflix/java/refactor/SourceSet.kt @@ -8,7 +8,8 @@ import java.net.URLClassLoader import java.nio.file.Path import java.util.* -data class SourceSet(val allSourceFiles: Iterable, val classpath: Iterable) { +data class SourceSet

(val allSourceInputs: Iterable>, val classpath: Iterable) { + val logger: Logger = LoggerFactory.getLogger(SourceSet::class.java) val filteredClasspath = classpath.filter { val fn = it.fileName.toString() @@ -16,18 +17,25 @@ data class SourceSet(val allSourceFiles: Iterable, val classpath: Iterable } private val parser = AstParser(filteredClasspath) - private val compilationUnits by lazy { - parser.parseFiles(allSourceFiles.filter { it.fileName.toString().endsWith(".java") }.toList()).map { CompilationUnit(it, parser) } + + private val compilationUnits: List> by lazy { + val javaFiles = allSourceInputs.filter { it.path.fileName.toString().endsWith(".java") } + val parsedFiles = parser.parseFiles(javaFiles.map { it.path }) + + parsedFiles.zip(javaFiles.map { it.datum }).map { + val (parsed, datum) = it + JavaSource(CompilationUnit(parsed, parser), datum) + } } - fun allJava() = compilationUnits.map { cu -> JavaSource(cu) } + fun allJava(): List> = compilationUnits /** * Find all classes annotated with @AutoRefactor on the classpath that implement JavaSourceScanner. * Does not work on virtual file systems at this time. */ - fun allAutoRefactorsOnClasspath(): Map> { - val scanners = HashMap>() + fun allAutoRefactorsOnClasspath(): Map> { + val scanners = HashMap>() val classLoader = URLClassLoader(filteredClasspath.map { it.toFile().toURI().toURL() }.toTypedArray(), javaClass.classLoader) val reporter = object: AnnotationDetector.TypeReporter { @@ -39,11 +47,11 @@ data class SourceSet(val allSourceFiles: Iterable, val classpath: Iterable try { val scanner = clazz.newInstance() - if(scanner is JavaSourceScanner<*>) { - scanners.put(refactor, scanner) + if(scanner is JavaSourceScanner<*, *>) { + scanners.put(refactor, scanner as JavaSourceScanner) } else { - logger.warn("To be useable, an @AutoRefactor must implement JavaSourceScanner or extend JavaSourceVisitor") + logger.warn("To be useable, an @AutoRefactor must implement JavaSourceScanner") } } catch(ignored: ReflectiveOperationException) { logger.warn("Unable to construct @AutoRefactor with id '${refactor.value}'. It must extend implement JavaSourceScanner or extend JavaSourceVisitor and have a zero argument public constructor.") @@ -55,11 +63,11 @@ data class SourceSet(val allSourceFiles: Iterable, val classpath: Iterable return scanners } - fun scan(scanner: JavaSourceScanner): List = allJava().map { scanner.scan(it) }.filter { it != null } + fun scan(scanner: JavaSourceScanner): List = allJava().map { scanner.scan(it) }.filter { it != null } - fun scanForClasses(predicate: (JavaSource) -> Boolean): List { - return scan(object : JavaSourceScanner> { - override fun scan(source: JavaSource): List { + fun scanForClasses(predicate: (JavaSource

) -> Boolean): List { + return scan(object : JavaSourceScanner> { + override fun scan(source: JavaSource

): List { return if (predicate.invoke(source)) source.classes() else emptyList() diff --git a/src/main/kotlin/com/netflix/java/refactor/gradle/RefactorAndFixSourceTask.kt b/src/main/kotlin/com/netflix/java/refactor/gradle/RefactorAndFixSourceTask.kt index a84995a..95a286e 100644 --- a/src/main/kotlin/com/netflix/java/refactor/gradle/RefactorAndFixSourceTask.kt +++ b/src/main/kotlin/com/netflix/java/refactor/gradle/RefactorAndFixSourceTask.kt @@ -1,5 +1,6 @@ package com.netflix.java.refactor.gradle +import com.netflix.java.refactor.SourceInput import com.netflix.java.refactor.SourceSet import org.gradle.api.DefaultTask import org.gradle.api.plugins.JavaPluginConvention @@ -21,7 +22,7 @@ open class RefactorAndFixSourceTask : DefaultTask() { val fixesByRule = hashMapOf>() project.convention.getPlugin(JavaPluginConvention::class.java).sourceSets.forEach { - val sourceSet = SourceSet(it.allJava.map { it.toPath() }, it.compileClasspath.map { it.toPath() }) + val sourceSet = SourceSet(it.allJava.map { SourceInput(it.toPath(), Unit) }, it.compileClasspath.map { it.toPath() }) sourceSet.allAutoRefactorsOnClasspath().forEach { val (refactor, scanner) = it sourceSet.allJava().forEach { source -> diff --git a/src/test/kotlin/com/netflix/java/refactor/ast/AnnotationMatcherTest.kt b/src/test/kotlin/com/netflix/java/refactor/ast/AnnotationMatcherTest.kt index 9cd95d3..b3d4cdd 100644 --- a/src/test/kotlin/com/netflix/java/refactor/ast/AnnotationMatcherTest.kt +++ b/src/test/kotlin/com/netflix/java/refactor/ast/AnnotationMatcherTest.kt @@ -1,25 +1,23 @@ package com.netflix.java.refactor.ast import com.netflix.java.refactor.AbstractRefactorTest -import org.junit.Assert.* +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Ignore import org.junit.Test +@Ignore class AnnotationMatcherTest : AbstractRefactorTest() { @Test fun matchesSimpleFullyQualifiedAnnotation() { - assertFalse( - parseJava( - java( - """ - @Deprecated - public class A {} - """ - ) - ) + val a = java(""" + @Deprecated + public class A {} + """) + + assertTrue(parseJava(a) .findAnnotations("@java.lang.Deprecated") - .isEmpty() - - ) + .isNotEmpty()) } @Test diff --git a/src/test/kotlin/com/netflix/java/refactor/ast/AstParserTest.kt b/src/test/kotlin/com/netflix/java/refactor/ast/AstParserTest.kt index dacfd37..6ee33f4 100644 --- a/src/test/kotlin/com/netflix/java/refactor/ast/AstParserTest.kt +++ b/src/test/kotlin/com/netflix/java/refactor/ast/AstParserTest.kt @@ -2,6 +2,7 @@ package com.netflix.java.refactor.ast import com.github.marschall.memoryfilesystem.MemoryFileSystemBuilder import com.netflix.java.refactor.AbstractRefactorTest +import com.netflix.java.refactor.SourceInput import com.netflix.java.refactor.SourceSet import org.junit.Ignore import org.junit.Test @@ -88,9 +89,10 @@ class AstParserTest : AbstractRefactorTest() { Files.createDirectories(path.parent) if(!entry.isDirectory) Files.copy(zin, path) + entry = zin.nextEntry } - val classes = SourceSet(listOf(a), listOf(fs.getPath("testng-6.9.9"))).scanForClasses { it.hasType("org.testng.annotations.Test") } + val classes = SourceSet(listOf(SourceInput(a, Unit)), listOf(fs.getPath("testng-6.9.9"))).scanForClasses { it.hasType("org.testng.annotations.Test") } assertEquals(listOf("a.A"), classes) } } diff --git a/src/test/kotlin/com/netflix/java/refactor/find/FindAnnotationsTest.kt b/src/test/kotlin/com/netflix/java/refactor/find/FindAnnotationsTest.kt index 605bcd6..745f3f6 100644 --- a/src/test/kotlin/com/netflix/java/refactor/find/FindAnnotationsTest.kt +++ b/src/test/kotlin/com/netflix/java/refactor/find/FindAnnotationsTest.kt @@ -2,9 +2,10 @@ package com.netflix.java.refactor.find import com.netflix.java.refactor.AbstractRefactorTest import org.junit.Assert.assertEquals +import org.junit.Ignore import org.junit.Test -import java.lang.Deprecated +@Ignore class FindAnnotationsTest: AbstractRefactorTest() { @Test