J2K: conversion with usage processing across multiple converted files works in tests (but not in real life yet)

This commit is contained in:
Valentin Kipyatkov
2014-10-20 22:34:22 +04:00
committed by valentin
parent 41c7ec8285
commit abf537e348
1111 changed files with 1904 additions and 1625 deletions
@@ -113,7 +113,7 @@ import org.jetbrains.jet.plugin.stubs.AbstractLazyResolveByStubTest
import org.jetbrains.jet.plugin.stubs.AbstractMultiFileHighlightingTest
import org.jetbrains.jet.cfg.AbstractPseudoValueTest
import org.jetbrains.jet.plugin.structureView.AbstractKotlinFileStructureTest
import org.jetbrains.jet.j2k.test.AbstractJavaToKotlinConverterTest
import org.jetbrains.jet.j2k.test.AbstractJavaToKotlinConverterSingleFileTest
import org.jetbrains.jet.jps.build.AbstractIncrementalJpsTest
import org.jetbrains.jet.asJava.AbstractKotlinLightClassTest
import org.jetbrains.jet.lang.resolve.java.AbstractJavaTypeSubstitutorTest
@@ -127,6 +127,7 @@ import org.jetbrains.jet.generators.tests.reservedWords.generateTestDataForReser
import org.jetbrains.k2js.test.semantics.AbstractReservedWordTest
import org.jetbrains.jet.resolve.AbstractReferenceResolveInJavaTest
import org.jetbrains.k2js.test.semantics.AbstractBridgeTest
import org.jetbrains.jet.j2k.test.AbstractJavaToKotlinConverterMultiFileTest
import org.jetbrains.jet.j2k.test.AbstractJavaToKotlinConverterForWebDemoTest
fun main(args: Array<String>) {
@@ -629,14 +630,18 @@ fun main(args: Array<String>) {
}
testGroup("j2k/tests/test", "j2k/tests/testData") {
testClass(javaClass<AbstractJavaToKotlinConverterTest>()) {
model("ast", extension = "java")
testClass(javaClass<AbstractJavaToKotlinConverterSingleFileTest>()) {
model("fileOrElement", extension = "java")
}
}
testGroup("j2k/tests/test", "j2k/tests/testData") {
testClass(javaClass<AbstractJavaToKotlinConverterForWebDemoTest>()) {
model("ast", extension = "java")
testClass(javaClass<AbstractJavaToKotlinConverterMultiFileTest>()) {
model("multiFile", extension = null)
}
}
testGroup("j2k/tests/test", "j2k/tests/testData") {
testClass(javaClass<AbstractJavaToKotlinConverterForWebDemoTest>()) {
model("fileOrElement", extension = "java")
}
}
@@ -25,8 +25,10 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiJavaFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.j2k.*;
import org.jetbrains.jet.plugin.j2k.J2kPostProcessor;
import org.jetbrains.jet.j2k.ConverterSettings;
import org.jetbrains.jet.j2k.FilesConversionScope;
import org.jetbrains.jet.j2k.IdeaReferenceSearcher;
import org.jetbrains.jet.j2k.JavaToKotlinConverter;
import java.util.List;
@@ -47,9 +49,7 @@ public class JavaToKotlinAction extends AnAction {
final JavaToKotlinConverter converter = new JavaToKotlinConverter(project,
ConverterSettings.defaultSettings,
new FilesConversionScope(selectedJavaFiles),
IdeaReferenceSearcher.INSTANCE$,
//TODO: (module refactoring) resulting files should be analyzed in context of respective java files
new J2kPostProcessor(selectedJavaFiles.iterator().next()));
IdeaReferenceSearcher.INSTANCE$);
CommandProcessor.getInstance().executeCommand(
project,
new Runnable() {
@@ -21,13 +21,17 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ex.MessagesEx;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiJavaFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.codeStyle.CodeStyleManager;
import kotlin.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.j2k.JavaToKotlinConverter;
import org.jetbrains.jet.j2k.PostProcessor;
import org.jetbrains.jet.plugin.j2k.J2kPostProcessor;
import java.io.IOException;
import java.util.*;
@@ -124,7 +128,8 @@ public class JavaToKotlinActionUtil {
try {
VirtualFile virtualFile = psiFile.getVirtualFile();
if (psiFile instanceof PsiJavaFile && virtualFile != null) {
String result = converter.elementToKotlin(psiFile);
J2kPostProcessor postProcessor = new J2kPostProcessor(psiFile);
String result = converter.elementsToKotlin(new Pair<PsiElement, PostProcessor>(psiFile, postProcessor)).get(0); //TODO: convert all files in one call!
PsiManager manager = psiFile.getManager();
assert manager != null;
VirtualFile copy = virtualFile.copy(manager, virtualFile.getParent(), virtualFile.getNameWithoutExtension() + ".kt");
@@ -32,8 +32,8 @@ import org.jetbrains.jet.plugin.editor.JetEditorOptions
import java.awt.datatransfer.Transferable
import com.intellij.openapi.util.TextRange
import com.intellij.psi.codeStyle.CodeStyleManager
import org.jetbrains.jet.plugin.j2k.J2kPostProcessor;
import com.intellij.lang.java.JavaLanguage
import org.jetbrains.jet.plugin.j2k.J2kPostProcessor
public class ConvertJavaCopyPastePostProcessor() : CopyPastePostProcessor<TextBlockTransferableData>() {
@@ -89,8 +89,7 @@ public class ConvertJavaCopyPastePostProcessor() : CopyPastePostProcessor<TextBl
val converter = JavaToKotlinConverter(fileCopiedFrom.getProject(),
ConverterSettings.defaultSettings,
FilesConversionScope(listOf(fileCopiedFrom)),
IdeaReferenceSearcher,
J2kPostProcessor(fileCopiedTo))
IdeaReferenceSearcher)
val startOffsets = code.startOffsets
val endOffsets = code.endOffsets
assert(startOffsets.size == endOffsets.size) { "Must have the same size" }
@@ -98,12 +97,13 @@ public class ConvertJavaCopyPastePostProcessor() : CopyPastePostProcessor<TextBl
for (i in startOffsets.indices) {
val startOffset = startOffsets[i]
val endOffset = endOffsets[i]
result.append(convertRangeToKotlin(fileCopiedFrom, TextRange(startOffset, endOffset), converter))
result.append(convertRangeToKotlin(fileCopiedFrom, fileCopiedTo, TextRange(startOffset, endOffset), converter))
}
return StringUtil.convertLineSeparators(result.toString())
}
private fun convertRangeToKotlin(file: PsiJavaFile,
fileCopiedTo: JetFile,
range: TextRange,
converter: JavaToKotlinConverter): String {
val result = StringBuilder()
@@ -120,7 +120,7 @@ public class ConvertJavaCopyPastePostProcessor() : CopyPastePostProcessor<TextBl
val elementToConvert = findTopMostParentWhollyInRange(currentRange, leafElement)
val unconvertedPrefix = fileText.substring(currentRange.start, elementToConvert.range.start)
result.append(unconvertedPrefix)
val converted = converter.elementToKotlin(elementToConvert)
val converted = converter.elementsToKotlin(elementToConvert to J2kPostProcessor(fileCopiedTo))[0]
if (converted.isNotEmpty()) {
result.append(converted)
}
+20 -5
View File
@@ -72,7 +72,25 @@ class Converter private(private val elementToConvert: PsiElement,
private fun createDefaultCodeConverter() = CodeConverter(this, DefaultExpressionConverter(), DefaultStatementConverter(), null)
public fun convert(): Element? = convertTopElement(elementToConvert)
public trait IntermediateResult {
fun finishConversion(usageProcessings: Collection<UsageProcessing>): String
val usageProcessings: Collection<UsageProcessing>
}
public fun convert(): IntermediateResult? {
val element = convertTopElement(elementToConvert) ?: return null
return object: IntermediateResult {
override fun finishConversion(usageProcessings: Collection<UsageProcessing>): String {
unfoldLazyElements(usageProcessings)
val builder = CodeBuilder(elementToConvert)
builder.append(element)
return builder.result
}
override val usageProcessings: Collection<UsageProcessing> = commonState.usageProcessings
}
}
private fun convertTopElement(element: PsiElement): Element? = when (element) {
is PsiJavaFile -> convertFile(element)
@@ -88,10 +106,7 @@ class Converter private(private val elementToConvert: PsiElement,
else -> null
}
public val usageProcessings: Collection<UsageProcessing>
get() = commonState.usageProcessings
public fun unfoldLazyElements(usageProcessings: Collection<UsageProcessing>) {
private fun unfoldLazyElements(usageProcessings: Collection<UsageProcessing>) {
val codeConverter = createDefaultCodeConverter().withSpecialExpressionConverter(UsageProcessingExpressionConverter(usageProcessings))
// we use loop with index because new lazy elements can be added during unfolding
@@ -24,7 +24,8 @@ import com.intellij.psi.PsiJavaFile
import org.jetbrains.jet.lang.psi.JetFile
import org.jetbrains.jet.lang.resolve.BindingContext
import com.intellij.openapi.diagnostic.Logger
import org.jetbrains.jet.j2k.usageProcessing.UsageProcessingExpressionConverter
import java.util.ArrayList
import org.jetbrains.jet.j2k.usageProcessing.UsageProcessing
public trait ConversionScope {
public fun contains(element: PsiElement): Boolean
@@ -42,43 +43,52 @@ public trait PostProcessor {
public class JavaToKotlinConverter(private val project: Project,
private val settings: ConverterSettings,
private val conversionScope: ConversionScope,
private val referenceSearcher: ReferenceSearcher,
private val postProcessor: PostProcessor?) {
private val conversionScope: ConversionScope /*TODO: drop this parameter*/,
private val referenceSearcher: ReferenceSearcher) {
private val LOG = Logger.getInstance("#org.jetbrains.jet.j2k.JavaToKotlinConverter")
//TODO: run not for one element when multiple files
public fun elementToKotlin(psiElement: PsiElement): String {
public fun elementsToKotlin(vararg psiElementsAndProcessors: Pair<PsiElement, PostProcessor?>): List<String> {
try {
val converter = Converter.create(psiElement, settings, conversionScope, referenceSearcher, postProcessor)
val element = converter.convert() ?: return ""
val intermediateResults = ArrayList<Converter.IntermediateResult?>(psiElementsAndProcessors.size)
val usageProcessings = ArrayList<UsageProcessing>()
for ((psiElement, postProcessor) in psiElementsAndProcessors) {
val converter = Converter.create(psiElement, settings, conversionScope, referenceSearcher, postProcessor)
val result = converter.convert()
intermediateResults.add(result)
result?.usageProcessings?.let { usageProcessings.addAll(it) }
}
converter.unfoldLazyElements(converter.usageProcessings)
val results = ArrayList<String>(psiElementsAndProcessors.size)
for (result in intermediateResults) {
results.add(result?.finishConversion(usageProcessings) ?: "")
}
val builder = CodeBuilder(psiElement)
builder.append(element)
if (postProcessor != null) {
try {
return AfterConversionPass(project, postProcessor).run(builder.result)
val finalResults = ArrayList<String>(psiElementsAndProcessors.size)
for ((i, result) in results.withIndices()) {
val postProcessor = psiElementsAndProcessors[i].second
if (postProcessor != null) {
try {
finalResults.add(AfterConversionPass(project, postProcessor).run(result))
}
catch(e: ProcessCanceledException) {
throw e
}
catch(t: Throwable) {
LOG.error(t)
finalResults.add(result)
}
}
catch(e: ProcessCanceledException) {
throw e
}
catch(t: Throwable) {
LOG.error(t)
return builder.result
else {
finalResults.add(result)
}
}
else {
return builder.result
}
return finalResults
}
catch(e: ElementCreationStackTraceRequiredException) {
// if we got this exception then we need to turn element creation stack traces on to get better diagnostic
Element.saveCreationStacktraces = true
try {
return elementToKotlin(psiElement)
return elementsToKotlin(*psiElementsAndProcessors)
}
finally {
Element.saveCreationStacktraces = false
@@ -90,8 +90,8 @@ public object JavaToKotlinTranslator {
fun generateKotlinCode(javaCode: String): String {
val file = createFile(javaCode)
if (file is PsiJavaFile) {
val converter = JavaToKotlinConverter(file.getProject(), ConverterSettings.defaultSettings, FilesConversionScope(listOf(file)), EmptyReferenceSearcher, null)
return prettify(converter.elementToKotlin(file))
val converter = JavaToKotlinConverter(file.getProject(), ConverterSettings.defaultSettings, FilesConversionScope(listOf(file)), EmptyReferenceSearcher)
return prettify(converter.elementsToKotlin(file to null)[0])
}
return ""
}
@@ -0,0 +1,68 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* 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.
*/
package org.jetbrains.jet.j2k.test
import java.io.File
import com.intellij.testFramework.LightPlatformTestCase
import com.intellij.psi.codeStyle.CodeStyleManager
import org.jetbrains.jet.JetTestUtils
import com.intellij.openapi.project.Project
import com.intellij.openapi.command.WriteCommandAction
import org.jetbrains.jet.j2k.FilesConversionScope
import org.jetbrains.jet.plugin.j2k.J2kPostProcessor
import org.jetbrains.jet.plugin.JetWithJdkAndRuntimeLightProjectDescriptor
import com.intellij.psi.PsiJavaFile
import org.jetbrains.jet.j2k.IdeaReferenceSearcher
import org.jetbrains.jet.j2k.JavaToKotlinConverter
import com.intellij.psi.PsiManager
import java.util.ArrayList
import org.jetbrains.jet.j2k.ConverterSettings
public abstract class AbstractJavaToKotlinConverterMultiFileTest() : AbstractJavaToKotlinConverterTest() {
public fun doTest(dirPath: String) {
val project = LightPlatformTestCase.getProject()!!
val javaFiles = File(dirPath).listFiles {(file, name): Boolean -> name.endsWith(".java") }
val psiFiles = ArrayList<PsiJavaFile>()
for (javaFile: File in javaFiles) {
val virtualFile = addFile(javaFile, "test")
val psiFile = PsiManager.getInstance(project).findFile(virtualFile) as PsiJavaFile
psiFiles.add(psiFile)
}
val converter = JavaToKotlinConverter(project, ConverterSettings.defaultSettings, FilesConversionScope(psiFiles), IdeaReferenceSearcher)
val results: List<String> = converter.elementsToKotlin(*psiFiles.map { it to J2kPostProcessor(it) }.copyToArray())
.map { reformat(it, project) }
for ((i, javaFile) in javaFiles.withIndices()) {
val kotlinPath = javaFile.getPath().replace(".java", ".kt")
val expectedFile = File(kotlinPath)
JetTestUtils.assertEqualsToFile(expectedFile, results[i])
}
}
private fun reformat(text: String, project: Project): String {
val convertedFile = JetTestUtils.createFile("converted", text, project)
WriteCommandAction.runWriteCommandAction(project) {
CodeStyleManager.getInstance(project)!!.reformat(convertedFile)
}
return convertedFile.getText()!!
}
override fun getProjectDescriptor()
= JetWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
}
@@ -0,0 +1,149 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* 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.
*/
package org.jetbrains.jet.j2k.test
import java.io.File
import com.intellij.openapi.util.io.FileUtil
import org.jetbrains.jet.j2k.ConverterSettings
import java.util.regex.Pattern
import com.intellij.testFramework.LightPlatformTestCase
import com.intellij.psi.codeStyle.CodeStyleManager
import org.jetbrains.jet.JetTestUtils
import com.intellij.openapi.project.Project
import com.intellij.openapi.command.WriteCommandAction
import org.jetbrains.jet.test.util.trimIndent
import org.jetbrains.jet.j2k.FilesConversionScope
import org.jetbrains.jet.plugin.j2k.J2kPostProcessor
import org.jetbrains.jet.plugin.JetWithJdkAndRuntimeLightProjectDescriptor
import com.intellij.psi.PsiJavaFile
import org.jetbrains.jet.j2k.IdeaReferenceSearcher
import org.jetbrains.jet.j2k.JavaToKotlinConverter
public abstract class AbstractJavaToKotlinConverterSingleFileTest() : AbstractJavaToKotlinConverterTest() {
val testHeaderPattern = Pattern.compile("//(element|expression|statement|method|class|file|comp)\n")
public fun doTest(javaPath: String) {
val project = LightPlatformTestCase.getProject()!!
val javaFile = File(javaPath)
val fileContents = FileUtil.loadFile(javaFile, true)
val matcher = testHeaderPattern.matcher(fileContents)
val (prefix, javaCode) = if (matcher.find()) {
Pair(matcher.group().trim().substring(2), matcher.replaceFirst(""))
}
else {
Pair("file", fileContents)
}
fun parseBoolean(text: String): Boolean = when (text) {
"true" -> true
"false" -> false
else -> throw IllegalArgumentException("Unknown option value: $text")
}
var settings = ConverterSettings.defaultSettings.copy()
val directives = JetTestUtils.parseDirectives(javaCode)
for ((name, value) in directives) {
when (name) {
"forceNotNullTypes" -> settings.forceNotNullTypes = parseBoolean(value)
"specifyLocalVariableTypeByDefault" -> settings.specifyLocalVariableTypeByDefault = parseBoolean(value)
"specifyFieldTypeByDefault" -> settings.specifyFieldTypeByDefault = parseBoolean(value)
"openByDefault" -> settings.openByDefault = parseBoolean(value)
else -> throw IllegalArgumentException("Unknown option: $name")
}
}
val rawConverted = when (prefix) {
"element" -> elementToKotlin(javaCode, settings, project)
"expression" -> expressionToKotlin(javaCode, settings, project)
"statement" -> statementToKotlin(javaCode, settings, project)
"method" -> methodToKotlin(javaCode, settings, project)
"class" -> fileToKotlin(javaCode, settings, project)
"file" -> fileToKotlin(javaCode, settings, project)
else -> throw IllegalStateException("Specify what is it: file, class, method, statement or expression " +
"using the first line of test data file")
}
val reformatInFun = prefix in setOf("element", "expression", "statement")
val actual = reformat(rawConverted, project, reformatInFun)
val kotlinPath = javaPath.replace(".java", ".kt")
val expectedFile = File(kotlinPath)
JetTestUtils.assertEqualsToFile(expectedFile, actual)
}
private fun reformat(text: String, project: Project, inFunContext: Boolean): String {
val textToFormat = if (inFunContext) "fun convertedTemp() {\n$text\n}" else text
val convertedFile = JetTestUtils.createFile("converted", textToFormat, project)
WriteCommandAction.runWriteCommandAction(project) {
CodeStyleManager.getInstance(project)!!.reformat(convertedFile)
}
val reformattedText = convertedFile.getText()!!
return if (inFunContext)
reformattedText.removeFirstLine().removeLastLine().trimIndent()
else
reformattedText
}
private fun elementToKotlin(text: String, settings: ConverterSettings, project: Project): String {
val fileWithText = createJavaFile(text)
val converter = JavaToKotlinConverter(project, settings, FilesConversionScope(listOf(fileWithText)), IdeaReferenceSearcher)
val element = fileWithText.getFirstChild()!!
return converter.elementsToKotlin(element to J2kPostProcessor(fileWithText))[0]
}
private fun fileToKotlin(text: String, settings: ConverterSettings, project: Project): String {
val file = createJavaFile(text)
val converter = JavaToKotlinConverter(project, settings, FilesConversionScope(listOf(file)), IdeaReferenceSearcher)
return converter.elementsToKotlin(file to J2kPostProcessor(file))[0]
}
private fun methodToKotlin(text: String, settings: ConverterSettings, project: Project): String {
val result = fileToKotlin("final class C {" + text + "}", settings, project).replaceAll("class C \\{", "")
return result.substring(0, (result.lastIndexOf("}"))).trim()
}
private fun statementToKotlin(text: String, settings: ConverterSettings, project: Project): String {
val result = methodToKotlin("void main() {" + text + "}", settings, project)
return result.substring(0, result.lastIndexOf("}")).replaceFirst("fun main\\(\\) \\{", "").trim()
}
private fun expressionToKotlin(code: String, settings: ConverterSettings, project: Project): String {
val result = statementToKotlin("final Object o =" + code + "}", settings, project)
return result.replaceFirst("val o:Any\\? = ", "").replaceFirst("val o:Any = ", "").replaceFirst("val o = ", "").trim()
}
override fun getProjectDescriptor()
= JetWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
private fun String.removeFirstLine(): String {
val lastNewLine = indexOf('\n')
return if (lastNewLine == -1) "" else substring(lastNewLine)
}
private fun String.removeLastLine(): String {
val lastNewLine = lastIndexOf('\n')
return if (lastNewLine == -1) "" else substring(0, lastNewLine)
}
private fun createJavaFile(text: String): PsiJavaFile {
return myFixture.configureByText("converterTestFile.java", text) as PsiJavaFile
}
}
@@ -16,169 +16,51 @@
package org.jetbrains.jet.j2k.test
import java.io.File
import com.intellij.openapi.util.io.FileUtil
import org.jetbrains.jet.j2k.ConverterSettings
import java.util.regex.Pattern
import java.io.File
import com.intellij.testFramework.LightPlatformTestCase
import com.intellij.psi.codeStyle.CodeStyleManager
import org.jetbrains.jet.JetTestUtils
import com.intellij.openapi.project.Project
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.application.ApplicationManager
import org.jetbrains.jet.test.util.trimIndent
import org.jetbrains.jet.j2k.FilesConversionScope
import org.jetbrains.jet.plugin.j2k.J2kPostProcessor
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import org.jetbrains.jet.plugin.JetWithJdkAndRuntimeLightProjectDescriptor
import com.intellij.psi.PsiJavaFile
import org.jetbrains.jet.j2k.IdeaReferenceSearcher
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.util.Computable
import junit.framework.TestCase
import org.jetbrains.jet.j2k.translateToKotlin
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
import org.jetbrains.jet.JetTestCaseBuilder
import com.intellij.openapi.util.Disposer
import org.jetbrains.jet.j2k.JavaToKotlinConverter
import org.jetbrains.jet.j2k.JavaToKotlinTranslator
import org.jetbrains.jet.JetTestCaseBuilder
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
public abstract class AbstractJavaToKotlinConverterTest() : LightCodeInsightFixtureTestCase() {
val testHeaderPattern = Pattern.compile("//(element|expression|statement|method|class|file|comp)\n")
public abstract class AbstractJavaToKotlinConverterTest : LightCodeInsightFixtureTestCase() {
override fun setUp() {
super.setUp()
VfsRootAccess.allowRootAccess(JetTestCaseBuilder.getHomeDirectory())
fun addFile(fileName: String, packageName: String) {
val code = FileUtil.loadFile(File("j2k/tests/testData/$fileName"), true)
val root = LightPlatformTestCase.getSourceRoot()!!
val dir = root.findChild(packageName) ?: root.createChildDirectory(null, packageName)
val file = dir.createChildData(null, fileName)!!
file.getOutputStream(null)!!.writer().use { it.write(code) }
}
ApplicationManager.getApplication()!!.runWriteAction{
addFile("KotlinApi.kt", "kotlinApi")
addFile("JavaApi.java", "javaApi")
}
addFile("KotlinApi.kt", "kotlinApi")
addFile("JavaApi.java", "javaApi")
}
override fun tearDown() {
VfsRootAccess.disallowRootAccess(JetTestCaseBuilder.getHomeDirectory())
super<LightCodeInsightFixtureTestCase>.tearDown()
super.tearDown()
}
private fun addFile(fileName: String, packageName: String) {
addFile(File("j2k/tests/testData/$fileName"), packageName)
}
public fun doTest(javaPath: String) {
val project = LightPlatformTestCase.getProject()!!
val javaFile = File(javaPath)
val fileContents = FileUtil.loadFile(javaFile, true)
val matcher = testHeaderPattern.matcher(fileContents)
val (prefix, javaCode) = if (matcher.find()) {
Pair(matcher.group().trim().substring(2), matcher.replaceFirst(""))
}
else {
Pair("file", fileContents)
}
fun parseBoolean(text: String): Boolean = when (text) {
"true" -> true
"false" -> false
else -> throw IllegalArgumentException("Unknown option value: $text")
}
var settings = ConverterSettings.defaultSettings.copy()
val directives = JetTestUtils.parseDirectives(javaCode)
for ((name, value) in directives) {
when (name) {
"forceNotNullTypes" -> settings.forceNotNullTypes = parseBoolean(value)
"specifyLocalVariableTypeByDefault" -> settings.specifyLocalVariableTypeByDefault = parseBoolean(value)
"specifyFieldTypeByDefault" -> settings.specifyFieldTypeByDefault = parseBoolean(value)
"openByDefault" -> settings.openByDefault = parseBoolean(value)
else -> throw IllegalArgumentException("Unknown option: $name")
fun addFile(file: File, packageName: String): VirtualFile {
return ApplicationManager.getApplication()!!.runWriteAction(object: Computable<VirtualFile> {
override fun compute(): VirtualFile? {
val code = FileUtil.loadFile(file, true)
val root = LightPlatformTestCase.getSourceRoot()!!
val virtualDir = root.findChild(packageName) ?: root.createChildDirectory(null, packageName)
val virtualFile = virtualDir.createChildData(null, file.getName())!!
virtualFile.getOutputStream(null)!!.writer().use { it.write(code) }
return virtualFile
}
}
val rawConverted = when (prefix) {
"element" -> elementToKotlin(javaCode, settings, project)
"expression" -> expressionToKotlin(javaCode, settings, project)
"statement" -> statementToKotlin(javaCode, settings, project)
"method" -> methodToKotlin(javaCode, settings, project)
"class" -> fileToKotlin(javaCode, settings, project)
"file" -> fileToKotlin(javaCode, settings, project)
else -> throw IllegalStateException("Specify what is it: file, class, method, statement or expression " +
"using the first line of test data file")
}
val reformatInFun = prefix in setOf("element", "expression", "statement")
val actual = reformat(rawConverted, project, reformatInFun)
val kotlinPath = javaPath.replace(".java", ".kt")
val expectedFile = File(kotlinPath)
JetTestUtils.assertEqualsToFile(expectedFile, actual)
})
}
private fun reformat(text: String, project: Project, inFunContext: Boolean): String {
val textToFormat = if (inFunContext) "fun convertedTemp() {\n$text\n}" else text
val convertedFile = JetTestUtils.createFile("converted", textToFormat, project)
WriteCommandAction.runWriteCommandAction(project) {
CodeStyleManager.getInstance(project)!!.reformat(convertedFile)
}
val reformattedText = convertedFile.getText()!!
return if (inFunContext)
reformattedText.removeFirstLine().removeLastLine().trimIndent()
else
reformattedText
}
private fun elementToKotlin(text: String, settings: ConverterSettings, project: Project): String {
val fileWithText = createJavaFile(text)
val converter = JavaToKotlinConverter(project, settings, FilesConversionScope(listOf(fileWithText)), IdeaReferenceSearcher, J2kPostProcessor(fileWithText))
val element = fileWithText.getFirstChild()!!
return converter.elementToKotlin(element)
}
private fun fileToKotlin(text: String, settings: ConverterSettings, project: Project): String {
val file = createJavaFile(text)
val converter = JavaToKotlinConverter(project, settings, FilesConversionScope(listOf(file)), IdeaReferenceSearcher, J2kPostProcessor(file))
return converter.elementToKotlin(file)
}
private fun methodToKotlin(text: String, settings: ConverterSettings, project: Project): String {
val result = fileToKotlin("final class C {" + text + "}", settings, project).replaceAll("class C \\{", "")
return result.substring(0, (result.lastIndexOf("}"))).trim()
}
private fun statementToKotlin(text: String, settings: ConverterSettings, project: Project): String {
val result = methodToKotlin("void main() {" + text + "}", settings, project)
return result.substring(0, result.lastIndexOf("}")).replaceFirst("fun main\\(\\) \\{", "").trim()
}
private fun expressionToKotlin(code: String, settings: ConverterSettings, project: Project): String {
val result = statementToKotlin("final Object o =" + code + "}", settings, project)
return result.replaceFirst("val o:Any\\? = ", "").replaceFirst("val o:Any = ", "").replaceFirst("val o = ", "").trim()
}
override fun getProjectDescriptor()
= JetWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
private fun String.removeFirstLine(): String {
val lastNewLine = indexOf('\n')
return if (lastNewLine == -1) "" else substring(lastNewLine)
}
private fun String.removeLastLine(): String {
val lastNewLine = lastIndexOf('\n')
return if (lastNewLine == -1) "" else substring(0, lastNewLine)
}
private fun createJavaFile(text: String): PsiJavaFile {
return myFixture.configureByText("converterTestFile.java", text) as PsiJavaFile
}
}
public abstract class AbstractJavaToKotlinConverterForWebDemoTest() : TestCase() {
@@ -0,0 +1,46 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* 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.
*/
package org.jetbrains.jet.j2k.test;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.jet.JUnit3RunnerWithInners;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.test.InnerTestClasses;
import org.jetbrains.jet.test.TestMetadata;
import org.junit.runner.RunWith;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("j2k/tests/testData/multiFile")
@TestDataPath("$PROJECT_ROOT")
@InnerTestClasses({})
@RunWith(JUnit3RunnerWithInners.class)
public class JavaToKotlinConverterMultiFileTestGenerated extends AbstractJavaToKotlinConverterMultiFileTest {
public void testAllFilesPresentInMultiFile() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("j2k/tests/testData/multiFile"), Pattern.compile("^([^\\.]+)$"), true);
}
@TestMetadata("GetterAndSetterUsages")
public void testGetterAndSetterUsages() throws Exception {
String fileName = JetTestUtils.navigationMetadata("j2k/tests/testData/multiFile/GetterAndSetterUsages/");
doTest(fileName);
}
}

Some files were not shown because too many files have changed in this diff Show More