diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetCodeFragmentImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetCodeFragmentImpl.java index d3932448996..51b9675e2c1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetCodeFragmentImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetCodeFragmentImpl.java @@ -19,13 +19,17 @@ package org.jetbrains.jet.lang.psi; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.impl.PsiManagerEx; +import com.intellij.psi.impl.file.impl.FileManager; +import com.intellij.psi.impl.source.tree.FileElement; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.tree.IElementType; import com.intellij.testFramework.LightVirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.plugin.JetFileType; -public class JetCodeFragmentImpl extends JetFile implements PsiCodeFragment { +public abstract class JetCodeFragmentImpl extends JetFile implements PsiCodeFragment { + private final Project project; + protected PsiElement context; private GlobalSearchScope resolveScope; @@ -34,6 +38,7 @@ public class JetCodeFragmentImpl extends JetFile implements PsiCodeFragment { new LightVirtualFile(name, JetFileType.INSTANCE, text), true), false); ((SingleRootFileViewProvider)getViewProvider()).forceCachedPsi(this); init(TokenType.CODE_FRAGMENT, elementType); + this.project = project; this.context = context; } @@ -68,4 +73,27 @@ public class JetCodeFragmentImpl extends JetFile implements PsiCodeFragment { if (resolveScope != null) return resolveScope; return super.getResolveScope(); } + + @Override + protected JetCodeFragmentImpl clone() { + JetCodeFragmentImpl clone = (JetCodeFragmentImpl)cloneImpl((FileElement)calcTreeElement().clone()); + clone.myOriginalFile = this; + FileManager fileManager = ((PsiManagerEx) PsiManager.getInstance(project)).getFileManager(); + SingleRootFileViewProvider cloneViewProvider = (SingleRootFileViewProvider)fileManager.createFileViewProvider(new LightVirtualFile( + getName(), + JetFileType.INSTANCE, + getText()), true); + cloneViewProvider.forceCachedPsi(clone); + clone.myViewProvider = cloneViewProvider; + return clone; + } + + private FileViewProvider myViewProvider = null; + + @Override + @NotNull + public FileViewProvider getViewProvider() { + if (myViewProvider != null) return myViewProvider; + return super.getViewProvider(); + } } diff --git a/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt index 93e323914a8..6ab9a049246 100644 --- a/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt +++ b/generators/src/org/jetbrains/jet/generators/tests/GenerateTests.kt @@ -107,6 +107,8 @@ import org.jetbrains.jet.completion.AbstractMultiFileJvmBasicCompletionTest import org.jetbrains.jet.plugin.refactoring.introduce.introduceVariable.AbstractJetExtractionTest import org.jetbrains.jet.plugin.debugger.evaluate.AbstractKotlinEvaluateExpressionTest import org.jetbrains.jet.plugin.debugger.evaluate.AbstractSelectExpressionForDebuggerTest +import org.jetbrains.jet.plugin.debugger.evaluate.AbstractCodeFragmentCompletionTest +import org.jetbrains.jet.plugin.debugger.evaluate.AbstractCodeFragmentHighlightingTest fun main(args: Array) { System.setProperty("java.awt.headless", "true") @@ -266,6 +268,10 @@ fun main(args: Array) { model("checker/infos", testMethod = "doTestWithInfos") } + testClass(javaClass()) { + model("checker/codeFragments", extension = "kt") + } + testClass(javaClass()) { model("checker/js") } @@ -308,6 +314,10 @@ fun main(args: Array) { model("completion/handlers/smart") } + testClass(javaClass()) { + model("completion/basic/codeFragments", extension = "kt") + } + testClass(javaClass()) { model("navigation/gotoSuper", extension = "test") } diff --git a/idea/src/org/jetbrains/jet/plugin/caches/resolve/KotlinResolveCache.kt b/idea/src/org/jetbrains/jet/plugin/caches/resolve/KotlinResolveCache.kt index 7814788f880..e321d05e746 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/resolve/KotlinResolveCache.kt +++ b/idea/src/org/jetbrains/jet/plugin/caches/resolve/KotlinResolveCache.kt @@ -50,6 +50,7 @@ import org.jetbrains.jet.plugin.project.ResolveSessionForBodies import org.jetbrains.jet.plugin.project.TargetPlatformDetector import java.util.HashSet import org.jetbrains.jet.analyzer.AnalyzerFacade +import org.jetbrains.jet.lang.psi.JetCodeFragmentImpl private val LOG = Logger.getInstance(javaClass()) @@ -158,7 +159,7 @@ class KotlinCacheService(val project: Project) { if (elements.isEmpty()) return AnalyzeExhaust.EMPTY val firstFile = elements.first().getContainingJetFile() - if (elements.size == 1 && !isFileInScope(firstFile)) { + if (elements.size == 1 && (!isFileInScope(firstFile) && firstFile !is JetCodeFragmentImpl)) { return getCacheForSyntheticFile(firstFile).getAnalysisResultsForElements(elements) } diff --git a/idea/src/org/jetbrains/jet/plugin/debugger/evaluate/KotlinCodeFragmentFactory.kt b/idea/src/org/jetbrains/jet/plugin/debugger/evaluate/KotlinCodeFragmentFactory.kt index d560aa99e2a..c2146ac0682 100644 --- a/idea/src/org/jetbrains/jet/plugin/debugger/evaluate/KotlinCodeFragmentFactory.kt +++ b/idea/src/org/jetbrains/jet/plugin/debugger/evaluate/KotlinCodeFragmentFactory.kt @@ -21,23 +21,19 @@ import com.intellij.debugger.engine.evaluation.TextWithImports import com.intellij.psi.PsiElement import com.intellij.openapi.project.Project import com.intellij.psi.JavaCodeFragment -import com.intellij.openapi.fileTypes.LanguageFileType -import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilder import org.jetbrains.jet.plugin.JetFileType -import org.jetbrains.jet.lang.psi.JetCodeFragmentImpl -import com.intellij.psi.tree.IElementType -import org.jetbrains.jet.lexer.JetToken -import org.jetbrains.jet.JetNodeType -import org.jetbrains.jet.lexer.JetTokens import org.jetbrains.jet.lang.psi.JetExpressionCodeFragmentImpl import com.intellij.psi.PsiCodeBlock import com.intellij.debugger.engine.evaluation.CodeFragmentKind import com.intellij.psi.JavaCodeFragmentFactory +import org.jetbrains.jet.plugin.debugger.KotlinEditorTextProvider +import com.intellij.psi.util.PsiTreeUtil +import org.jetbrains.jet.lang.psi.JetExpression class KotlinCodeFragmentFactory: CodeFragmentFactory() { override fun createCodeFragment(item: TextWithImports, context: PsiElement?, project: Project): JavaCodeFragment { if (item.getKind() == CodeFragmentKind.EXPRESSION) { - val codeFragment = JetExpressionCodeFragmentImpl(project, "fragment.kt", item.getText(), context) + val codeFragment = JetExpressionCodeFragmentImpl(project, "fragment.kt", item.getText(), getContextElement(context)) if (item.getImports().isNotEmpty()) { codeFragment.addImportsFromString(item.getImports()) } @@ -60,4 +56,16 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() { override fun getFileType() = JetFileType.INSTANCE override fun getEvaluatorBuilder() = KotlinEvaluationBuilder + + class object { + fun getContextElement(elementAt: PsiElement?): PsiElement? { + if (elementAt == null) return null + + val expressionAtOffset = PsiTreeUtil.findElementOfClassAtOffset(elementAt.getContainingFile()!!, elementAt.getTextOffset(), javaClass(), false) + if (expressionAtOffset != null) { + return expressionAtOffset + } + return KotlinEditorTextProvider.findExpressionInner(elementAt) + } + } } diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/DebugInfoAnnotator.java b/idea/src/org/jetbrains/jet/plugin/highlighter/DebugInfoAnnotator.java index 2e1d80bced7..c2f6200af45 100644 --- a/idea/src/org/jetbrains/jet/plugin/highlighter/DebugInfoAnnotator.java +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/DebugInfoAnnotator.java @@ -23,6 +23,7 @@ import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.checkers.DebugInfoUtil; +import org.jetbrains.jet.lang.psi.JetCodeFragmentImpl; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetReferenceExpression; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -46,7 +47,7 @@ public class DebugInfoAnnotator implements Annotator { return; } - if (element instanceof JetFile) { + if (element instanceof JetFile && !(element instanceof JetCodeFragmentImpl)) { JetFile file = (JetFile) element; try { BindingContext bindingContext = ResolvePackage.getAnalysisResults(file).getBindingContext(); diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/JetPsiChecker.java b/idea/src/org/jetbrains/jet/plugin/highlighter/JetPsiChecker.java index 2b1ec07d2e1..750a6bb13e1 100644 --- a/idea/src/org/jetbrains/jet/plugin/highlighter/JetPsiChecker.java +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/JetPsiChecker.java @@ -40,11 +40,14 @@ import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.diagnostics.Severity; import org.jetbrains.jet.lang.diagnostics.rendering.DefaultErrorMessages; +import org.jetbrains.jet.lang.psi.JetCodeFragmentImpl; +import org.jetbrains.jet.lang.psi.JetElement; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetReferenceExpression; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.plugin.JetPluginUtil; import org.jetbrains.jet.plugin.caches.resolve.ResolvePackage; +import org.jetbrains.jet.plugin.project.ResolveSessionForBodies; import org.jetbrains.jet.plugin.quickfix.JetIntentionActionsFactory; import org.jetbrains.jet.plugin.quickfix.QuickFixes; @@ -90,7 +93,8 @@ public class JetPsiChecker implements Annotator, HighlightRangeExtension { @Override public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) { - if (!JetPluginUtil.isInSource(element) || JetPluginUtil.isKtFileInGradleProjectInWrongFolder(element)) { + if (!(JetPluginUtil.isInSource(element) || element.getContainingFile() instanceof JetCodeFragmentImpl) + || JetPluginUtil.isKtFileInGradleProjectInWrongFolder(element)) { return; } @@ -100,19 +104,32 @@ public class JetPsiChecker implements Annotator, HighlightRangeExtension { JetFile file = (JetFile) element.getContainingFile(); - AnalyzeExhaust analyzeExhaust = ResolvePackage.getAnalysisResults(file); - if (analyzeExhaust.isError()) { - HighlighterPackage.updateHighlightingResult(file, true); + BindingContext bindingContext; + if (file instanceof JetCodeFragmentImpl) { + if (element instanceof JetElement) { + ResolveSessionForBodies resolveSession = ResolvePackage.getLazyResolveSession((JetElement) element); + bindingContext = resolveSession.resolveToElement((JetElement) element); + } + else { + return; + } + } + else { + AnalyzeExhaust analyzeExhaust = ResolvePackage.getAnalysisResults(file); + if (analyzeExhaust.isError()) { + HighlighterPackage.updateHighlightingResult(file, true); - throw new ProcessCanceledException(analyzeExhaust.getError()); + throw new ProcessCanceledException(analyzeExhaust.getError()); + } + + bindingContext = analyzeExhaust.getBindingContext(); } - BindingContext bindingContext = analyzeExhaust.getBindingContext(); for (HighlightingVisitor visitor : getAfterAnalysisVisitor(holder, bindingContext)) { element.accept(visitor); } - if (JetPluginUtil.isInSource(element, /* includeLibrarySources = */ false)) { + if (JetPluginUtil.isInSource(element, /* includeLibrarySources = */ false) || file instanceof JetCodeFragmentImpl) { ElementAnnotator elementAnnotator = new ElementAnnotator(element, holder); for (Diagnostic diagnostic : bindingContext.getDiagnostics().forElement(element)) { elementAnnotator.registerDiagnosticAnnotations(diagnostic); diff --git a/idea/src/org/jetbrains/jet/plugin/project/ResolveElementCache.java b/idea/src/org/jetbrains/jet/plugin/project/ResolveElementCache.java index ad688cbc8a7..444e82691e1 100644 --- a/idea/src/org/jetbrains/jet/plugin/project/ResolveElementCache.java +++ b/idea/src/org/jetbrains/jet/plugin/project/ResolveElementCache.java @@ -27,6 +27,7 @@ import kotlin.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.di.InjectorForBodyResolve; +import org.jetbrains.jet.di.InjectorForMacros; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.Annotated; import org.jetbrains.jet.lang.psi.*; @@ -39,6 +40,7 @@ import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.TypeConstructor; +import org.jetbrains.jet.lang.types.TypeUtils; import org.jetbrains.jet.storage.ExceptionTracker; import org.jetbrains.jet.storage.LazyResolveStorageManager; import org.jetbrains.jet.storage.MemoizedFunctionToNotNull; @@ -92,7 +94,8 @@ public class ResolveElementCache { JetAnnotationEntry.class, JetTypeParameter.class, JetTypeConstraint.class, - JetPackageDirective.class); + JetPackageDirective.class, + JetExpressionCodeFragment.class); if (elementOfAdditionalResolve != null && !(elementOfAdditionalResolve instanceof JetParameter)) { if (elementOfAdditionalResolve instanceof JetPackageDirective) { @@ -159,6 +162,9 @@ public class ResolveElementCache { else if (resolveElement instanceof JetTypeConstraint) { typeConstraintAdditionalResolve(resolveSession, (JetTypeConstraint) resolveElement); } + else if (resolveElement instanceof JetExpressionCodeFragment) { + codeFragmentAdditionalResolve(resolveSession, (JetExpressionCodeFragment) resolveElement, trace); + } else if (PsiTreeUtil.getParentOfType(resolveElement, JetPackageDirective.class) != null) { packageRefAdditionalResolve(resolveSession, trace, resolveElement); } @@ -206,6 +212,34 @@ public class ResolveElementCache { } } + private void codeFragmentAdditionalResolve( + ResolveSession resolveSession, + JetExpressionCodeFragment codeFragment, + BindingTrace trace + ) { + JetExpression codeFragmentExpression = codeFragment.getExpression(); + if (codeFragmentExpression == null) return; + + PsiElement contextElement = codeFragment.getContext(); + if (!(contextElement instanceof JetExpression)) return; + + JetExpression contextExpression = (JetExpression) contextElement; + BindingContext contextForElement = resolveToElement(contextExpression); + + JetScope scopeForContextElement = contextForElement.get(BindingContext.RESOLUTION_SCOPE, contextExpression); + if (scopeForContextElement != null) { + DataFlowInfo dataFlowInfoForContextElement = contextForElement.get(BindingContext.EXPRESSION_DATA_FLOW_INFO, contextExpression); + InjectorForMacros injectorForMacros = new InjectorForMacros(codeFragment.getProject(), resolveSession.getModuleDescriptor()); + injectorForMacros.getExpressionTypingServices().getType( + scopeForContextElement, + codeFragmentExpression, + TypeUtils.NO_EXPECTED_TYPE, + dataFlowInfoForContextElement == null ? DataFlowInfo.EMPTY : dataFlowInfoForContextElement, + trace + ); + } + } + private static void annotationAdditionalResolve(ResolveSession resolveSession, JetAnnotationEntry jetAnnotationEntry) { JetDeclaration declaration = PsiTreeUtil.getParentOfType(jetAnnotationEntry, JetDeclaration.class); if (declaration != null) { diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportInsertHelper.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportInsertHelper.java index a05165158f1..fca746323d6 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportInsertHelper.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportInsertHelper.java @@ -96,6 +96,10 @@ public class ImportInsertHelper { } public static void writeImportToFile(@NotNull ImportPath importPath, @NotNull JetFile file) { + if (file instanceof JetCodeFragmentImpl) { + // TODO Insert import doesn't work for codeFragments yet + return; + } JetImportList importList = file.getImportList(); if (importList != null) { JetImportDirective newDirective = JetPsiFactory.createImportDirective(file.getProject(), importPath); diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/JetSingleIntentionActionFactory.java b/idea/src/org/jetbrains/jet/plugin/quickfix/JetSingleIntentionActionFactory.java index 1ecbd890a63..8736ed05c56 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/JetSingleIntentionActionFactory.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/JetSingleIntentionActionFactory.java @@ -20,6 +20,7 @@ import com.intellij.codeInsight.intention.IntentionAction; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.diagnostics.Diagnostic; +import org.jetbrains.jet.lang.psi.JetCodeFragmentImpl; import java.util.LinkedList; import java.util.List; @@ -33,6 +34,11 @@ public abstract class JetSingleIntentionActionFactory implements JetIntentionAct @Override public final List createActions(Diagnostic diagnostic) { List intentionActionList = new LinkedList(); + + if (diagnostic.getPsiElement().getContainingFile() instanceof JetCodeFragmentImpl) { + return intentionActionList; + } + IntentionAction intentionAction = createAction(diagnostic); if (intentionAction != null) { intentionActionList.add(intentionAction); diff --git a/idea/testData/checker/codeFragments/binaryExpression.kt b/idea/testData/checker/codeFragments/binaryExpression.kt new file mode 100644 index 00000000000..05708572399 --- /dev/null +++ b/idea/testData/checker/codeFragments/binaryExpression.kt @@ -0,0 +1,4 @@ +fun foo() { + val a = 1 + a +} \ No newline at end of file diff --git a/idea/testData/checker/codeFragments/binaryExpression.kt.fragment b/idea/testData/checker/codeFragments/binaryExpression.kt.fragment new file mode 100644 index 00000000000..7ebcef59f0c --- /dev/null +++ b/idea/testData/checker/codeFragments/binaryExpression.kt.fragment @@ -0,0 +1 @@ +a + b \ No newline at end of file diff --git a/idea/testData/checker/codeFragments/callExpression.kt b/idea/testData/checker/codeFragments/callExpression.kt new file mode 100644 index 00000000000..eb3c98fcb6f --- /dev/null +++ b/idea/testData/checker/codeFragments/callExpression.kt @@ -0,0 +1,4 @@ +fun foo(i: Int, s: String) { + val a = 1 + a +} \ No newline at end of file diff --git a/idea/testData/checker/codeFragments/callExpression.kt.fragment b/idea/testData/checker/codeFragments/callExpression.kt.fragment new file mode 100644 index 00000000000..5b90d643e0d --- /dev/null +++ b/idea/testData/checker/codeFragments/callExpression.kt.fragment @@ -0,0 +1 @@ +foo(a, 1) \ No newline at end of file diff --git a/idea/testData/checker/codeFragments/contextElementAsStatement.kt b/idea/testData/checker/codeFragments/contextElementAsStatement.kt new file mode 100644 index 00000000000..642771b5bbc --- /dev/null +++ b/idea/testData/checker/codeFragments/contextElementAsStatement.kt @@ -0,0 +1,4 @@ +fun foo() { + val a = 1 + val b = 2 +} \ No newline at end of file diff --git a/idea/testData/checker/codeFragments/contextElementAsStatement.kt.fragment b/idea/testData/checker/codeFragments/contextElementAsStatement.kt.fragment new file mode 100644 index 00000000000..1ae28016a70 --- /dev/null +++ b/idea/testData/checker/codeFragments/contextElementAsStatement.kt.fragment @@ -0,0 +1 @@ +a + c \ No newline at end of file diff --git a/idea/testData/checker/codeFragments/simpleNameExpression.kt b/idea/testData/checker/codeFragments/simpleNameExpression.kt new file mode 100644 index 00000000000..05708572399 --- /dev/null +++ b/idea/testData/checker/codeFragments/simpleNameExpression.kt @@ -0,0 +1,4 @@ +fun foo() { + val a = 1 + a +} \ No newline at end of file diff --git a/idea/testData/checker/codeFragments/simpleNameExpression.kt.fragment b/idea/testData/checker/codeFragments/simpleNameExpression.kt.fragment new file mode 100644 index 00000000000..67f4efdaa0f --- /dev/null +++ b/idea/testData/checker/codeFragments/simpleNameExpression.kt.fragment @@ -0,0 +1 @@ +b \ No newline at end of file diff --git a/idea/testData/checker/codeFragments/smartCasts.kt b/idea/testData/checker/codeFragments/smartCasts.kt new file mode 100644 index 00000000000..c8f7f84b6ab --- /dev/null +++ b/idea/testData/checker/codeFragments/smartCasts.kt @@ -0,0 +1,6 @@ +fun foo() { + val a: Int? = 1 + if (a != null) { + a + } +} \ No newline at end of file diff --git a/idea/testData/checker/codeFragments/smartCasts.kt.fragment b/idea/testData/checker/codeFragments/smartCasts.kt.fragment new file mode 100644 index 00000000000..4e43f3bd05e --- /dev/null +++ b/idea/testData/checker/codeFragments/smartCasts.kt.fragment @@ -0,0 +1 @@ +a + 1 \ No newline at end of file diff --git a/idea/testData/completion/basic/codeFragments/localVal.kt b/idea/testData/completion/basic/codeFragments/localVal.kt new file mode 100644 index 00000000000..cb7d4f800ab --- /dev/null +++ b/idea/testData/completion/basic/codeFragments/localVal.kt @@ -0,0 +1,7 @@ +fun foo() { + val aaabbbccc = 1 + aaabbbccc +} + +// INVOCATION_COUNT: 1 +// EXIST: aaabbbccc \ No newline at end of file diff --git a/idea/testData/completion/basic/codeFragments/localVal.kt.fragment b/idea/testData/completion/basic/codeFragments/localVal.kt.fragment new file mode 100644 index 00000000000..0c3168bfd9b --- /dev/null +++ b/idea/testData/completion/basic/codeFragments/localVal.kt.fragment @@ -0,0 +1 @@ +aaabb \ No newline at end of file diff --git a/idea/testData/completion/basic/codeFragments/topLevel.kt b/idea/testData/completion/basic/codeFragments/topLevel.kt new file mode 100644 index 00000000000..49978e4843e --- /dev/null +++ b/idea/testData/completion/basic/codeFragments/topLevel.kt @@ -0,0 +1,8 @@ +val aaabbbccc = 1 + +fun foo() { + aaabbbccc +} + +// INVOCATION_COUNT: 1 +// EXIST: aaabbbccc \ No newline at end of file diff --git a/idea/testData/completion/basic/codeFragments/topLevel.kt.fragment b/idea/testData/completion/basic/codeFragments/topLevel.kt.fragment new file mode 100644 index 00000000000..0c3168bfd9b --- /dev/null +++ b/idea/testData/completion/basic/codeFragments/topLevel.kt.fragment @@ -0,0 +1 @@ +aaabb \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/completion/AbstractKotlinSourceInJavaCompletionTest.java b/idea/tests/org/jetbrains/jet/completion/AbstractKotlinSourceInJavaCompletionTest.java index 4056609d02e..93b537d2e95 100644 --- a/idea/tests/org/jetbrains/jet/completion/AbstractKotlinSourceInJavaCompletionTest.java +++ b/idea/tests/org/jetbrains/jet/completion/AbstractKotlinSourceInJavaCompletionTest.java @@ -18,7 +18,7 @@ public abstract class AbstractKotlinSourceInJavaCompletionTest extends JetFixtur } @Override - public void doTest(String testPath) { + public void doTest(String testPath) throws Exception { File mockLibDir = new File(PluginTestCaseBase.getTestDataPathBase() + "/completion/injava/mockLib"); File[] listFiles = mockLibDir.listFiles(); assertNotNull(listFiles); diff --git a/idea/tests/org/jetbrains/jet/completion/JetFixtureCompletionBaseTestCase.java b/idea/tests/org/jetbrains/jet/completion/JetFixtureCompletionBaseTestCase.java index 538a55d3306..63d15aba526 100644 --- a/idea/tests/org/jetbrains/jet/completion/JetFixtureCompletionBaseTestCase.java +++ b/idea/tests/org/jetbrains/jet/completion/JetFixtureCompletionBaseTestCase.java @@ -19,10 +19,12 @@ package org.jetbrains.jet.completion; import com.intellij.codeInsight.CodeInsightSettings; import com.intellij.codeInsight.completion.CompletionType; import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.plugin.project.TargetPlatform; +import java.io.File; import java.util.Collections; import java.util.List; @@ -62,10 +64,10 @@ public abstract class JetFixtureCompletionBaseTestCase extends LightCodeInsightF @NotNull protected abstract CompletionType completionType(); - public void doTest(String testPath) { + public void doTest(String testPath) throws Exception { setUpFixture(testPath); - String fileText = myFixture.getFile().getText(); + String fileText = FileUtil.loadFile(new File(testPath), true); Integer invocationCount = ExpectedCompletionUtils.getInvocationCount(fileText); diff --git a/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/AbstractEditorForEvaluateExpressionTest.kt b/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/AbstractEditorForEvaluateExpressionTest.kt new file mode 100644 index 00000000000..c0639c15254 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/AbstractEditorForEvaluateExpressionTest.kt @@ -0,0 +1,59 @@ +/* + * 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.plugin.debugger.evaluate + +import org.jetbrains.jet.checkers.AbstractJetPsiCheckerTest +import org.jetbrains.jet.completion.AbstractJvmBasicCompletionTest +import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture +import com.intellij.psi.PsiElement +import org.jetbrains.jet.lang.psi.JetExpressionCodeFragment +import com.intellij.openapi.util.io.FileUtil +import java.io.File +import org.jetbrains.jet.lang.psi.JetPsiFactory +import org.jetbrains.jet.plugin.debugger.KotlinEditorTextProvider +import com.intellij.openapi.util.text.StringUtil + +abstract class AbstractCodeFragmentHighlightingTest: AbstractJetPsiCheckerTest() { + override fun doTest(filePath: String) { + myFixture.configureByCodeFragment(filePath) + myFixture.checkHighlighting(true, false, false) + } +} + +abstract class AbstractCodeFragmentCompletionTest : AbstractJvmBasicCompletionTest() { + override fun setUpFixture(testPath: String) { + myFixture.configureByCodeFragment(testPath) + } +} + +private fun JavaCodeInsightTestFixture.configureByCodeFragment(filePath: String) { + configureByFile(filePath) + + val elementAt = getFile()?.findElementAt(getCaretOffset()) + val file = createExpressionCodeFragment(filePath, elementAt!!) + + configureFromExistingVirtualFile(file.getVirtualFile()) +} + +private fun createExpressionCodeFragment(filePath: String, contextElement: PsiElement): JetExpressionCodeFragment { + val codeFragmentText = FileUtil.loadFile(File(filePath + ".fragment"), true).trim() + return JetPsiFactory.createExpressionCodeFragment( + contextElement.getProject(), + codeFragmentText, + KotlinCodeFragmentFactory.getContextElement(contextElement) + ) +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/CodeFragmentCompletionTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/CodeFragmentCompletionTestGenerated.java new file mode 100644 index 00000000000..bfbaa811529 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/CodeFragmentCompletionTestGenerated.java @@ -0,0 +1,49 @@ +/* + * 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.plugin.debugger.evaluate; + +import junit.framework.Assert; +import junit.framework.Test; +import junit.framework.TestSuite; + +import java.io.File; +import java.util.regex.Pattern; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.test.InnerTestClasses; +import org.jetbrains.jet.test.TestMetadata; + +import org.jetbrains.jet.plugin.debugger.evaluate.AbstractCodeFragmentCompletionTest; + +/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("idea/testData/completion/basic/codeFragments") +public class CodeFragmentCompletionTestGenerated extends AbstractCodeFragmentCompletionTest { + public void testAllFilesPresentInCodeFragments() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/completion/basic/codeFragments"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("localVal.kt") + public void testLocalVal() throws Exception { + doTest("idea/testData/completion/basic/codeFragments/localVal.kt"); + } + + @TestMetadata("topLevel.kt") + public void testTopLevel() throws Exception { + doTest("idea/testData/completion/basic/codeFragments/topLevel.kt"); + } + +} diff --git a/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/CodeFragmentHighlightingTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/CodeFragmentHighlightingTestGenerated.java new file mode 100644 index 00000000000..f551226bfb6 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/debugger/evaluate/CodeFragmentHighlightingTestGenerated.java @@ -0,0 +1,64 @@ +/* + * 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.plugin.debugger.evaluate; + +import junit.framework.Assert; +import junit.framework.Test; +import junit.framework.TestSuite; + +import java.io.File; +import java.util.regex.Pattern; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.test.InnerTestClasses; +import org.jetbrains.jet.test.TestMetadata; + +import org.jetbrains.jet.plugin.debugger.evaluate.AbstractCodeFragmentHighlightingTest; + +/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("idea/testData/checker/codeFragments") +public class CodeFragmentHighlightingTestGenerated extends AbstractCodeFragmentHighlightingTest { + public void testAllFilesPresentInCodeFragments() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/checker/codeFragments"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("binaryExpression.kt") + public void testBinaryExpression() throws Exception { + doTest("idea/testData/checker/codeFragments/binaryExpression.kt"); + } + + @TestMetadata("callExpression.kt") + public void testCallExpression() throws Exception { + doTest("idea/testData/checker/codeFragments/callExpression.kt"); + } + + @TestMetadata("contextElementAsStatement.kt") + public void testContextElementAsStatement() throws Exception { + doTest("idea/testData/checker/codeFragments/contextElementAsStatement.kt"); + } + + @TestMetadata("simpleNameExpression.kt") + public void testSimpleNameExpression() throws Exception { + doTest("idea/testData/checker/codeFragments/simpleNameExpression.kt"); + } + + @TestMetadata("smartCasts.kt") + public void testSmartCasts() throws Exception { + doTest("idea/testData/checker/codeFragments/smartCasts.kt"); + } + +}