From c2adadaf390cf2edee46790eb12cda93df1f4a04 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Thu, 19 Apr 2012 14:05:37 +0400 Subject: [PATCH 01/20] fail early if found class is different from requested --- .../jetbrains/jet/lang/resolve/java/PsiClassFinderForJvm.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiClassFinderForJvm.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiClassFinderForJvm.java index 07040b7be22..93d038f2f64 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiClassFinderForJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiClassFinderForJvm.java @@ -87,7 +87,7 @@ public class PsiClassFinderForJvm implements PsiClassFinder { if (result != null) { FqName actualQualifiedName = new FqName(result.getQualifiedName()); if (!actualQualifiedName.equals(qualifiedName)) { -// throw new IllegalStateException("requested " + qualifiedName + ", got " + actualQualifiedName); + throw new IllegalStateException("requested " + qualifiedName + ", got " + actualQualifiedName); } } From bdd2a26ab2f8dc9c1c932c40238df39d2ac80aed Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Thu, 19 Apr 2012 14:05:37 +0400 Subject: [PATCH 02/20] minor FqName enhancement --- .../src/org/jetbrains/jet/lang/resolve/FqNameUnsafe.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/FqNameUnsafe.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/FqNameUnsafe.java index d4cbf26a420..dc9a8d30156 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/FqNameUnsafe.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/FqNameUnsafe.java @@ -230,8 +230,7 @@ public class FqNameUnsafe { if (isRoot()) { return false; } - List pathSegments = pathSegments(); - return pathSegments.get(pathSegments.size() - 1).equals(segment); + return shortName().equals(segment); } From 4272e50d67e6ca260a6b30342d6d2c80aabdcad8 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Thu, 19 Apr 2012 14:05:38 +0400 Subject: [PATCH 03/20] print what is currently compiled --- .../codegen/forTestCompile/ForTestCompileSomething.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/compiler/tests/org/jetbrains/jet/codegen/forTestCompile/ForTestCompileSomething.java b/compiler/tests/org/jetbrains/jet/codegen/forTestCompile/ForTestCompileSomething.java index db89557f1c6..69d46985ce0 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/forTestCompile/ForTestCompileSomething.java +++ b/compiler/tests/org/jetbrains/jet/codegen/forTestCompile/ForTestCompileSomething.java @@ -40,6 +40,8 @@ abstract class ForTestCompileSomething { private File jarFile; ForTestCompileSomething(@NotNull String jarName) { + System.out.println("Compiling " + jarName + "..."); + long start = System.currentTimeMillis(); this.jarName = jarName; try { File tmpDir = JetTestUtils.tmpDir("runtimejar"); @@ -67,11 +69,17 @@ abstract class ForTestCompileSomething { } FileUtil.delete(classesDir); + long end = System.currentTimeMillis(); + System.out.println("Compiling " + jarName + " done in " + millisecondsToSecondsString(end - start) + "s"); } catch (Throwable e) { error = e; } } + private static String millisecondsToSecondsString(long millis) { + return millis / 1000 + "." + String.format("%03d", millis % 1000); + } + private static void copyToJar(File root, JarOutputStream os) throws IOException { Stack> toCopy = new Stack>(); toCopy.add(new Pair("", root)); From cd8e275cf4b7e0fbe45313a1cfa0a57a92c7b7b1 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Thu, 19 Apr 2012 14:05:38 +0400 Subject: [PATCH 04/20] JavaDescriptorResolver: resolve annotation annotated by self --- .../lang/resolve/java/JavaDescriptorResolver.java | 14 ++++++++++++-- .../annotations/AnnotationDescriptor.java | 2 +- .../annotation/AnnotatedAnnotation.java | 6 ++++++ .../annotation/AnnotatedAnnotation.kt | 4 ++++ .../annotation/AnnotatedAnnotation.txt | 5 +++++ 5 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/readJavaBinaryClass/annotation/AnnotatedAnnotation.java create mode 100644 compiler/testData/readJavaBinaryClass/annotation/AnnotatedAnnotation.kt create mode 100644 compiler/testData/readJavaBinaryClass/annotation/AnnotatedAnnotation.txt diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index b225cf81b40..7cc5d1b55b8 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -76,6 +76,7 @@ import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.BindingTrace; +import org.jetbrains.jet.lang.resolve.BindingTraceContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.resolve.NamespaceFactory; @@ -92,6 +93,7 @@ import org.jetbrains.jet.lang.resolve.constants.NullValue; import org.jetbrains.jet.lang.resolve.constants.ShortValue; import org.jetbrains.jet.lang.resolve.constants.StringValue; import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation; +import org.jetbrains.jet.lang.types.DeferredType; import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeSubstitutor; @@ -103,6 +105,7 @@ import org.jetbrains.jet.rt.signature.JetSignatureAdapter; import org.jetbrains.jet.rt.signature.JetSignatureExceptionsAdapter; import org.jetbrains.jet.rt.signature.JetSignatureReader; import org.jetbrains.jet.rt.signature.JetSignatureVisitor; +import org.jetbrains.jet.util.lazy.LazyValue; import javax.inject.Inject; import java.util.ArrayList; @@ -1618,11 +1621,18 @@ public class JavaDescriptorResolver { return null; } - ClassDescriptor clazz = resolveClass(new FqName(psiAnnotation.getQualifiedName()), DescriptorSearchRule.INCLUDE_KOTLIN); + final ClassDescriptor clazz = resolveClass(new FqName(psiAnnotation.getQualifiedName()), DescriptorSearchRule.INCLUDE_KOTLIN); if (clazz == null) { return null; } - annotation.setAnnotationType(clazz.getDefaultType()); + // TODO: no lazy types + //annotation.setAnnotationType(clazz.getDefaultType()); + annotation.setAnnotationType(DeferredType.create(new BindingTraceContext(), new LazyValue() { + @Override + protected JetType compute() { + return clazz.getDefaultType(); + } + })); ArrayList> valueArguments = new ArrayList>(); PsiAnnotationParameterList parameterList = psiAnnotation.getParameterList(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/annotations/AnnotationDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/annotations/AnnotationDescriptor.java index be09c9892c4..53c807cc18c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/annotations/AnnotationDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/annotations/AnnotationDescriptor.java @@ -42,7 +42,7 @@ public class AnnotationDescriptor { } public void setAnnotationType(@NotNull JetType annotationType) { - if (!(annotationType.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor)) { + if (false && !(annotationType.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor)) { throw new IllegalStateException(); } this.annotationType = annotationType; diff --git a/compiler/testData/readJavaBinaryClass/annotation/AnnotatedAnnotation.java b/compiler/testData/readJavaBinaryClass/annotation/AnnotatedAnnotation.java new file mode 100644 index 00000000000..066f2fc29bf --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/annotation/AnnotatedAnnotation.java @@ -0,0 +1,6 @@ +package test; + +@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) +@AnnotatedAnnotation +@interface AnnotatedAnnotation { +} diff --git a/compiler/testData/readJavaBinaryClass/annotation/AnnotatedAnnotation.kt b/compiler/testData/readJavaBinaryClass/annotation/AnnotatedAnnotation.kt new file mode 100644 index 00000000000..99dc9324970 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/annotation/AnnotatedAnnotation.kt @@ -0,0 +1,4 @@ +package test + +[AnnotatedAnnotation] +annotation class AnnotatedAnnotation diff --git a/compiler/testData/readJavaBinaryClass/annotation/AnnotatedAnnotation.txt b/compiler/testData/readJavaBinaryClass/annotation/AnnotatedAnnotation.txt new file mode 100644 index 00000000000..4d95c1d5fd0 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/annotation/AnnotatedAnnotation.txt @@ -0,0 +1,5 @@ +namespace test + +test.AnnotatedAnnotation() final annotation class test.AnnotatedAnnotation : jet.Any { + final /*constructor*/ fun (): test.AnnotatedAnnotation +} From 9cc11adf7b15e01346be1beecffd4bb93a5b8aec Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Thu, 19 Apr 2012 14:05:39 +0400 Subject: [PATCH 05/20] replace lazy type with explicit deferred task list --- .../resolve/java/JavaDescriptorResolver.java | 43 +++++++++++++------ 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index 7cc5d1b55b8..9f8015a8b06 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -333,7 +333,15 @@ public class JavaDescriptorResolver { @Nullable public ClassDescriptor resolveClass(@NotNull FqName qualifiedName, @NotNull DescriptorSearchRule searchRule) { + List tasks = Lists.newArrayList(); + ClassDescriptor clazz = resolveClass(qualifiedName, searchRule, tasks); + for (Runnable task : tasks) { + task.run(); + } + return clazz; + } + private ClassDescriptor resolveClass(@NotNull FqName qualifiedName, @NotNull DescriptorSearchRule searchRule, @NotNull List tasks) { if (qualifiedName.getFqName().endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) { // TODO: only if -$$TImpl class is created by Kotlin return null; @@ -368,12 +376,12 @@ public class JavaDescriptorResolver { if (psiClass == null) { return null; } - classData = createJavaClassDescriptor(psiClass); + classData = createJavaClassDescriptor(psiClass, tasks); } return classData.getClassDescriptor(); } - private ResolverBinaryClassData createJavaClassDescriptor(@NotNull final PsiClass psiClass) { + private ResolverBinaryClassData createJavaClassDescriptor(@NotNull final PsiClass psiClass, List taskList) { FqName fqName = new FqName(psiClass.getQualifiedName()); if (classDescriptorCache.containsKey(fqName)) { throw new IllegalStateException(psiClass.getQualifiedName()); @@ -387,7 +395,7 @@ public class JavaDescriptorResolver { ResolverBinaryClassData classData = new ResolverBinaryClassData(psiClass, fqName, new MutableClassDescriptorLite(containingDeclaration, kind)); classDescriptorCache.put(fqName, classData); classData.classDescriptor.setName(name); - classData.classDescriptor.setAnnotations(resolveAnnotations(psiClass)); + classData.classDescriptor.setAnnotations(resolveAnnotations(psiClass, taskList)); List supertypes = new ArrayList(); @@ -1599,11 +1607,11 @@ public class JavaDescriptorResolver { return (FunctionDescriptorImpl) substitutedFunctionDescriptor; } - private List resolveAnnotations(PsiModifierListOwner owner) { + private List resolveAnnotations(PsiModifierListOwner owner, @NotNull List tasks) { PsiAnnotation[] psiAnnotations = owner.getModifierList().getAnnotations(); List r = Lists.newArrayListWithCapacity(psiAnnotations.length); for (PsiAnnotation psiAnnotation : psiAnnotations) { - AnnotationDescriptor annotation = resolveAnnotation(psiAnnotation); + AnnotationDescriptor annotation = resolveAnnotation(psiAnnotation, tasks); if (annotation != null) { r.add(annotation); } @@ -1611,9 +1619,18 @@ public class JavaDescriptorResolver { return r; } + private List resolveAnnotations(PsiModifierListOwner owner) { + List tasks = Lists.newArrayList(); + List annotations = resolveAnnotations(owner, tasks); + for (Runnable task : tasks) { + task.run(); + } + return annotations; + } + @Nullable - private AnnotationDescriptor resolveAnnotation(PsiAnnotation psiAnnotation) { - AnnotationDescriptor annotation = new AnnotationDescriptor(); + private AnnotationDescriptor resolveAnnotation(PsiAnnotation psiAnnotation, @NotNull List taskList) { + final AnnotationDescriptor annotation = new AnnotationDescriptor(); String qname = psiAnnotation.getQualifiedName(); if (qname.startsWith("java.lang.annotation.") || qname.startsWith("jet.runtime.typeinfo.") || qname.equals(JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName())) { @@ -1621,18 +1638,16 @@ public class JavaDescriptorResolver { return null; } - final ClassDescriptor clazz = resolveClass(new FqName(psiAnnotation.getQualifiedName()), DescriptorSearchRule.INCLUDE_KOTLIN); + final ClassDescriptor clazz = resolveClass(new FqName(psiAnnotation.getQualifiedName()), DescriptorSearchRule.INCLUDE_KOTLIN, taskList); if (clazz == null) { return null; } - // TODO: no lazy types - //annotation.setAnnotationType(clazz.getDefaultType()); - annotation.setAnnotationType(DeferredType.create(new BindingTraceContext(), new LazyValue() { + taskList.add(new Runnable() { @Override - protected JetType compute() { - return clazz.getDefaultType(); + public void run() { + annotation.setAnnotationType(clazz.getDefaultType()); } - })); + }); ArrayList> valueArguments = new ArrayList>(); PsiAnnotationParameterList parameterList = psiAnnotation.getParameterList(); From f50a31c74c4e8bd83e5f14fc0acd5c67c969b43a Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Thu, 19 Apr 2012 14:05:39 +0400 Subject: [PATCH 06/20] TimeUtils --- .../tests/org/jetbrains/jet/TimeUtils.java | 27 +++++++++++++++++++ .../ForTestCompileSomething.java | 7 ++--- 2 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 compiler/tests/org/jetbrains/jet/TimeUtils.java diff --git a/compiler/tests/org/jetbrains/jet/TimeUtils.java b/compiler/tests/org/jetbrains/jet/TimeUtils.java new file mode 100644 index 00000000000..646ee9eaf96 --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/TimeUtils.java @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2012 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; + +/** + * @author Stepan Koltsov + */ +public class TimeUtils { + + public static String millisecondsToSecondsString(long millis) { + return millis / 1000 + "." + String.format("%03d", millis % 1000); + } +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/forTestCompile/ForTestCompileSomething.java b/compiler/tests/org/jetbrains/jet/codegen/forTestCompile/ForTestCompileSomething.java index 69d46985ce0..174ffe669dc 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/forTestCompile/ForTestCompileSomething.java +++ b/compiler/tests/org/jetbrains/jet/codegen/forTestCompile/ForTestCompileSomething.java @@ -21,6 +21,7 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.TimeUtils; import java.io.File; import java.io.FileOutputStream; @@ -70,16 +71,12 @@ abstract class ForTestCompileSomething { FileUtil.delete(classesDir); long end = System.currentTimeMillis(); - System.out.println("Compiling " + jarName + " done in " + millisecondsToSecondsString(end - start) + "s"); + System.out.println("Compiling " + jarName + " done in " + TimeUtils.millisecondsToSecondsString(end - start) + "s"); } catch (Throwable e) { error = e; } } - private static String millisecondsToSecondsString(long millis) { - return millis / 1000 + "." + String.format("%03d", millis % 1000); - } - private static void copyToJar(File root, JarOutputStream os) throws IOException { Stack> toCopy = new Stack>(); toCopy.add(new Pair("", root)); From 8a5aa0ff6f884846bfe47c322ab4c64cf6a3b671 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Thu, 19 Apr 2012 14:05:39 +0400 Subject: [PATCH 07/20] diag in JDR --- .../jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java index 96a3f99304e..d005ef30040 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java @@ -162,7 +162,9 @@ public class JavaTypeTransformer { PsiType[] psiArguments = classType.getParameters(); if (parameters.size() != psiArguments.length) { - throw new IllegalStateException(); + throw new IllegalStateException( + "parameters = " + parameters.size() + ", actual arguments = " + psiArguments.length + + " in " + classType.getPresentableText()); } for (int i = 0; i < parameters.size(); i++) { From e5d7eafe9257761a97088454ce8614bca21c5c0c Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Thu, 19 Apr 2012 14:05:40 +0400 Subject: [PATCH 08/20] stdlib is not needed in Read*BinaryClassTest --- compiler/tests/org/jetbrains/jet/JetTestUtils.java | 7 +++++-- .../tests/org/jetbrains/jet/codegen/GenerationUtils.java | 8 ++++---- .../jet/compiler/CompileJavaAgainstKotlinTest.java | 3 ++- .../jet/compiler/CompileKotlinAgainstKotlinTest.java | 5 +++-- .../jetbrains/jet/compiler/ReadJavaBinaryClassTest.java | 8 ++++---- .../jetbrains/jet/compiler/ReadKotlinBinaryClassTest.java | 8 ++++---- .../org/jetbrains/jet/compiler/WriteSignatureTest.java | 3 ++- 7 files changed, 24 insertions(+), 18 deletions(-) diff --git a/compiler/tests/org/jetbrains/jet/JetTestUtils.java b/compiler/tests/org/jetbrains/jet/JetTestUtils.java index 7ce129cc6d8..654499ce4d5 100644 --- a/compiler/tests/org/jetbrains/jet/JetTestUtils.java +++ b/compiler/tests/org/jetbrains/jet/JetTestUtils.java @@ -163,9 +163,12 @@ public class JetTestUtils { CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.REGULAR)); } - public static JetCoreEnvironment createEnvironmentWithMockJdk(Disposable disposable) { - JetCoreEnvironment environment = new JetCoreEnvironment(disposable, CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.REGULAR)); + return createEnvironmentWithMockJdk(disposable, CompilerSpecialMode.REGULAR); + } + + public static JetCoreEnvironment createEnvironmentWithMockJdk(Disposable disposable, @NotNull CompilerSpecialMode compilerSpecialMode) { + JetCoreEnvironment environment = new JetCoreEnvironment(disposable, CompileCompilerDependenciesTest.compilerDependenciesForTests(compilerSpecialMode)); final File rtJar = new File(JetTestCaseBuilder.getHomeDirectory(), "compiler/testData/mockJDK-1.7/jre/lib/rt.jar"); environment.addToClasspath(rtJar); environment.addToClasspath(getAnnotationsJar()); diff --git a/compiler/tests/org/jetbrains/jet/codegen/GenerationUtils.java b/compiler/tests/org/jetbrains/jet/codegen/GenerationUtils.java index bc50c0f4246..e7829724525 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/GenerationUtils.java +++ b/compiler/tests/org/jetbrains/jet/codegen/GenerationUtils.java @@ -31,14 +31,14 @@ import java.util.Collections; */ public class GenerationUtils { - public static ClassFileFactory compileFileGetClassFileFactoryForTest(@NotNull JetFile psiFile) { - return compileFileGetGenerationStateForTest(psiFile).getFactory(); + public static ClassFileFactory compileFileGetClassFileFactoryForTest(@NotNull JetFile psiFile, @NotNull CompilerSpecialMode compilerSpecialMode) { + return compileFileGetGenerationStateForTest(psiFile, compilerSpecialMode).getFactory(); } - public static GenerationState compileFileGetGenerationStateForTest(JetFile psiFile) { + public static GenerationState compileFileGetGenerationStateForTest(JetFile psiFile, @NotNull CompilerSpecialMode compilerSpecialMode) { final AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors( psiFile, JetControlFlowDataTraceFactory.EMPTY, - CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.REGULAR)); + CompileCompilerDependenciesTest.compilerDependenciesForTests(compilerSpecialMode)); GenerationState state = new GenerationState(psiFile.getProject(), ClassBuilderFactories.binaries(false), analyzeExhaust, Collections.singletonList(psiFile)); state.compileCorrectFiles(CompilationErrorHandler.THROW_EXCEPTION); return state; diff --git a/compiler/tests/org/jetbrains/jet/compiler/CompileJavaAgainstKotlinTest.java b/compiler/tests/org/jetbrains/jet/compiler/CompileJavaAgainstKotlinTest.java index 5f3d17e046f..7834b4ead9d 100644 --- a/compiler/tests/org/jetbrains/jet/compiler/CompileJavaAgainstKotlinTest.java +++ b/compiler/tests/org/jetbrains/jet/compiler/CompileJavaAgainstKotlinTest.java @@ -28,6 +28,7 @@ import org.jetbrains.jet.JetTestCaseBuilder; import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.codegen.*; import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode; import org.jetbrains.jet.plugin.JetLanguage; import org.junit.Assert; @@ -75,7 +76,7 @@ public class CompileJavaAgainstKotlinTest extends TestCaseWithTmpdir { virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET); JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false); - ClassFileFactory classFileFactory = GenerationUtils.compileFileGetClassFileFactoryForTest(psiFile); + ClassFileFactory classFileFactory = GenerationUtils.compileFileGetClassFileFactoryForTest(psiFile, CompilerSpecialMode.REGULAR); CompileEnvironmentUtil.writeToOutputDirectory(classFileFactory, tmpdir.getPath()); diff --git a/compiler/tests/org/jetbrains/jet/compiler/CompileKotlinAgainstKotlinTest.java b/compiler/tests/org/jetbrains/jet/compiler/CompileKotlinAgainstKotlinTest.java index a3e56c4eeb3..7eddece3513 100644 --- a/compiler/tests/org/jetbrains/jet/compiler/CompileKotlinAgainstKotlinTest.java +++ b/compiler/tests/org/jetbrains/jet/compiler/CompileKotlinAgainstKotlinTest.java @@ -29,6 +29,7 @@ import org.jetbrains.jet.JetTestCaseBuilder; import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.codegen.*; import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode; import org.jetbrains.jet.plugin.JetLanguage; import java.io.File; @@ -89,7 +90,7 @@ public class CompileKotlinAgainstKotlinTest extends TestCaseWithTmpdir { virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET); JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false); - ClassFileFactory classFileFactory = GenerationUtils.compileFileGetClassFileFactoryForTest(psiFile); + ClassFileFactory classFileFactory = GenerationUtils.compileFileGetClassFileFactoryForTest(psiFile, CompilerSpecialMode.REGULAR); CompileEnvironmentUtil.writeToOutputDirectory(classFileFactory, aDir.getPath()); @@ -107,7 +108,7 @@ public class CompileKotlinAgainstKotlinTest extends TestCaseWithTmpdir { virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET); JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false); - ClassFileFactory classFileFactory = GenerationUtils.compileFileGetClassFileFactoryForTest(psiFile); + ClassFileFactory classFileFactory = GenerationUtils.compileFileGetClassFileFactoryForTest(psiFile, CompilerSpecialMode.REGULAR); CompileEnvironmentUtil.writeToOutputDirectory(classFileFactory, bDir.getPath()); diff --git a/compiler/tests/org/jetbrains/jet/compiler/ReadJavaBinaryClassTest.java b/compiler/tests/org/jetbrains/jet/compiler/ReadJavaBinaryClassTest.java index f9a41a25b10..251107a40a0 100644 --- a/compiler/tests/org/jetbrains/jet/compiler/ReadJavaBinaryClassTest.java +++ b/compiler/tests/org/jetbrains/jet/compiler/ReadJavaBinaryClassTest.java @@ -76,7 +76,7 @@ public class ReadJavaBinaryClassTest extends TestCaseWithTmpdir { } private NamespaceDescriptor compileKotlin() throws Exception { - JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable); + JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable, CompilerSpecialMode.JDK_HEADERS); String text = FileUtil.loadFile(ktFile); @@ -86,7 +86,7 @@ public class ReadJavaBinaryClassTest extends TestCaseWithTmpdir { BindingContext bindingContext = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors( psiFile, JetControlFlowDataTraceFactory.EMPTY, - CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.REGULAR)) + CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.JDK_HEADERS)) .getBindingContext(); return bindingContext.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, FqName.topLevel("test")); } @@ -108,13 +108,13 @@ public class ReadJavaBinaryClassTest extends TestCaseWithTmpdir { fileManager.close(); } - JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable); + JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable, CompilerSpecialMode.JDK_HEADERS); jetCoreEnvironment.addToClasspath(tmpdir); jetCoreEnvironment.addToClasspath(new File("out/production/runtime")); InjectorForJavaSemanticServices injector = new InjectorForJavaSemanticServices( - CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.REGULAR), jetCoreEnvironment.getProject()); + CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.JDK_HEADERS), jetCoreEnvironment.getProject()); JavaDescriptorResolver javaDescriptorResolver = injector.getJavaDescriptorResolver(); return javaDescriptorResolver.resolveNamespace(FqName.topLevel("test"), DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN); } diff --git a/compiler/tests/org/jetbrains/jet/compiler/ReadKotlinBinaryClassTest.java b/compiler/tests/org/jetbrains/jet/compiler/ReadKotlinBinaryClassTest.java index ae233c890cd..cd07037c40b 100644 --- a/compiler/tests/org/jetbrains/jet/compiler/ReadKotlinBinaryClassTest.java +++ b/compiler/tests/org/jetbrains/jet/compiler/ReadKotlinBinaryClassTest.java @@ -63,7 +63,7 @@ public class ReadKotlinBinaryClassTest extends TestCaseWithTmpdir { @Override public void runTest() throws Exception { - jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable); + jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable, CompilerSpecialMode.JDK_HEADERS); String text = FileUtil.loadFile(testFile); @@ -71,7 +71,7 @@ public class ReadKotlinBinaryClassTest extends TestCaseWithTmpdir { virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET); JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false); - GenerationState state = GenerationUtils.compileFileGetGenerationStateForTest(psiFile); + GenerationState state = GenerationUtils.compileFileGetGenerationStateForTest(psiFile, CompilerSpecialMode.JDK_HEADERS); ClassFileFactory classFileFactory = state.getFactory(); @@ -84,13 +84,13 @@ public class ReadKotlinBinaryClassTest extends TestCaseWithTmpdir { Disposer.dispose(myTestRootDisposable); - jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable); + jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable, CompilerSpecialMode.JDK_HEADERS); jetCoreEnvironment.addToClasspath(tmpdir); jetCoreEnvironment.addToClasspath(new File("out/production/runtime")); InjectorForJavaSemanticServices injector = new InjectorForJavaSemanticServices( - CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.REGULAR), jetCoreEnvironment.getProject()); + CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.JDK_HEADERS), jetCoreEnvironment.getProject()); JavaDescriptorResolver javaDescriptorResolver = injector.getJavaDescriptorResolver(); NamespaceDescriptor namespaceFromClass = javaDescriptorResolver.resolveNamespace(FqName.topLevel("test"), DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN); diff --git a/compiler/tests/org/jetbrains/jet/compiler/WriteSignatureTest.java b/compiler/tests/org/jetbrains/jet/compiler/WriteSignatureTest.java index b74d9c7419a..f09a6fa3a0f 100644 --- a/compiler/tests/org/jetbrains/jet/compiler/WriteSignatureTest.java +++ b/compiler/tests/org/jetbrains/jet/compiler/WriteSignatureTest.java @@ -31,6 +31,7 @@ import org.jetbrains.jet.JetTestCaseBuilder; import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.codegen.*; import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode; import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; import org.jetbrains.jet.plugin.JetLanguage; import org.junit.Assert; @@ -80,7 +81,7 @@ public class WriteSignatureTest extends TestCaseWithTmpdir { virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET); JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false); - ClassFileFactory classFileFactory = GenerationUtils.compileFileGetClassFileFactoryForTest(psiFile); + ClassFileFactory classFileFactory = GenerationUtils.compileFileGetClassFileFactoryForTest(psiFile, CompilerSpecialMode.REGULAR); CompileEnvironmentUtil.writeToOutputDirectory(classFileFactory, tmpdir.getPath()); From 7eb653ea22eca4be60e53858cc145a7096d7f2ac Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Thu, 19 Apr 2012 14:05:40 +0400 Subject: [PATCH 09/20] ReadKotlinBinaryClassTest: inner class extend inner class --- .../class/InnerClassExtendInnerClass.kt | 7 +++++++ .../class/InnerClassExtendInnerClass.txt | 11 +++++++++++ 2 files changed, 18 insertions(+) create mode 100644 compiler/testData/readKotlinBinaryClass/class/InnerClassExtendInnerClass.kt create mode 100644 compiler/testData/readKotlinBinaryClass/class/InnerClassExtendInnerClass.txt diff --git a/compiler/testData/readKotlinBinaryClass/class/InnerClassExtendInnerClass.kt b/compiler/testData/readKotlinBinaryClass/class/InnerClassExtendInnerClass.kt new file mode 100644 index 00000000000..85a4f6c29cc --- /dev/null +++ b/compiler/testData/readKotlinBinaryClass/class/InnerClassExtendInnerClass.kt @@ -0,0 +1,7 @@ +package test + +class Outer() { + open class Inner1() + + class Inner2() : Inner1() +} diff --git a/compiler/testData/readKotlinBinaryClass/class/InnerClassExtendInnerClass.txt b/compiler/testData/readKotlinBinaryClass/class/InnerClassExtendInnerClass.txt new file mode 100644 index 00000000000..fef91cbe9b3 --- /dev/null +++ b/compiler/testData/readKotlinBinaryClass/class/InnerClassExtendInnerClass.txt @@ -0,0 +1,11 @@ +namespace test + +final class test.Outer : jet.Any { + final /*constructor*/ fun (): test.Outer + open class test.Outer.Inner1 : jet.Any { + final /*constructor*/ fun (): test.Outer.Inner1 + } + final class test.Outer.Inner2 : test.Outer.Inner1 { + final /*constructor*/ fun (): test.Outer.Inner2 + } +} From bfdba9cebc2c42100654f8e3eccb07f65b558534 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Thu, 19 Apr 2012 14:08:50 +0400 Subject: [PATCH 10/20] test for inner class of generic class inheriting another generic class actually fixed in Idea in 4afdd61d8dcb846994166ed8f30a7515e9661d56. Thanks, Max! --- .../readJavaBinaryClass/InnerClassesInGeneric.java | 12 ++++++++++++ .../readJavaBinaryClass/InnerClassesInGeneric.kt | 11 +++++++++++ .../readJavaBinaryClass/InnerClassesInGeneric.txt | 13 +++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 compiler/testData/readJavaBinaryClass/InnerClassesInGeneric.java create mode 100644 compiler/testData/readJavaBinaryClass/InnerClassesInGeneric.kt create mode 100644 compiler/testData/readJavaBinaryClass/InnerClassesInGeneric.txt diff --git a/compiler/testData/readJavaBinaryClass/InnerClassesInGeneric.java b/compiler/testData/readJavaBinaryClass/InnerClassesInGeneric.java new file mode 100644 index 00000000000..f322543204f --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/InnerClassesInGeneric.java @@ -0,0 +1,12 @@ +package test; + +interface Trait

{ +} + +class Outer { + class Inner { + } + + class Inner2 extends Inner implements Trait

{ + } +} diff --git a/compiler/testData/readJavaBinaryClass/InnerClassesInGeneric.kt b/compiler/testData/readJavaBinaryClass/InnerClassesInGeneric.kt new file mode 100644 index 00000000000..f7aecfe1b5a --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/InnerClassesInGeneric.kt @@ -0,0 +1,11 @@ +package test + +trait Trait + +open class Outer() { + open class Inner() { + } + + open class Inner2() : Inner(), Trait

{ + } +} diff --git a/compiler/testData/readJavaBinaryClass/InnerClassesInGeneric.txt b/compiler/testData/readJavaBinaryClass/InnerClassesInGeneric.txt new file mode 100644 index 00000000000..e662ea177e8 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/InnerClassesInGeneric.txt @@ -0,0 +1,13 @@ +namespace test + +open class test.Outer : jet.Any { + final /*constructor*/ fun (): test.Outer + open class test.Outer.Inner : jet.Any { + final /*constructor*/ fun (): test.Outer.Inner + } + open class test.Outer.Inner2 : test.Outer.Inner, test.Trait

{ + final /*constructor*/ fun (): test.Outer.Inner2 + } +} +abstract trait test.Trait : jet.Any { +} From e698b0eec45cf370f3eabd5b3b5d1c2cd17d8897 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Thu, 19 Apr 2012 14:22:58 +0400 Subject: [PATCH 11/20] resolve all descriptors from libraries (basic) --- .../jet/compiler/longTest/LibFromMaven.java | 57 +++++ ...solveDescriptorsFromExternalLibraries.java | 199 ++++++++++++++++++ 2 files changed, 256 insertions(+) create mode 100644 compiler/tests/org/jetbrains/jet/compiler/longTest/LibFromMaven.java create mode 100644 compiler/tests/org/jetbrains/jet/compiler/longTest/ResolveDescriptorsFromExternalLibraries.java diff --git a/compiler/tests/org/jetbrains/jet/compiler/longTest/LibFromMaven.java b/compiler/tests/org/jetbrains/jet/compiler/longTest/LibFromMaven.java new file mode 100644 index 00000000000..f16c660f1da --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/compiler/longTest/LibFromMaven.java @@ -0,0 +1,57 @@ +/* + * Copyright 2010-2012 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.compiler.longTest; + +import org.jetbrains.annotations.NotNull; + +/** + * @author Stepan Koltsov + */ +public class LibFromMaven { + @NotNull + private final String org; + @NotNull + private final String module; + @NotNull + private final String rev; + + public LibFromMaven(@NotNull String org, @NotNull String module, @NotNull String rev) { + this.org = org; + this.module = module; + this.rev = rev; + } + + @NotNull + public String getOrg() { + return org; + } + + @NotNull + public String getModule() { + return module; + } + + @NotNull + public String getRev() { + return rev; + } + + @Override + public String toString() { + return org + "/" + module + "/" + rev; + } +} diff --git a/compiler/tests/org/jetbrains/jet/compiler/longTest/ResolveDescriptorsFromExternalLibraries.java b/compiler/tests/org/jetbrains/jet/compiler/longTest/ResolveDescriptorsFromExternalLibraries.java new file mode 100644 index 00000000000..a5b9c30a7ba --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/compiler/longTest/ResolveDescriptorsFromExternalLibraries.java @@ -0,0 +1,199 @@ +/* + * Copyright 2010-2012 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.compiler.longTest; + +import com.google.common.io.ByteStreams; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.util.Disposer; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.commons.httpclient.params.HttpMethodParams; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.CompileCompilerDependenciesTest; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.TimeUtils; +import org.jetbrains.jet.compiler.JetCoreEnvironment; +import org.jetbrains.jet.di.InjectorForJavaSemanticServices; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.resolve.FqName; +import org.jetbrains.jet.lang.resolve.java.CompilerDependencies; +import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode; +import org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +/** + * @author Stepan Koltsov + */ +public class ResolveDescriptorsFromExternalLibraries { + + @NotNull + private final CompilerDependencies compilerDependencies; + + + public static void main(String[] args) throws Exception { + new ResolveDescriptorsFromExternalLibraries().run(); + System.out.println("$"); + } + + + public ResolveDescriptorsFromExternalLibraries() { + System.out.println("Getting compiler dependencies"); + compilerDependencies = CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.REGULAR); + } + + private void run() throws Exception { + testLibrary("com.google.guava", "guava", "12.0-rc2"); + testLibrary("org.springframework", "spring-core", "3.1.1.RELEASE"); + } + + private void testLibrary(@NotNull String org, @NotNull String module, @NotNull String rev) throws Exception { + LibFromMaven lib = new LibFromMaven(org, module, rev); + File jar = getLibrary(lib); + System.out.println("Testing library " + lib + "..."); + System.out.println("Using file " + jar); + + long start = System.currentTimeMillis(); + + Disposable junk = new Disposable() { + @Override + public void dispose() { } + }; + + JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(junk); + jetCoreEnvironment.addToClasspath(jar); + + + InjectorForJavaSemanticServices injector = new InjectorForJavaSemanticServices(compilerDependencies, jetCoreEnvironment.getProject()); + + FileInputStream is = new FileInputStream(jar); + try { + ZipInputStream zip = new ZipInputStream(is); + for (;;) { + ZipEntry entry = zip.getNextEntry(); + if (entry == null) { + break; + } + String entryName = entry.getName(); + if (!entryName.endsWith(".class")) { + continue; + } + if (entryName.matches("(.*/|)package-info\\.class")) { + continue; + } + if (entryName.contains("$")) { + continue; + } + String className = entryName.substring(0, entryName.length() - ".class".length()).replace("/", "."); + ClassDescriptor clazz = injector.getJavaDescriptorResolver().resolveClass(new FqName(className), DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN); + if (clazz == null) { + throw new IllegalStateException("class not found by name " + className + " in " + lib); + } + clazz.getDefaultType().getMemberScope().getAllDescriptors(); + } + + } finally { + try { + is.close(); + } + catch (Throwable e) {} + + Disposer.dispose(junk); + } + + System.out.println("Testing library " + lib + " done in " + TimeUtils.millisecondsToSecondsString(System.currentTimeMillis() - start) + "s"); + } + + @NotNull + private File getLibrary(@NotNull LibFromMaven lib) throws Exception { + File userHome = new File(System.getProperty("user.home")); + String fileName = lib.getModule() + "-" + lib.getRev() + ".jar"; + + File dir = new File(userHome, ".kotlin-project/resolve-libraries/" + lib.getOrg() + "/" + lib.getModule()); + + File file = new File(dir, fileName); + if (file.exists()) { + return file; + } + + JetTestUtils.mkdirs(dir); + + File tmp = new File(dir, fileName + "~"); + + String uri = url(lib); + GetMethod method = new GetMethod(uri); + + FileOutputStream os = null; + + System.out.println("Downloading library " + lib + " to " + file); + + MultiThreadedHttpConnectionManager connectionManager = null; + try { + connectionManager = new MultiThreadedHttpConnectionManager(); + HttpClient httpClient = new HttpClient(connectionManager); + os = new FileOutputStream(tmp); + String userAgent = ResolveDescriptorsFromExternalLibraries.class.getName() + "/commons-httpclient"; + method.getParams().setParameter(HttpMethodParams.USER_AGENT, userAgent); + int code = httpClient.executeMethod(method); + if (code != 200) { + throw new RuntimeException("failed to execute GET " + uri + ", code is " + code); + } + InputStream responseBodyAsStream = method.getResponseBodyAsStream(); + if (responseBodyAsStream == null) { + throw new RuntimeException("method is executed fine, but response is null"); + } + ByteStreams.copy(responseBodyAsStream, os); + os.close(); + if (!tmp.renameTo(file)) { + throw new RuntimeException("failed to rename file: " + tmp + " to " + file); + } + return file; + } + finally { + if (method != null) { + try { + method.releaseConnection(); + } + catch (Throwable e) {} + } + if (connectionManager != null) { + try { + connectionManager.shutdown(); + } + catch (Throwable e) {} + } + if (os != null) { + try { + os.close(); + } + catch (Throwable e) {} + } + tmp.delete(); + } + } + + private static String url(LibFromMaven lib) { + return "http://repo1.maven.org/maven2/" + lib.getOrg().replace(".", "/") + "/" + lib.getModule() + "/" + lib.getRev() + + "/" + lib.getModule() + "-" + lib.getRev() + ".jar"; + } +} From 0efe0d5d934e0bf3a08fe424590afd2b765e555b Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Thu, 19 Apr 2012 14:32:02 +0400 Subject: [PATCH 12/20] better message in CompilationException --- .../org/jetbrains/jet/codegen/CompilationException.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CompilationException.java b/compiler/backend/src/org/jetbrains/jet/codegen/CompilationException.java index f890d94c0ff..017b499e327 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CompilationException.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CompilationException.java @@ -62,11 +62,13 @@ public class CompilationException extends RuntimeException { private String where() { Throwable cause = getCause(); - if (cause != null && cause.getStackTrace().length > 0) { - return cause.getStackTrace()[0].getFileName() + ":" + cause.getStackTrace()[0].getLineNumber(); + Throwable throwable = cause != null ? cause : this; + StackTraceElement[] stackTrace = throwable.getStackTrace(); + if (stackTrace != null && stackTrace.length > 0) { + return stackTrace[0].getFileName() + ":" + stackTrace[0].getLineNumber(); } else { - return "far away in cyberspace"; + return "unknown"; } } From 44c5e0ca2e44ede377c21d25ca9844bb6514f010 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Thu, 19 Apr 2012 15:09:20 +0400 Subject: [PATCH 13/20] Report exceptions even when running under a release build of IDEA --- idea/src/META-INF/plugin.xml | 2 +- .../reporter/KotlinReportSubmitter.java | 49 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 idea/src/org/jetbrains/jet/plugin/reporter/KotlinReportSubmitter.java diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index e6132530e51..00f43bf7d8d 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -56,7 +56,7 @@ - + diff --git a/idea/src/org/jetbrains/jet/plugin/reporter/KotlinReportSubmitter.java b/idea/src/org/jetbrains/jet/plugin/reporter/KotlinReportSubmitter.java new file mode 100644 index 00000000000..dd158d9404c --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/reporter/KotlinReportSubmitter.java @@ -0,0 +1,49 @@ +/* + * Copyright 2010-2012 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.reporter; + +import com.intellij.diagnostic.ITNReporter; +import com.intellij.openapi.diagnostic.ErrorReportSubmitter; +import com.intellij.openapi.diagnostic.IdeaLoggingEvent; +import com.intellij.openapi.diagnostic.SubmittedReportInfo; + +import java.awt.*; + +/** + * We need to wrap ITNReporter into this delegating class to work around the following problem: + * + * Kotlin's lifecycle does not align with the one of IDEA, so every now and then we are in the situation when users + * install an unstable build of Kotlin on a released build of IDEA. Since IDEA does not show exceptions from ITNReporter + * in release build, the user doesn't see exceptions from Kotlin in such a situations. Wrapping solves this problem: + * even release builds of IDEA will report Kotlin exceptions to the user (and allow to submit them to Exception Analyzer). + * + * @author abreslav + */ +public class KotlinReportSubmitter extends ErrorReportSubmitter { + + private final ErrorReportSubmitter delegate = new ITNReporter(); + + @Override + public String getReportActionText() { + return delegate.getReportActionText(); + } + + @Override + public SubmittedReportInfo submit(IdeaLoggingEvent[] events, Component parentComponent) { + return delegate.submit(events, parentComponent); + } +} From 558d1a0e2f6afa5386984fcdab30704f1aa0e43a Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Thu, 19 Apr 2012 14:20:36 +0400 Subject: [PATCH 14/20] KT-1680 Warn if non-null variable is compared to null #KT-1680 fixed --- .../org/jetbrains/jet/lang/diagnostics/Errors.java | 2 ++ .../expressions/BasicExpressionTypingVisitor.java | 7 +++++++ .../tests/nullabilityAndAutoCasts/kt1680.jet | 14 ++++++++++++++ 3 files changed, 23 insertions(+) create mode 100644 compiler/testData/diagnostics/tests/nullabilityAndAutoCasts/kt1680.jet diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java index 42028fc4d2c..193aac1df0c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java @@ -380,6 +380,8 @@ public interface Errors { } }, TO_STRING, TO_STRING); + DiagnosticFactory2 SENSELESS_COMPARISON = DiagnosticFactory2.create(WARNING, "Condition ''{0}'' is always ''{1}''", ELEMENT_TEXT, TO_STRING); + DiagnosticFactory2 OVERRIDING_FINAL_MEMBER = DiagnosticFactory2.create(ERROR, "''{0}'' in ''{1}'' is final and cannot be overridden", NAME, NAME); DiagnosticFactory3 CANNOT_WEAKEN_ACCESS_PRIVILEGE = DiagnosticFactory3.create(ERROR, "Cannot weaken access privilege ''{0}'' for ''{1}'' in ''{2}''", PositioningStrategies.POSITION_VISIBILITY_MODIFIER, TO_STRING, NAME, NAME); DiagnosticFactory3 CANNOT_CHANGE_ACCESS_PRIVILEGE = DiagnosticFactory3.create(ERROR, "Cannot change access privilege ''{0}'' for ''{1}'' in ''{2}''", PositioningStrategies.POSITION_VISIBILITY_MODIFIER, TO_STRING, NAME, NAME); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java index 66059c490fe..bc932755159 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -950,9 +950,16 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { context.trace.report(EQUALITY_NOT_APPLICABLE.on(expression, operationSign, leftType, rightType)); } } + if (isSenselessComparisonWithNull(leftType, right) || isSenselessComparisonWithNull(rightType, left)) { + context.trace.report(SENSELESS_COMPARISON.on(expression, expression, operationSign.getReferencedNameElementType() == JetTokens.EXCLEQ)); + } } } + private boolean isSenselessComparisonWithNull(JetType firstType, JetExpression secondExpression) { + return !firstType.isNullable() && secondExpression instanceof JetConstantExpression && secondExpression.getNode().getElementType() == JetNodeTypes.NULL; + } + protected JetType visitAssignmentOperation(JetBinaryExpression expression, ExpressionTypingContext context) { return assignmentIsNotAnExpressionError(expression, context); } diff --git a/compiler/testData/diagnostics/tests/nullabilityAndAutoCasts/kt1680.jet b/compiler/testData/diagnostics/tests/nullabilityAndAutoCasts/kt1680.jet new file mode 100644 index 00000000000..8b1a7a42ebc --- /dev/null +++ b/compiler/testData/diagnostics/tests/nullabilityAndAutoCasts/kt1680.jet @@ -0,0 +1,14 @@ +//KT-1680 Warn if non-null variable is compared to null +package kt1680 + +fun foo() { + val x = 1 + if (x != null) {} // <-- need a warning here! + if (x == null) {} + if (null != x) {} + if (null == x) {} + + val y : Int? = 1 + if (y != null) {} + if (y == null) {} +} \ No newline at end of file From d245a10d02c5d3251f91bb41657013926d701b98 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Thu, 19 Apr 2012 16:01:46 +0400 Subject: [PATCH 15/20] KT-1822 Error 'cannot infer visibility' required #KT-1822 fixed --- .../jet/lang/diagnostics/Errors.java | 5 ++- .../diagnostics/PositioningStrategies.java | 2 + .../jet/lang/resolve/OverrideResolver.java | 40 +++++++++++++------ .../diagnostics/tests/scopes/kt151.jet | 2 +- .../diagnostics/tests/scopes/kt1822.jet | 30 ++++++++++++++ 5 files changed, 64 insertions(+), 15 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/scopes/kt1822.jet diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java index 193aac1df0c..d2e374196ed 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java @@ -156,11 +156,12 @@ public interface Errors { DiagnosticFactory BY_IN_SECONDARY_CONSTRUCTOR = DiagnosticFactory.create(ERROR, "'by'-clause is only supported for primary constructors"); DiagnosticFactory INITIALIZER_WITH_NO_ARGUMENTS = DiagnosticFactory.create(ERROR, "Constructor arguments required"); DiagnosticFactory MANY_CALLS_TO_THIS = DiagnosticFactory.create(ERROR, "Only one call to 'this(...)' is allowed"); - DiagnosticFactory1 NOTHING_TO_OVERRIDE = DiagnosticFactory1.create(ERROR, "{0} overrides nothing", PositioningStrategies.positionModifier(JetTokens.OVERRIDE_KEYWORD), DescriptorRenderer.TEXT); + DiagnosticFactory1 NOTHING_TO_OVERRIDE = DiagnosticFactory1.create(ERROR, "{0} overrides nothing", PositioningStrategies.POSITION_OVERRIDE_MODIFIER, DescriptorRenderer.TEXT); DiagnosticFactory3 VIRTUAL_MEMBER_HIDDEN = DiagnosticFactory3.create(ERROR, "''{0}'' hides ''{1}'' in class {2} and needs 'override' modifier", PositioningStrategies.POSITION_NAME_IDENTIFIER, DescriptorRenderer.TEXT, DescriptorRenderer.TEXT, DescriptorRenderer.TEXT); DiagnosticFactory3 CANNOT_OVERRIDE_INVISIBLE_MEMBER = - DiagnosticFactory3.create(ERROR, "''{0}'' cannot has no access to ''{1}'' in class {2}, so it cannot override it", PositioningStrategies.positionModifier(JetTokens.OVERRIDE_KEYWORD), DescriptorRenderer.TEXT, DescriptorRenderer.TEXT, DescriptorRenderer.TEXT); + DiagnosticFactory3.create(ERROR, "''{0}'' cannot has no access to ''{1}'' in class {2}, so it cannot override it", PositioningStrategies.POSITION_OVERRIDE_MODIFIER, DescriptorRenderer.TEXT, DescriptorRenderer.TEXT, DescriptorRenderer.TEXT); + DiagnosticFactory CANNOT_INFER_VISIBILITY = DiagnosticFactory.create(ERROR, "Cannot infer visibility. Please specify it explicitly", PositioningStrategies.POSITION_OVERRIDE_MODIFIER); DiagnosticFactory1 ENUM_ENTRY_SHOULD_BE_INITIALIZED = DiagnosticFactory1.create(ERROR, "Missing delegation specifier ''{0}''", PositioningStrategies.POSITION_NAME_IDENTIFIER, NAME); DiagnosticFactory1 ENUM_ENTRY_ILLEGAL_TYPE = DiagnosticFactory1.create(ERROR, "The type constructor of enum entry should be ''{0}''", NAME); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/PositioningStrategies.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/PositioningStrategies.java index 5cfdb034a23..96bf5fffeea 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/PositioningStrategies.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/PositioningStrategies.java @@ -88,6 +88,8 @@ public class PositioningStrategies { public static final PositioningStrategy POSITION_ABSTRACT_MODIFIER = positionModifier(JetTokens.ABSTRACT_KEYWORD); + public static final PositioningStrategy POSITION_OVERRIDE_MODIFIER = positionModifier(JetTokens.OVERRIDE_KEYWORD); + public static PositioningStrategy positionModifier(final JetKeywordToken token) { return new PositioningStrategy() { @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java index e971843d3e1..cb1e794bf8c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java @@ -36,6 +36,7 @@ import javax.inject.Inject; import java.util.*; import static org.jetbrains.jet.lang.diagnostics.Errors.*; +import static org.jetbrains.jet.lang.resolve.BindingContext.DECLARATION_TO_DESCRIPTOR; import static org.jetbrains.jet.lang.resolve.BindingContext.DELEGATED; /** @@ -418,10 +419,10 @@ public class OverrideResolver { private void resolveUnknownVisibilityForMembers(@NotNull Set fakeOverrides) { for (CallableMemberDescriptor override : fakeOverrides) { - resolveUnknownVisibilityForMember(override); + resolveUnknownVisibilityForMember(null, override); } - for (CallableMemberDescriptor memberDescriptor : context.getMembers().values()) { - resolveUnknownVisibilityForMember(memberDescriptor); + for (Map.Entry entry : context.getMembers().entrySet()) { + resolveUnknownVisibilityForMember(entry.getKey(), entry.getValue()); } for (PropertyDescriptor propertyDescriptor : context.getProperties().values()) { for (PropertyAccessorDescriptor accessor : propertyDescriptor.getAccessors()) { @@ -432,13 +433,19 @@ public class OverrideResolver { } } - private void resolveUnknownVisibilityForMember(@NotNull CallableMemberDescriptor memberDescriptor) { + private void resolveUnknownVisibilityForMember(@Nullable JetDeclaration member, @NotNull CallableMemberDescriptor memberDescriptor) { resolveUnknownVisibilityForOverriddenDescriptors(memberDescriptor.getOverriddenDescriptors()); if (memberDescriptor.getVisibility() != Visibilities.INHERITED) { return; } Visibility visibility = findMaxVisibility(memberDescriptor.getOverriddenDescriptors()); + if (visibility == null) { + if (member != null) { + trace.report(CANNOT_INFER_VISIBILITY.on(member)); + } + visibility = Visibilities.PUBLIC; + } if (memberDescriptor instanceof PropertyDescriptor) { ((PropertyDescriptor)memberDescriptor).setVisibility(visibility); @@ -465,12 +472,14 @@ public class OverrideResolver { private void resolveUnknownVisibilityForOverriddenDescriptors(@NotNull Collection descriptors) { for (CallableMemberDescriptor descriptor : descriptors) { if (descriptor.getVisibility() == Visibilities.INHERITED) { - resolveUnknownVisibilityForMember(descriptor); + PsiElement element = BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), descriptor); + JetDeclaration declaration = (element instanceof JetDeclaration) ? (JetDeclaration) element : null; + resolveUnknownVisibilityForMember(declaration, descriptor); } } } - @NotNull + @Nullable private Visibility findMaxVisibility(@NotNull Collection descriptors) { if (descriptors.isEmpty()) { return Visibilities.INTERNAL; @@ -483,16 +492,23 @@ public class OverrideResolver { maxVisibility = visibility; continue; } - Integer compare = Visibilities.compare(visibility, maxVisibility); - if (compare == null) { - maxVisibility = Visibilities.PUBLIC; //todo error or warning when inference only from incomparable visibilities - continue; + Integer compareResult = Visibilities.compare(visibility, maxVisibility); + if (compareResult == null) { + maxVisibility = null; } - if (compare > 0) { + else if (compareResult > 0) { maxVisibility = visibility; } } - assert maxVisibility != null; + if (maxVisibility == null) { + return null; + } + for (CallableMemberDescriptor descriptor : descriptors) { + Integer compareResult = Visibilities.compare(maxVisibility, descriptor.getVisibility()); + if (compareResult == null || compareResult < 0) { + return null; + } + } return maxVisibility; } diff --git a/compiler/testData/diagnostics/tests/scopes/kt151.jet b/compiler/testData/diagnostics/tests/scopes/kt151.jet index 6387a2b3810..e50bbf6526d 100644 --- a/compiler/testData/diagnostics/tests/scopes/kt151.jet +++ b/compiler/testData/diagnostics/tests/scopes/kt151.jet @@ -36,5 +36,5 @@ class F : C(), T { } class G : C(), T { - override fun foo() {} + public override fun foo() {} } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/scopes/kt1822.jet b/compiler/testData/diagnostics/tests/scopes/kt1822.jet new file mode 100644 index 00000000000..77031e1edf5 --- /dev/null +++ b/compiler/testData/diagnostics/tests/scopes/kt1822.jet @@ -0,0 +1,30 @@ +//KT-1822 Error 'cannot infer visibility' required +package kt1822 + +open class C { + internal open fun foo() {} +} + +trait T { + protected fun foo() {} +} + +class G : C(), T { + override fun foo() {} //should be an error "cannot infer visibility"; for now 'public' is inferred in such cases +} + +open class A { + internal open fun foo() {} +} + +trait B { + protected fun foo() {} +} + +trait D { + public fun foo() {} +} + +class E : A(), B, D { + override fun foo() {} +} \ No newline at end of file From 414966b27e7bc3af71ac6059589311adf1fe39d7 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 18 Apr 2012 18:30:58 +0400 Subject: [PATCH 16/20] More adjustment in icons --- .../jetbrains/jet/plugin/icons/field_value.png | Bin 0 -> 633 bytes .../jet/plugin/icons/field_variable.png | Bin 0 -> 713 bytes .../jet/plugin/JetDescriptorIconProvider.java | 16 ++++++++++++++-- .../jetbrains/jet/plugin/JetIconProvider.java | 6 +++--- idea/src/org/jetbrains/jet/plugin/JetIcons.java | 2 ++ 5 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 idea/resources/org/jetbrains/jet/plugin/icons/field_value.png create mode 100644 idea/resources/org/jetbrains/jet/plugin/icons/field_variable.png diff --git a/idea/resources/org/jetbrains/jet/plugin/icons/field_value.png b/idea/resources/org/jetbrains/jet/plugin/icons/field_value.png new file mode 100644 index 0000000000000000000000000000000000000000..f49d3094c631fec90fe3e6927f2f78df45d62a8f GIT binary patch literal 633 zcmV-<0*3vGP)bDCxTuvz zL;VPrh&p8!#f1y;SNIDAH!kYma1|63apTsV;M$D~v#=smO9X9_X|+jds+-A7XXak- zeJ>5E;;I98?tAm*oO8dPVP+iXnbFtVN3X7NP7f%jfb$&U$0qBHz*B2-=WAlkyDuKD zTLJ}F=Fi+-3>vkQ^QS$d-!!mXj9AXut|=n??(D^1TCLgLA6a5GSB!9|cmm6;`6RUE6bkSKu~C9+S2I5ntL=R8eo zLZJD==#OkwSD!q?=j{+hQ^cqCH>|#VigL9Kj)Wu;P_Y0a{)>QM6(MT=;$?hTZ=+BW zg3fm=*XqcJIXITzVnVK|9gRSc60)%o6yOV>-P;nS8GQY@h2UZx*`5^QK!7pZNSUSy zY^&H7ic^BWZ~;-Apcn2~A1pP5fLtB2ak}Fa4%_HbNL|I%{Dn(+{`w94^P;|+f=0P( zsWG<2hXXj30$hk{k-^Qg4TSpx+`4)l=^$|_{%;cPgh_EMiMC4ete>jl@tynNp?p>W zi)O3H2~7wl5$J^3VM&b3Pp407lF1&iGD!8c&bKL9vM}PqU$zg+Q TnIjmn00000NkvXXu0mjf({d+| literal 0 HcmV?d00001 diff --git a/idea/resources/org/jetbrains/jet/plugin/icons/field_variable.png b/idea/resources/org/jetbrains/jet/plugin/icons/field_variable.png new file mode 100644 index 0000000000000000000000000000000000000000..dc47319f827e2188ba03597d15b291006dd32eec GIT binary patch literal 713 zcmV;)0yh1LP)2;Y=|kKq#kUHXpC1wym<9uO%Eo$8q@d}=%F?0!9M{_Jb5rNp)n>RG}W{PTEJr3 z0@4ql>@MugI7@f2dhI0dOm_0jZ{B(KeNBup9A|WC)0;c9NB4X@CV7N-c=WwB9&sKE zJeCdN{dZ3f0mcUhMcfnPGZ(^_1AV6)Rza|ssYD@H8k3d$=H2wy#YCx)e{nl99sLlU z|C@oHMI?0Z*0a&@xJwkf1*%X`nF0cX#V%Tg+`}hq*8Z#MZ+%Yva8#SjM%wNx{uy`J z@3PoLfe-?fsGxi$l!B=y5S7B#W4Dfs28JC2&IkHaJAlct8=-)uTNG%MVtV#DmQq=m zhzZH13?99lL-$D$RAR6R{XI^XFR1&}0fg*B4l8RhXn>&CgZN^KZ*xFq9f5NmsJ{tl zjY4fQ^jZh)y2%}YN9f{)X>V2-{KHld@>VuCpZ=W4)eF0__5`YMxgvma zNlTAvqb_BCC3Ds4)+?i=%|}W(y8dJFaU%9HmQSygtCc;u)*@6QgzigKd83#vf6si1 vZEmkVxpwnm)Hr9-y74&8WIAp;{}EsSX(v24yHFAq00000NkvXXu0mjfm#9Kv literal 0 HcmV?d00001 diff --git a/idea/src/org/jetbrains/jet/plugin/JetDescriptorIconProvider.java b/idea/src/org/jetbrains/jet/plugin/JetDescriptorIconProvider.java index 2b6506cfc7c..1317a34b943 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetDescriptorIconProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/JetDescriptorIconProvider.java @@ -76,7 +76,8 @@ public final class JetDescriptorIconProvider { return PlatformIcons.PACKAGE_OPEN_ICON; } if (descriptor instanceof FunctionDescriptor) { - return JetIcons.FUNCTION; + return descriptor.getContainingDeclaration() instanceof ClassDescriptor ? + PlatformIcons.METHOD_ICON : JetIcons.FUNCTION; } if (descriptor instanceof ClassDescriptor) { switch (((ClassDescriptor)descriptor).getKind()) { @@ -97,9 +98,20 @@ public final class JetDescriptorIconProvider { return null; } } + if (descriptor instanceof ValueParameterDescriptor) { + return JetIcons.PARAMETER; + } + + if (descriptor instanceof LocalVariableDescriptor) { + return ((LocalVariableDescriptor)descriptor).isVar() ? JetIcons.VAR : JetIcons.VAL; + } if (descriptor instanceof PropertyDescriptor) { - return ((PropertyDescriptor)descriptor).isVar() ? JetIcons.VAR : JetIcons.VAL; + return ((PropertyDescriptor)descriptor).isVar() ? JetIcons.FIELD_VAR : JetIcons.FIELD_VAL; + } + + if (descriptor instanceof TypeParameterDescriptor) { + return PlatformIcons.CLASS_ICON; } LOG.warn("No icon for descriptor: " + descriptor); diff --git a/idea/src/org/jetbrains/jet/plugin/JetIconProvider.java b/idea/src/org/jetbrains/jet/plugin/JetIconProvider.java index 970a9f2f58a..a237db389ea 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetIconProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/JetIconProvider.java @@ -64,7 +64,7 @@ public class JetIconProvider extends IconProvider { } if (psiElement instanceof JetNamedFunction) { return PsiTreeUtil.getParentOfType(psiElement, JetNamedDeclaration.class) instanceof JetClass - ? JetIcons.LAMBDA + ? PlatformIcons.METHOD_ICON : JetIcons.FUNCTION; } if (psiElement instanceof JetClass) { @@ -90,14 +90,14 @@ public class JetIconProvider extends IconProvider { if (parameter.getValOrVarNode() != null) { JetParameterList parameterList = PsiTreeUtil.getParentOfType(psiElement, JetParameterList.class); if (parameterList != null && parameterList.getParent() instanceof JetClass) { - return parameter.isVarArg() ? JetIcons.VAR : JetIcons.VAL; + return parameter.isMutable() ? JetIcons.FIELD_VAR : JetIcons.FIELD_VAL; } } return JetIcons.PARAMETER; } if (psiElement instanceof JetProperty) { JetProperty property = (JetProperty)psiElement; - return property.isVar() ? JetIcons.VAR : JetIcons.VAL; + return property.isVar() ? JetIcons.FIELD_VAR : JetIcons.FIELD_VAL; } return null; } diff --git a/idea/src/org/jetbrains/jet/plugin/JetIcons.java b/idea/src/org/jetbrains/jet/plugin/JetIcons.java index 79ef34542c1..8e9969cec3f 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetIcons.java +++ b/idea/src/org/jetbrains/jet/plugin/JetIcons.java @@ -34,4 +34,6 @@ public interface JetIcons { Icon VAR = IconLoader.getIcon("/org/jetbrains/jet/plugin/icons/variable.png"); Icon VAL = IconLoader.getIcon("/org/jetbrains/jet/plugin/icons/value.png"); Icon PARAMETER = IconLoader.getIcon("/org/jetbrains/jet/plugin/icons/parameter.png"); + Icon FIELD_VAL = IconLoader.getIcon("/org/jetbrains/jet/plugin/icons/field_value.png"); + Icon FIELD_VAR = IconLoader.getIcon("/org/jetbrains/jet/plugin/icons/field_variable.png"); } From aa4e4623d4be0fe21d434ad3202302322128b472 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Thu, 19 Apr 2012 16:05:39 +0400 Subject: [PATCH 17/20] KT-1630 Do not select automatically completion proposal in definition of lambda parameters #KT-1630 fixed --- .../lang/parsing/JetExpressionParsing.java | 139 +++++++++--------- .../testData/psi/FunctionLiterals_ERR.jet | 4 + .../testData/psi/FunctionLiterals_ERR.txt | 67 ++++++++- idea/src/META-INF/plugin.xml | 1 + .../UnfocusedPossibleFunctionParameter.java | 76 ++++++++++ .../InBeginningOfFunctionLiteral.kt | 4 + .../InBeginningOfFunctionLiteral.kt.after | 4 + .../InBeginningOfFunctionLiteralInBrackets.kt | 4 + ...inningOfFunctionLiteralInBrackets.kt.after | 4 + .../confidence/InBlockOfFunctionLiteral.kt | 4 + .../InBlockOfFunctionLiteral.kt.after | 4 + .../confidence/JetConfidenceTest.java | 19 +++ 12 files changed, 257 insertions(+), 73 deletions(-) create mode 100644 idea/src/org/jetbrains/jet/plugin/completion/confidence/UnfocusedPossibleFunctionParameter.java create mode 100644 idea/testData/completion/confidence/InBeginningOfFunctionLiteral.kt create mode 100644 idea/testData/completion/confidence/InBeginningOfFunctionLiteral.kt.after create mode 100644 idea/testData/completion/confidence/InBeginningOfFunctionLiteralInBrackets.kt create mode 100644 idea/testData/completion/confidence/InBeginningOfFunctionLiteralInBrackets.kt.after create mode 100644 idea/testData/completion/confidence/InBlockOfFunctionLiteral.kt create mode 100644 idea/testData/completion/confidence/InBlockOfFunctionLiteral.kt.after diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java index 22263d12863..50eb3075b84 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java @@ -1128,27 +1128,20 @@ public class JetExpressionParsing extends AbstractJetParsing { // {(a, b) -> ...} { - PsiBuilder.Marker rollbackMarker = mark(); + boolean preferParamsToExpressions = isConfirmedParametersByComma(); + PsiBuilder.Marker rollbackMarker = mark(); parseFunctionLiteralParametersAndType(); - paramsFound = rollbackOrDropAt(rollbackMarker, ARROW); + paramsFound = preferParamsToExpressions ? + rollbackOrDrop(rollbackMarker, ARROW, "An -> is expected", RBRACE) : + rollbackOrDropAt(rollbackMarker, ARROW); } if (!paramsFound) { // If not found, try a typeRef DOT and then LPAR .. RPAR ARROW // {((A) -> B).(x) -> ... } - PsiBuilder.Marker rollbackMarker = mark(); - int lastDot = matchTokenStreamPredicate(new LastBefore(new At(DOT), new AtSet(ARROW, RPAR))); - if (lastDot >= 0) { - createTruncatedBuilder(lastDot).parseTypeRef(); - if (at(DOT)) { - advance(); // DOT - parseFunctionLiteralParametersAndType(); - } - } - - paramsFound = rollbackOrDropAt(rollbackMarker, ARROW); + paramsFound = parseFunctionTypeDotParametersAndType(); } } else { @@ -1157,69 +1150,21 @@ public class JetExpressionParsing extends AbstractJetParsing { // {a -> ...} // {a, b -> ...} PsiBuilder.Marker rollbackMarker = mark(); + boolean preferParamsToExpressions = (lookahead(1) == COMMA); parseFunctionLiteralShorthandParameterList(); parseOptionalFunctionLiteralType(); - paramsFound = rollbackOrDropAt(rollbackMarker, ARROW); + + paramsFound = preferParamsToExpressions ? + rollbackOrDrop(rollbackMarker, ARROW, "An -> is expected", RBRACE) : + rollbackOrDropAt(rollbackMarker, ARROW); } if (!paramsFound && atSet(JetParsing.TYPE_REF_FIRST)) { // Try to parse a type DOT valueParameterList ARROW // {A.(b) -> ...} - PsiBuilder.Marker rollbackMarker = mark(); - int lastDot = matchTokenStreamPredicate(new LastBefore(new At(DOT), new AtSet(ARROW, RBRACE))); - if (lastDot >= 0) { // There is a receiver type - createTruncatedBuilder(lastDot).parseTypeRef(); - } - - if (at(DOT)) { - advance(); // DOT - parseFunctionLiteralParametersAndType(); - paramsFound = rollbackOrDropAt(rollbackMarker, ARROW); - } - else { - rollbackMarker.rollbackTo(); - } + paramsFound = parseFunctionTypeDotParametersAndType(); } -// int doubleArrowPos = matchTokenStreamPredicate(new FirstBefore(new At(ARROW), new At(RBRACE)) { -// @Override -// public boolean isTopLevel(int openAngleBrackets, int openBrackets, int openBraces, int openParentheses) { -// return openBraces == 0; -// } -// }); -// -// boolean doubleArrowPresent = doubleArrowPos >= 0; -// if (doubleArrowPresent) { -// boolean dontExpectParameters = false; -// -// int lastDot = matchTokenStreamPredicate(new LastBefore(new At(DOT), new AtOffset(doubleArrowPos))); -// if (lastDot >= 0) { // There is a receiver type -// createTruncatedBuilder(lastDot).parseTypeRef(); -// -// expect(DOT, "Expecting '.'"); -// -// if (!at(LPAR)) { -// int firstLParPos = matchTokenStreamPredicate(new FirstBefore(new At(LPAR), new AtOffset(doubleArrowPos))); -// -// if (firstLParPos >= 0) { -// errorUntilOffset("Expecting '('", firstLParPos); -// } else { -// errorUntilOffset("To specify a receiver type, use the full notation: {ReceiverType.(parameters) [: ReturnType] -> ...}", -// doubleArrowPos); -// dontExpectParameters = true; -// } -// } -// -// } -// -// if (at(LPAR)) { -// parseFunctionLiteralParametersAndType(); -// } -// else if (!dontExpectParameters) { -// parseFunctionLiteralShorthandParameterList(); -// } -// -// expectNoAdvance(ARROW, "Expecting '->'"); -// } } + if (!paramsFound) { if (preferBlock) { literal.drop(); @@ -1231,6 +1176,7 @@ public class JetExpressionParsing extends AbstractJetParsing { return; } } + PsiBuilder.Marker body = mark(); parseStatements(); body.done(BLOCK); @@ -1252,6 +1198,25 @@ public class JetExpressionParsing extends AbstractJetParsing { return false; } + private boolean rollbackOrDrop(PsiBuilder.Marker rollbackMarker, + JetToken expected, String expectMessage, + IElementType validForDrop) { + if (at(expected)) { + advance(); // dropAt + rollbackMarker.drop(); + return true; + } + else if (at(validForDrop)) { + rollbackMarker.drop(); + expect(expected, expectMessage); + return true; + } + + rollbackMarker.rollbackTo(); + return false; + } + + /* * SimpleName{,} */ @@ -1289,9 +1254,45 @@ public class JetExpressionParsing extends AbstractJetParsing { parameterList.done(VALUE_PARAMETER_LIST); } + // Check that position is followed by top level comma. It can't be expression and we want it be + // parsed as parameters in function literal + private boolean isConfirmedParametersByComma() { + assert _at(LPAR); + PsiBuilder.Marker lparMarker = mark(); + advance(); // LPAR + int comma = matchTokenStreamPredicate(new FirstBefore(new At(COMMA), new AtSet(ARROW, RPAR))); + lparMarker.rollbackTo(); + return comma > 0; + } + + private boolean parseFunctionTypeDotParametersAndType() { + PsiBuilder.Marker rollbackMarker = mark(); + + // True when it's confirmed that body of literal can't be simple expressions and we prefer to parse + // it to function params if possible. + boolean preferParamsToExpressions = false; + + int lastDot = matchTokenStreamPredicate(new LastBefore(new At(DOT), new AtSet(ARROW, RPAR))); + if (lastDot >= 0) { + createTruncatedBuilder(lastDot).parseTypeRef(); + if (at(DOT)) { + advance(); // DOT + + if (at(LPAR)) { + preferParamsToExpressions = isConfirmedParametersByComma(); + } + + parseFunctionLiteralParametersAndType(); + } + } + + return preferParamsToExpressions ? + rollbackOrDrop(rollbackMarker, ARROW, "An -> is expected", RBRACE) : + rollbackOrDropAt(rollbackMarker, ARROW); + } + private void parseFunctionLiteralParametersAndType() { parseFunctionLiteralParameterList(); - parseOptionalFunctionLiteralType(); } diff --git a/compiler/testData/psi/FunctionLiterals_ERR.jet b/compiler/testData/psi/FunctionLiterals_ERR.jet index d275d6711a6..e3d82032282 100644 --- a/compiler/testData/psi/FunctionLiterals_ERR.jet +++ b/compiler/testData/psi/FunctionLiterals_ERR.jet @@ -15,4 +15,8 @@ fun foo() { {a : b -> f} {T.a : b -> f} + + {(a, b) } + {T.(a, b) } + {a, } } \ No newline at end of file diff --git a/compiler/testData/psi/FunctionLiterals_ERR.txt b/compiler/testData/psi/FunctionLiterals_ERR.txt index baa260581ae..3f4b7b3bb28 100644 --- a/compiler/testData/psi/FunctionLiterals_ERR.txt +++ b/compiler/testData/psi/FunctionLiterals_ERR.txt @@ -326,7 +326,66 @@ JetFile: FunctionLiterals_ERR.jet REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('f') PsiElement(RBRACE)('}') - PsiWhiteSpace('\n') - PsiElement(RBRACE)('}') - PsiErrorElement:Expecting '}' - \ No newline at end of file + PsiWhiteSpace('\n\n ') + FUNCTION_LITERAL_EXPRESSION + FUNCTION_LITERAL + PsiElement(LBRACE)('{') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('a') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('b') + PsiElement(RPAR)(')') + PsiErrorElement:An -> is expected + + PsiWhiteSpace(' ') + BLOCK + + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + FUNCTION_LITERAL_EXPRESSION + FUNCTION_LITERAL + PsiElement(LBRACE)('{') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiElement(DOT)('.') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('a') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('b') + PsiElement(RPAR)(')') + PsiErrorElement:An -> is expected + + PsiWhiteSpace(' ') + BLOCK + + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + FUNCTION_LITERAL_EXPRESSION + FUNCTION_LITERAL + PsiElement(LBRACE)('{') + VALUE_PARAMETER_LIST + VALUE_PARAMETER + PsiElement(IDENTIFIER)('a') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiErrorElement:Expecting parameter name + PsiElement(RBRACE)('}') + PsiErrorElement:Expecting '->' or ',' + + PsiWhiteSpace('\n') + BLOCK + + PsiElement(RBRACE)('}') + PsiErrorElement:Expecting '}' + \ No newline at end of file diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 00f43bf7d8d..78f27b2f6f7 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -109,6 +109,7 @@ + diff --git a/idea/src/org/jetbrains/jet/plugin/completion/confidence/UnfocusedPossibleFunctionParameter.java b/idea/src/org/jetbrains/jet/plugin/completion/confidence/UnfocusedPossibleFunctionParameter.java new file mode 100644 index 00000000000..7cc77460e6c --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/completion/confidence/UnfocusedPossibleFunctionParameter.java @@ -0,0 +1,76 @@ +/* + * Copyright 2010-2012 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.completion.confidence; + +import com.intellij.codeInsight.completion.CompletionConfidence; +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.ThreeState; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.*; + +/** + * @author Nikolay Krasko + */ +public class UnfocusedPossibleFunctionParameter extends CompletionConfidence { + @NotNull + @Override + public ThreeState shouldFocusLookup(@NotNull CompletionParameters parameters) { + // 1. Do not automatically insert completion for first reference expression in block inside + // function literal if it has no parameters yet. + + // 2. The same but for the case when first expression is additionally surrounded with brackets + + PsiElement position = parameters.getPosition(); + JetFunctionLiteralExpression functionLiteral = PsiTreeUtil.getParentOfType( + position, JetFunctionLiteralExpression.class); + + if (functionLiteral != null) { + PsiElement expectedReference = position.getParent(); + if (expectedReference instanceof JetSimpleNameExpression) { + if (PsiTreeUtil.findChildOfType(functionLiteral, JetParameterList.class) == null) { + { + // 1. + PsiElement expectedBlock = expectedReference.getParent(); + if (expectedBlock instanceof JetBlockExpression) { + if (expectedReference.getPrevSibling() == null) { + return ThreeState.NO; + } + } + } + + { + // 2. + PsiElement expectedParenthesized = expectedReference.getParent(); + if (expectedParenthesized instanceof JetParenthesizedExpression) { + PsiElement expectedBlock = expectedParenthesized.getParent(); + if (expectedBlock instanceof JetBlockExpression) { + if (expectedParenthesized.getPrevSibling() == null) { + return ThreeState.NO; + } + } + } + } + } + } + } + + return ThreeState.UNSURE; + } +} + diff --git a/idea/testData/completion/confidence/InBeginningOfFunctionLiteral.kt b/idea/testData/completion/confidence/InBeginningOfFunctionLiteral.kt new file mode 100644 index 00000000000..03898c0f8b1 --- /dev/null +++ b/idea/testData/completion/confidence/InBeginningOfFunctionLiteral.kt @@ -0,0 +1,4 @@ +fun main(args : Array) { + val mmm = 12 + val t = { } +} \ No newline at end of file diff --git a/idea/testData/completion/confidence/InBeginningOfFunctionLiteral.kt.after b/idea/testData/completion/confidence/InBeginningOfFunctionLiteral.kt.after new file mode 100644 index 00000000000..c1079d37611 --- /dev/null +++ b/idea/testData/completion/confidence/InBeginningOfFunctionLiteral.kt.after @@ -0,0 +1,4 @@ +fun main(args : Array) { + val mmm = 12 + val t = { mm } +} \ No newline at end of file diff --git a/idea/testData/completion/confidence/InBeginningOfFunctionLiteralInBrackets.kt b/idea/testData/completion/confidence/InBeginningOfFunctionLiteralInBrackets.kt new file mode 100644 index 00000000000..0fcec1593b2 --- /dev/null +++ b/idea/testData/completion/confidence/InBeginningOfFunctionLiteralInBrackets.kt @@ -0,0 +1,4 @@ +fun main(args : Array) { + val mmm = 12 + val t = { () } +} \ No newline at end of file diff --git a/idea/testData/completion/confidence/InBeginningOfFunctionLiteralInBrackets.kt.after b/idea/testData/completion/confidence/InBeginningOfFunctionLiteralInBrackets.kt.after new file mode 100644 index 00000000000..34d71fc9fe5 --- /dev/null +++ b/idea/testData/completion/confidence/InBeginningOfFunctionLiteralInBrackets.kt.after @@ -0,0 +1,4 @@ +fun main(args : Array) { + val mmm = 12 + val t = { (mm ) } +} \ No newline at end of file diff --git a/idea/testData/completion/confidence/InBlockOfFunctionLiteral.kt b/idea/testData/completion/confidence/InBlockOfFunctionLiteral.kt new file mode 100644 index 00000000000..f438d237441 --- /dev/null +++ b/idea/testData/completion/confidence/InBlockOfFunctionLiteral.kt @@ -0,0 +1,4 @@ +fun main(args : Array) { + val mmm = 12 + val t = { i -> } +} \ No newline at end of file diff --git a/idea/testData/completion/confidence/InBlockOfFunctionLiteral.kt.after b/idea/testData/completion/confidence/InBlockOfFunctionLiteral.kt.after new file mode 100644 index 00000000000..b541c7e8f9f --- /dev/null +++ b/idea/testData/completion/confidence/InBlockOfFunctionLiteral.kt.after @@ -0,0 +1,4 @@ +fun main(args : Array) { + val mmm = 12 + val t = { i -> mmm } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/completion/confidence/JetConfidenceTest.java b/idea/tests/org/jetbrains/jet/completion/confidence/JetConfidenceTest.java index ec19983e491..9c6cd87ab9a 100644 --- a/idea/tests/org/jetbrains/jet/completion/confidence/JetConfidenceTest.java +++ b/idea/tests/org/jetbrains/jet/completion/confidence/JetConfidenceTest.java @@ -16,6 +16,8 @@ package org.jetbrains.jet.completion.confidence; +import com.intellij.codeInsight.completion.CodeCompletionHandlerBase; +import com.intellij.codeInsight.completion.CompletionType; import com.intellij.codeInsight.completion.LightCompletionTestCase; import com.intellij.openapi.projectRoots.JavaSdk; import com.intellij.openapi.projectRoots.Sdk; @@ -37,6 +39,18 @@ public class JetConfidenceTest extends LightCompletionTestCase { doTest("pub"); } + public void testInBeginningOfFunctionLiteral() { + doTest("mm"); + } + + public void testInBeginningOfFunctionLiteralInBrackets() { + doTest("mm"); + } + + public void testInBlockOfFunctionLiteral() { + doTest("mm"); + } + protected void doTest(String completionActivateType) { configureByFile(getBeforeFileName()); type(completionActivateType + " "); @@ -60,4 +74,9 @@ public class JetConfidenceTest extends LightCompletionTestCase { protected Sdk getProjectJDK() { return JavaSdk.getInstance().createJdk("JDK", SystemUtils.getJavaHome().getAbsolutePath()); } + + @Override + protected void complete() { + new CodeCompletionHandlerBase(CompletionType.BASIC, false, true, true).invokeCompletion(getProject(), getEditor(), 0, false); + } } \ No newline at end of file From b47d37094e982edbbae643fb71a9e40deb890091 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Thu, 19 Apr 2012 16:41:34 +0400 Subject: [PATCH 18/20] properly report exception if analyze failed #KT-1831 Fixed --- .../compiler/KotlinToJVMBytecodeCompiler.java | 2 ++ .../resolve/java/AnalyzerFacadeForJVM.java | 3 +- .../jet/analyzer/AnalyzeExhaust.java | 31 +++++++++++++++++-- .../jetbrains/jet/asJava/JetLightClass.java | 4 +++ .../jet/codegen/CodegenTestCase.java | 1 + .../jet/codegen/GenerationUtils.java | 1 + .../plugin/debugger/JetPositionManager.java | 1 + .../codewindow/BytecodeToolwindow.java | 12 +++++-- .../project/AnalyzerFacadeWithCache.java | 2 +- .../project/JSAnalyzerFacadeForIDEA.java | 4 +-- 10 files changed, 51 insertions(+), 10 deletions(-) diff --git a/compiler/cli/src/org/jetbrains/jet/compiler/KotlinToJVMBytecodeCompiler.java b/compiler/cli/src/org/jetbrains/jet/compiler/KotlinToJVMBytecodeCompiler.java index 51557493b91..ecc239820ad 100644 --- a/compiler/cli/src/org/jetbrains/jet/compiler/KotlinToJVMBytecodeCompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/compiler/KotlinToJVMBytecodeCompiler.java @@ -71,6 +71,8 @@ public class KotlinToJVMBytecodeCompiler { return null; } + exhaust.throwIfError(); + return generate(environment, dependencies, messageCollector, exhaust, stubs); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacadeForJVM.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacadeForJVM.java index 8b07dbc02a6..05fef231d78 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacadeForJVM.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacadeForJVM.java @@ -96,7 +96,8 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade { injector.getTopDownAnalyzer().analyzeFiles(files); - return new AnalyzeExhaust(bindingTraceContext.getBindingContext(), JetStandardLibrary.getInstance()); + + return AnalyzeExhaust.success(bindingTraceContext.getBindingContext(), JetStandardLibrary.getInstance()); } public static AnalyzeExhaust shallowAnalyzeFiles(Collection files, diff --git a/compiler/frontend/src/org/jetbrains/jet/analyzer/AnalyzeExhaust.java b/compiler/frontend/src/org/jetbrains/jet/analyzer/AnalyzeExhaust.java index 3a2a9af1ef9..4c2950bfb42 100644 --- a/compiler/frontend/src/org/jetbrains/jet/analyzer/AnalyzeExhaust.java +++ b/compiler/frontend/src/org/jetbrains/jet/analyzer/AnalyzeExhaust.java @@ -27,12 +27,22 @@ import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; public class AnalyzeExhaust { @NotNull private final BindingContext bindingContext; - @Nullable private final JetStandardLibrary standardLibrary; + private final Throwable error; - public AnalyzeExhaust(@NotNull BindingContext bindingContext, @Nullable JetStandardLibrary standardLibrary) { + private AnalyzeExhaust(@NotNull BindingContext bindingContext, + @Nullable JetStandardLibrary standardLibrary, @Nullable Throwable error) { this.bindingContext = bindingContext; this.standardLibrary = standardLibrary; + this.error = error; + } + + public static AnalyzeExhaust success(@NotNull BindingContext bindingContext, @NotNull JetStandardLibrary standardLibrary) { + return new AnalyzeExhaust(bindingContext, standardLibrary, null); + } + + public static AnalyzeExhaust error(@NotNull BindingContext bindingContext, @NotNull Throwable error) { + return new AnalyzeExhaust(bindingContext, null, error); } @NotNull @@ -40,8 +50,23 @@ public class AnalyzeExhaust { return bindingContext; } - @Nullable + @NotNull public JetStandardLibrary getStandardLibrary() { return standardLibrary; } + + @NotNull + public Throwable getError() { + return error; + } + + public boolean isError() { + return error != null; + } + + public void throwIfError() { + if (isError()) { + throw new IllegalStateException("failed to analyze: " + error, error); + } + } } diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java index 8a89bb36ab0..0108405be00 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java @@ -165,6 +165,10 @@ public class JetLightClass extends AbstractLightClass implements JetJavaMirrorMa // TODO: wrong environment // stepan.koltsov@ 2012-04-09 CompilerSpecialMode.REGULAR, CompilerDependencies.compilerDependenciesForProduction(CompilerSpecialMode.REGULAR)); + if (context.isError()) { + throw new IllegalStateException("failed to analyze: " + context.getError(), context.getError()); + } + final GenerationState state = new GenerationState(project, builderFactory, context, Collections.singletonList(file)) { @Override protected void generateNamespace(JetFile namespace) { diff --git a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java index 842f18efc63..c9f64026018 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java +++ b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java @@ -128,6 +128,7 @@ public abstract class CodegenTestCase extends JetLiteFixture { final AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors( myFile, JetControlFlowDataTraceFactory.EMPTY, CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.REGULAR)); + analyzeExhaust.throwIfError(); GenerationState state = new GenerationState(getProject(), classBuilderFactory, analyzeExhaust, Collections.singletonList(myFile)); state.compileCorrectFiles(CompilationErrorHandler.THROW_EXCEPTION); return state; diff --git a/compiler/tests/org/jetbrains/jet/codegen/GenerationUtils.java b/compiler/tests/org/jetbrains/jet/codegen/GenerationUtils.java index e7829724525..63f3b2c796c 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/GenerationUtils.java +++ b/compiler/tests/org/jetbrains/jet/codegen/GenerationUtils.java @@ -39,6 +39,7 @@ public class GenerationUtils { final AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors( psiFile, JetControlFlowDataTraceFactory.EMPTY, CompileCompilerDependenciesTest.compilerDependenciesForTests(compilerSpecialMode)); + analyzeExhaust.throwIfError(); GenerationState state = new GenerationState(psiFile.getProject(), ClassBuilderFactories.binaries(false), analyzeExhaust, Collections.singletonList(psiFile)); state.compileCorrectFiles(CompilationErrorHandler.THROW_EXCEPTION); return state; diff --git a/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java b/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java index 7b53f454aa2..5c2f3d532e5 100644 --- a/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java +++ b/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java @@ -155,6 +155,7 @@ public class JetPositionManager implements PositionManager { return mapper; } final AnalyzeExhaust analyzeExhaust = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file); + analyzeExhaust.throwIfError(); JetTypeMapper typeMapper = new InjectorForJetTypeMapper( analyzeExhaust.getStandardLibrary(), analyzeExhaust.getBindingContext(), Collections.singletonList(file)).getJetTypeMapper(); myTypeMappers.put(file, typeMapper); diff --git a/idea/src/org/jetbrains/jet/plugin/internal/codewindow/BytecodeToolwindow.java b/idea/src/org/jetbrains/jet/plugin/internal/codewindow/BytecodeToolwindow.java index b7bfe2551a2..81c51834404 100644 --- a/idea/src/org/jetbrains/jet/plugin/internal/codewindow/BytecodeToolwindow.java +++ b/idea/src/org/jetbrains/jet/plugin/internal/codewindow/BytecodeToolwindow.java @@ -206,13 +206,14 @@ public class BytecodeToolwindow extends JPanel implements Disposable { try { AnalyzeExhaust binding = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file); // AnalyzingUtils.throwExceptionOnErrors(binding); + if (binding.isError()) { + return printStackTraceToString(binding.getError()); + } state = new GenerationState(myProject, ClassBuilderFactories.TEXT, binding, Collections.singletonList(file)); state.compileCorrectFiles(CompilationErrorHandler.THROW_EXCEPTION); } catch (Exception e) { - StringWriter out = new StringWriter(1024); - e.printStackTrace(new PrintWriter(out)); - return out.toString().replaceAll("\r", ""); + return printStackTraceToString(e); } @@ -229,6 +230,11 @@ public class BytecodeToolwindow extends JPanel implements Disposable { return answer.toString(); } + private static String printStackTraceToString(Throwable e) {StringWriter out = new StringWriter(1024); + e.printStackTrace(new PrintWriter(out)); + return out.toString().replaceAll("\r", ""); + } + @Override public void dispose() { EditorFactory.getInstance().releaseEditor(myEditor); diff --git a/idea/src/org/jetbrains/jet/plugin/project/AnalyzerFacadeWithCache.java b/idea/src/org/jetbrains/jet/plugin/project/AnalyzerFacadeWithCache.java index c5ce3144984..fac916c618c 100644 --- a/idea/src/org/jetbrains/jet/plugin/project/AnalyzerFacadeWithCache.java +++ b/idea/src/org/jetbrains/jet/plugin/project/AnalyzerFacadeWithCache.java @@ -96,7 +96,7 @@ public final class AnalyzerFacadeWithCache { private Result emptyExhaustWithDiagnosticOnFile(Throwable e) { BindingTraceContext bindingTraceContext = new BindingTraceContext(); bindingTraceContext.report(Errors.EXCEPTION_WHILE_ANALYZING.on(file, e)); - AnalyzeExhaust analyzeExhaust = new AnalyzeExhaust(bindingTraceContext.getBindingContext(), null); + AnalyzeExhaust analyzeExhaust = AnalyzeExhaust.error(bindingTraceContext.getBindingContext(), e); return new Result(analyzeExhaust, PsiModificationTracker.MODIFICATION_COUNT); } }, false); diff --git a/idea/src/org/jetbrains/jet/plugin/project/JSAnalyzerFacadeForIDEA.java b/idea/src/org/jetbrains/jet/plugin/project/JSAnalyzerFacadeForIDEA.java index a9b0292b39f..80976459e39 100644 --- a/idea/src/org/jetbrains/jet/plugin/project/JSAnalyzerFacadeForIDEA.java +++ b/idea/src/org/jetbrains/jet/plugin/project/JSAnalyzerFacadeForIDEA.java @@ -47,6 +47,6 @@ public enum JSAnalyzerFacadeForIDEA implements AnalyzerFacade { @NotNull Predicate filesToAnalyzeCompletely, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) { BindingContext context = AnalyzerFacadeForJS.analyzeFiles(files, new IDEAConfig(project)); - return new AnalyzeExhaust(context, JetStandardLibrary.getInstance()); + return AnalyzeExhaust.success(context, JetStandardLibrary.getInstance()); } -} \ No newline at end of file +} From 9bfcc017b2f059bc4102440156fd03547612c25c Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Thu, 19 Apr 2012 16:41:39 +0400 Subject: [PATCH 19/20] use proper replace --- .../jet/plugin/internal/codewindow/BytecodeToolwindow.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/idea/src/org/jetbrains/jet/plugin/internal/codewindow/BytecodeToolwindow.java b/idea/src/org/jetbrains/jet/plugin/internal/codewindow/BytecodeToolwindow.java index 81c51834404..9ea5583e1b3 100644 --- a/idea/src/org/jetbrains/jet/plugin/internal/codewindow/BytecodeToolwindow.java +++ b/idea/src/org/jetbrains/jet/plugin/internal/codewindow/BytecodeToolwindow.java @@ -232,7 +232,7 @@ public class BytecodeToolwindow extends JPanel implements Disposable { private static String printStackTraceToString(Throwable e) {StringWriter out = new StringWriter(1024); e.printStackTrace(new PrintWriter(out)); - return out.toString().replaceAll("\r", ""); + return out.toString().replace("\r", ""); } @Override From 4953be7f6f2eb9111dfc684342fc942e60d2fff5 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Thu, 19 Apr 2012 17:09:16 +0400 Subject: [PATCH 20/20] KT-1786 IDEA complains about toolwindow icon size #KT-1786 fixed --- .../jetbrains/jet/plugin/icons/kotlin13x13.png | Bin 0 -> 521 bytes idea/src/META-INF/plugin.xml | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 idea/resources/org/jetbrains/jet/plugin/icons/kotlin13x13.png diff --git a/idea/resources/org/jetbrains/jet/plugin/icons/kotlin13x13.png b/idea/resources/org/jetbrains/jet/plugin/icons/kotlin13x13.png new file mode 100644 index 0000000000000000000000000000000000000000..2510d022cc8514035a0aa7e99091d295ddd5b6d0 GIT binary patch literal 521 zcmV+k0`~ohP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv0004aNkliR+#Ur0>2>cdm z8kgE3NS2&5zTChCUh)3rjl1PCyC(F^w>t^mDuOi}30-2R!JIhKWr>>~osOPcwMJR@ z=OP#G9GV%T;j4nmG6EZ#