diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java index 83de1aa49b1..46e5b9e5472 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java @@ -1,6 +1,7 @@ package org.jetbrains.jet.codegen; import org.jetbrains.jet.lang.psi.JetNamespace; +import org.jetbrains.jet.lang.psi.JetPsiUtil; import java.util.*; @@ -31,7 +32,7 @@ public class ClassFileFactory { NamespaceCodegen forNamespace(JetNamespace namespace) { assert !isDone : "Already done!"; - String fqName = CodegenUtil.getFQName(namespace); + String fqName = JetPsiUtil.getFQName(namespace); NamespaceCodegen codegen = ns2codegen.get(fqName); if (codegen == null) { final ClassBuilder builder = newVisitor(NamespaceCodegen.getJVMClassName(fqName) + ".class"); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java index e597e5967aa..53af0cdc730 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java @@ -1,16 +1,13 @@ package org.jetbrains.jet.codegen; -import com.intellij.psi.util.PsiTreeUtil; import gnu.trove.THashSet; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; -import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.calls.ExpressionAsFunctionDescriptor; import org.jetbrains.jet.lang.types.JetStandardClasses; import org.jetbrains.jet.lang.types.JetType; import java.util.Collections; -import java.util.Iterator; import java.util.List; import java.util.Set; @@ -108,40 +105,6 @@ public class CodegenUtil { return hasTypeInfoField(outerClassDescriptor.getDefaultType()); } - public static String getFQName(JetNamespace jetNamespace) { - JetNamespace parent = PsiTreeUtil.getParentOfType(jetNamespace, JetNamespace.class); - if (parent != null) { - String parentFQName = getFQName(parent); - if (parentFQName.length() > 0) { - return parentFQName + "." + getFQName(jetNamespace.getHeader()); - } - } - return getFQName(jetNamespace.getHeader()); // TODO: Must include module root namespace - } - - private static String getFQName(JetNamespaceHeader header) { - StringBuilder builder = new StringBuilder(); - for (Iterator iterator = header.getParentNamespaceNames().iterator(); iterator.hasNext(); ) { - JetSimpleNameExpression nameExpression = iterator.next(); - builder.append(nameExpression.getReferencedName()); - builder.append("."); - } -// PsiElement nameIdentifier = header.getNameIdentifier(); - builder.append(header.getName()); - return builder.toString(); - } - - public static String getFQName(JetClass jetClass) { - JetNamedDeclaration parent = PsiTreeUtil.getParentOfType(jetClass, JetNamespace.class, JetClass.class); - if (parent instanceof JetNamespace) { - return getFQName(((JetNamespace) parent)) + "." + jetClass.getName(); - } - if (parent instanceof JetClass) { - return getFQName(((JetClass) parent)) + "." + jetClass.getName(); - } - return jetClass.getName(); - } - public static FunctionDescriptor createInvoke(ExpressionAsFunctionDescriptor fd) { int arity = fd.getValueParameters().size(); FunctionDescriptorImpl invokeDescriptor = new FunctionDescriptorImpl( diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 4f80d963954..e40e22d5a47 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -801,7 +801,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { JetType defaultType = descriptor.getDefaultType(); if(CodegenUtil.hasTypeInfoField(defaultType)) { if(!CodegenUtil.hasDerivedTypeInfoField(defaultType, true)) { - v.newField(myClass, Opcodes.ACC_PRIVATE, "$typeInfo", "Ljet/typeinfo/TypeInfo;", null, null); + v.newField(myClass, Opcodes.ACC_PROTECTED, "$typeInfo", "Ljet/typeinfo/TypeInfo;", null, null); MethodVisitor mv = v.newMethod(myClass, Opcodes.ACC_PUBLIC, "getTypeInfo", "()Ljet/typeinfo/TypeInfo;", null, null); InstructionAdapter iv = null; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index d598ccfed5a..8ed9283d6f0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -629,7 +629,7 @@ public class JetTypeMapper { String baseName; if (container instanceof JetNamespace) { - baseName = NamespaceCodegen.getJVMClassName(CodegenUtil.getFQName(((JetNamespace) container))); + baseName = NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(((JetNamespace) container))); } else { ClassDescriptor aClass = bindingContext.get(BindingContext.CLASS, container); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/SignatureUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/SignatureUtil.java index 72d2ae08868..b8ee1a1c445 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/SignatureUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/SignatureUtil.java @@ -45,8 +45,9 @@ public class SignatureUtil { } else { sb.append("T"); - sb.append(descriptor.getContainingDeclaration().getName()); - sb.append(";"); + JetType defaultType = ((ClassDescriptor) descriptor.getContainingDeclaration()).getDefaultType(); + Type type = typeMapper.mapType(defaultType, OwnerKind.IMPLEMENTATION); + sb.append(type.getDescriptor()); sb.append(descriptor.getName()); sb.append(";"); } diff --git a/compiler/backend/src/org/jetbrains/jet/compiler/CompileEnvironment.java b/compiler/backend/src/org/jetbrains/jet/compiler/CompileEnvironment.java index ba0f2765822..58b709b60b9 100644 --- a/compiler/backend/src/org/jetbrains/jet/compiler/CompileEnvironment.java +++ b/compiler/backend/src/org/jetbrains/jet/compiler/CompileEnvironment.java @@ -5,9 +5,6 @@ import com.intellij.openapi.application.PathManager; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.CharsetToolkit; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiFile; import com.intellij.util.Function; import com.intellij.util.Processor; import jet.modules.IModuleBuilder; @@ -15,16 +12,15 @@ import jet.modules.IModuleSetBuilder; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.JetCoreEnvironment; import org.jetbrains.jet.codegen.ClassFileFactory; -import org.jetbrains.jet.codegen.CodegenUtil; import org.jetbrains.jet.codegen.GeneratedClassLoader; import org.jetbrains.jet.lang.psi.JetNamespace; +import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.plugin.JetMainDetector; import java.io.*; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.jar.*; @@ -332,7 +328,7 @@ public class CompileEnvironment { String mainClass = null; for (JetNamespace namespace : session.getSourceFileNamespaces()) { if (JetMainDetector.hasMain(namespace.getDeclarations())) { - mainClass = CodegenUtil.getFQName(namespace) + ".namespace"; + mainClass = JetPsiUtil.getFQName(namespace) + ".namespace"; break; } } 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 73a380e8260..cf154895c99 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,14 @@ public class JavaDescriptorResolver { @NotNull public ClassDescriptor resolveClass(@NotNull PsiClass psiClass) { String qualifiedName = psiClass.getQualifiedName(); + + // First, let's check that this is a real Java class, not a Java's view on a Kotlin class: + ClassDescriptor kotlinClassDescriptor = semanticServices.getKotlinClassDescriptor(qualifiedName); + if (kotlinClassDescriptor != null) { + return kotlinClassDescriptor; + } + + // Not let's take a descriptor of a Java class ClassDescriptor classDescriptor = classDescriptorCache.get(qualifiedName); if (classDescriptor == null) { classDescriptor = createJavaClassDescriptor(psiClass); @@ -86,6 +94,13 @@ public class JavaDescriptorResolver { @Nullable public ClassDescriptor resolveClass(@NotNull String qualifiedName) { + // First, let's check that this is a real Java class, not a Java's view on a Kotlin class: + ClassDescriptor kotlinClassDescriptor = semanticServices.getKotlinClassDescriptor(qualifiedName); + if (kotlinClassDescriptor != null) { + return kotlinClassDescriptor; + } + + // Not let's take a descriptor of a Java class ClassDescriptor classDescriptor = classDescriptorCache.get(qualifiedName); if (classDescriptor == null) { PsiClass psiClass = findClass(qualifiedName); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java index 2763af7e1f4..0f28be38590 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java @@ -5,10 +5,7 @@ import com.intellij.psi.PsiClass; import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiPackage; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; -import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; -import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; -import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.scopes.JetScopeImpl; import java.util.Collection; @@ -44,6 +41,13 @@ public class JavaPackageScope extends JetScopeImpl { @NotNull @Override public Set getFunctions(@NotNull String name) { + // If this package is actually a Kotlin namespace, then we access it through a namespace descriptor, and + // Kotlin functions are already there + NamespaceDescriptor kotlinNamespaceDescriptor = semanticServices.getKotlinNamespaceDescriptor(packageFQN); + if (kotlinNamespaceDescriptor != null) { + return Collections.emptySet(); + } + // TODO: what is GlobalSearchScope PsiClass psiClass = semanticServices.getDescriptorResolver().javaFacade.findClass(getQualifiedName("namespace")); if (psiClass == null) { @@ -54,7 +58,9 @@ public class JavaPackageScope extends JetScopeImpl { return Collections.emptySet(); } + System.out.println(psiClass.getQualifiedName()); return semanticServices.getDescriptorResolver().resolveFunctionGroup(containingDescriptor, psiClass, null, name, true); +// return Collections.emptySet(); } @NotNull @@ -79,6 +85,12 @@ public class JavaPackageScope extends JetScopeImpl { } for (PsiClass psiClass : javaPackage.getClasses()) { + // If this is a Kotlin class, we have already taken it through a containing namespace descriptor + ClassDescriptor kotlinClassDescriptor = semanticServices.getKotlinClassDescriptor(psiClass.getQualifiedName()); + if (kotlinClassDescriptor != null) { + continue; + } + if (psiClass.hasModifierProperty(PsiModifier.PUBLIC)) { allDescriptors.add(descriptorResolver.resolveClass(psiClass)); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaSemanticServices.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaSemanticServices.java index 5560dda971c..c4b9053e3a1 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaSemanticServices.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaSemanticServices.java @@ -2,7 +2,11 @@ package org.jetbrains.jet.lang.resolve.java; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.JetSemanticServices; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTrace; /** @@ -39,4 +43,14 @@ public class JavaSemanticServices { public JetSemanticServices getJetSemanticServices() { return jetSemanticServices; } + + @Nullable + public ClassDescriptor getKotlinClassDescriptor(String qualifiedName) { + return getTrace().get(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR, qualifiedName); + } + + @Nullable + public NamespaceDescriptor getKotlinNamespaceDescriptor(String qualifiedName) { + return getTrace().get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, qualifiedName); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index 3fe1c9f4947..2a7c167d0fb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -8,6 +8,7 @@ import org.jetbrains.jet.lexer.JetTokens; import java.util.Collection; import java.util.HashSet; +import java.util.Iterator; import java.util.Set; /** @@ -103,4 +104,38 @@ public class JetPsiUtil { return unquoteIdentifier(quoted); } } + + public static String getFQName(JetNamespace jetNamespace) { + JetNamespace parent = PsiTreeUtil.getParentOfType(jetNamespace, JetNamespace.class); + if (parent != null) { + String parentFQName = getFQName(parent); + if (parentFQName.length() > 0) { + return parentFQName + "." + getFQName(jetNamespace.getHeader()); + } + } + return getFQName(jetNamespace.getHeader()); // TODO: Must include module root namespace + } + + private static String getFQName(JetNamespaceHeader header) { + StringBuilder builder = new StringBuilder(); + for (Iterator iterator = header.getParentNamespaceNames().iterator(); iterator.hasNext(); ) { + JetSimpleNameExpression nameExpression = iterator.next(); + builder.append(nameExpression.getReferencedName()); + builder.append("."); + } +// PsiElement nameIdentifier = header.getNameIdentifier(); + builder.append(header.getName()); + return builder.toString(); + } + + public static String getFQName(JetClass jetClass) { + JetNamedDeclaration parent = PsiTreeUtil.getParentOfType(jetClass, JetNamespace.class, JetClass.class); + if (parent instanceof JetNamespace) { + return getFQName(((JetNamespace) parent)) + "." + jetClass.getName(); + } + if (parent instanceof JetClass) { + return getFQName(((JetClass) parent)) + "." + jetClass.getName(); + } + return jetClass.getName(); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java index 5e8557fd62a..0c6113a8b03 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java @@ -18,6 +18,8 @@ import org.jetbrains.jet.util.slicedmap.*; import java.util.Collection; +import static org.jetbrains.jet.util.slicedmap.RewritePolicy.DO_NOTHING; + /** * @author abreslav */ @@ -26,12 +28,12 @@ public interface BindingContext { WritableSlice> COMPILE_TIME_VALUE = Slices.createSimpleSlice(); WritableSlice TYPE = Slices.createSimpleSlice(); - WritableSlice EXPRESSION_TYPE = new BasicWritableSlice(RewritePolicy.DO_NOTHING); + WritableSlice EXPRESSION_TYPE = new BasicWritableSlice(DO_NOTHING); - WritableSlice REFERENCE_TARGET = new BasicWritableSlice(RewritePolicy.DO_NOTHING); - WritableSlice> RESOLVED_CALL = new BasicWritableSlice>(RewritePolicy.DO_NOTHING); + WritableSlice REFERENCE_TARGET = new BasicWritableSlice(DO_NOTHING); + WritableSlice> RESOLVED_CALL = new BasicWritableSlice>(DO_NOTHING); - WritableSlice>> AMBIGUOUS_REFERENCE_TARGET = new BasicWritableSlice>>(RewritePolicy.DO_NOTHING); + WritableSlice>> AMBIGUOUS_REFERENCE_TARGET = new BasicWritableSlice>>(DO_NOTHING); WritableSlice LOOP_RANGE_ITERATOR = Slices.createSimpleSlice(); WritableSlice LOOP_RANGE_HAS_NEXT = Slices.createSimpleSlice(); @@ -61,7 +63,7 @@ public interface BindingContext { WritableSlice, Boolean> DEFERRED_TYPE = Slices.createCollectiveSetSlice(); - WritableSlice BACKING_FIELD_REQUIRED = new Slices.SetSlice(RewritePolicy.DO_NOTHING) { + WritableSlice BACKING_FIELD_REQUIRED = new Slices.SetSlice(DO_NOTHING) { @Override public Boolean computeValue(SlicedMap map, PropertyDescriptor propertyDescriptor, Boolean backingFieldRequired, boolean valueNotFound) { backingFieldRequired = valueNotFound ? false : backingFieldRequired; @@ -92,7 +94,7 @@ public interface BindingContext { }; WritableSlice IS_INITIALIZED = Slices.createSimpleSetSlice(); - WritableSlice BLOCK = new Slices.SetSlice(RewritePolicy.DO_NOTHING) { + WritableSlice BLOCK = new Slices.SetSlice(DO_NOTHING) { @Override public Boolean computeValue(SlicedMap map, JetFunctionLiteralExpression expression, Boolean isBlock, boolean valueNotFound) { isBlock = valueNotFound ? false : isBlock; @@ -136,6 +138,9 @@ public interface BindingContext { WritableSlice LABEL_TARGET = Slices.sliceBuilder().build(); WritableSlice VALUE_PARAMETER_AS_PROPERTY = Slices.sliceBuilder().build(); + WritableSlice FQNAME_TO_CLASS_DESCRIPTOR = new BasicWritableSlice(DO_NOTHING); + WritableSlice FQNAME_TO_NAMESPACE_DESCRIPTOR = new BasicWritableSlice(DO_NOTHING); + @SuppressWarnings("UnusedDeclaration") @Deprecated // This field is needed only for the side effects of its initializer Void _static_initializer = BasicWritableSlice.initSliceDebugNames(BindingContext.class); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java index 435fed20e44..5bff2b93d31 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -20,7 +20,6 @@ import org.jetbrains.jet.lang.types.TypeConstructor; import org.jetbrains.jet.lang.types.TypeProjection; import org.jetbrains.jet.lang.types.TypeUtils; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; import org.jetbrains.jet.lexer.JetTokens; import java.util.*; @@ -91,6 +90,7 @@ public class TypeHierarchyResolver { @Override public void visitClass(JetClass klass) { MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(context.getTrace(), owner, outerScope, getClassKind(klass)); + context.getTrace().record(FQNAME_TO_CLASS_DESCRIPTOR, JetPsiUtil.getFQName(klass), mutableClassDescriptor); if (klass.hasModifier(JetTokens.ENUM_KEYWORD)) { MutableClassDescriptor classObjectDescriptor = new MutableClassDescriptor(context.getTrace(), mutableClassDescriptor, outerScope, ClassKind.OBJECT); @@ -217,6 +217,7 @@ public class TypeHierarchyResolver { Collections.emptyList(), // TODO: annotations name ); + context.getTrace().record(FQNAME_TO_NAMESPACE_DESCRIPTOR, DescriptorUtils.getFQName(namespaceDescriptor), namespaceDescriptor); WritableScopeImpl scope = new WritableScopeImpl(JetScope.EMPTY, namespaceDescriptor, new TraceBasedRedeclarationHandler(context.getTrace())).setDebugName("Namespace member scope"); scope.changeLockLevel(WritableScope.LockLevel.BOTH); namespaceDescriptor.initialize(scope); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index de1fb006eca..e611247ebe7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -505,7 +505,7 @@ public class CallResolver { } else { tracing.typeInferenceFailed(temporaryTrace, solution.getStatus()); - candidateCall.setStatus(OTHER_ERROR); + candidateCall.setStatus(checkAllValueArguments(scope, tracing, task, candidateCall)); } } else { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java index e6f8263432f..8ea8f233b0c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java @@ -409,6 +409,7 @@ public class ConstraintSystemImpl implements ConstraintSystem { KnownType knownBoundType = (KnownType) upperBound; boolean ok = constraintExpander.isSubtypeOf(jetType, knownBoundType.getType()); if (!ok) { + listener.error("Error while expanding '" + jetType + " :< " + knownBoundType.getType() + "'"); return new Solution().registerError("Mismatch while expanding constraints"); } } diff --git a/compiler/testData/codegen/typeInfo/inheritance.jet b/compiler/testData/codegen/typeInfo/inheritance.jet new file mode 100644 index 00000000000..225bda1f665 --- /dev/null +++ b/compiler/testData/codegen/typeInfo/inheritance.jet @@ -0,0 +1,9 @@ +open class A () { + fun plus(e: T) = B (e) +} + +class B (val e: T) : A() { + fun add() = B (e) +} + +fun box() = if( A().plus("239").add().e == "239" ) "OK" else "fail" \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java index 09f1485d650..30a35b498b8 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java +++ b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java @@ -1,24 +1,17 @@ package org.jetbrains.jet.codegen; -import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.CharsetToolkit; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiFile; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.JetLiteFixture; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetNamespace; +import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.parsing.JetParsingTest; -import org.junit.Assert; -import java.io.File; -import java.io.FilenameFilter; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -99,7 +92,7 @@ public abstract class CodegenTestCase extends JetLiteFixture { GeneratedClassLoader loader = new GeneratedClassLoader(codegens); final JetNamespace namespace = myFile.getRootNamespace(); - String fqName = NamespaceCodegen.getJVMClassName(CodegenUtil.getFQName(namespace)).replace("/", "."); + String fqName = NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(namespace)).replace("/", "."); Class namespaceClass = loader.loadClass(fqName); Method method = namespaceClass.getMethod("box"); return (String) method.invoke(null); @@ -120,7 +113,7 @@ public abstract class CodegenTestCase extends JetLiteFixture { protected Class loadRootNamespaceClass(ClassFileFactory state) { final JetNamespace namespace = myFile.getRootNamespace(); - String fqName = NamespaceCodegen.getJVMClassName(CodegenUtil.getFQName(namespace)).replace("/", "."); + String fqName = NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(namespace)).replace("/", "."); Map classMap = loadAllClasses(state); return classMap.get(fqName); } diff --git a/compiler/tests/org/jetbrains/jet/codegen/TypeInfoTest.java b/compiler/tests/org/jetbrains/jet/codegen/TypeInfoTest.java index 1ce4e56d3c8..85b9dae07d8 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/TypeInfoTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/TypeInfoTest.java @@ -142,5 +142,10 @@ public class TypeInfoTest extends CodegenTestCase { blackBoxFile("typeInfo/inner.jet"); // System.out.println(generateToText()); } + + public void testInheritance() throws Exception { + blackBoxFile("typeInfo/inheritance.jet"); + System.out.println(generateToText()); + } } diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index a42a55fc25b..6fd690eba51 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -59,9 +59,9 @@ - + + diff --git a/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java b/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java index 6f77c9f6f42..69eaa6c40e3 100644 --- a/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java +++ b/idea/src/org/jetbrains/jet/plugin/debugger/JetPositionManager.java @@ -17,7 +17,6 @@ import com.sun.jdi.ReferenceType; import com.sun.jdi.request.ClassPrepareRequest; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.codegen.CodegenUtil; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.NamespaceCodegen; @@ -113,10 +112,10 @@ public class JetPositionManager implements PositionManager { else { JetNamespace namespace = PsiTreeUtil.getParentOfType(sourcePosition.getElementAt(), JetNamespace.class); if (namespace != null) { - names.add(NamespaceCodegen.getJVMClassName(CodegenUtil.getFQName(namespace))); + names.add(NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(namespace))); } else { - names.add(NamespaceCodegen.getJVMClassName(CodegenUtil.getFQName(file.getRootNamespace()))); + names.add(NamespaceCodegen.getJVMClassName(JetPsiUtil.getFQName(file.getRootNamespace()))); } } return names; diff --git a/idea/src/org/jetbrains/jet/plugin/java/JavaElementFinder.java b/idea/src/org/jetbrains/jet/plugin/java/JavaElementFinder.java index 3cfc18e96b0..adf84a87b4c 100644 --- a/idea/src/org/jetbrains/jet/plugin/java/JavaElementFinder.java +++ b/idea/src/org/jetbrains/jet/plugin/java/JavaElementFinder.java @@ -15,11 +15,7 @@ import com.intellij.psi.impl.file.PsiPackageImpl; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.codegen.CodegenUtil; -import org.jetbrains.jet.lang.psi.JetClassOrObject; -import org.jetbrains.jet.lang.psi.JetDeclaration; -import org.jetbrains.jet.lang.psi.JetFile; -import org.jetbrains.jet.lang.psi.JetNamespace; +import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.plugin.JetFileType; import java.util.ArrayList; @@ -52,7 +48,7 @@ public class JavaElementFinder extends PsiElementFinder { final List filesInScope = collectProjectFiles(project, scope); for (JetFile file : filesInScope) { JetNamespace rootNamespace = file.getRootNamespace(); - final String packageName = CodegenUtil.getFQName(rootNamespace); + final String packageName = JetPsiUtil.getFQName(rootNamespace); if (packageName != null && qualifiedName.startsWith(packageName)) { if (qualifiedName.equals(fqn(packageName, "namespace"))) { answer.add(new JetLightClass(psiManager, file, "namespace")); @@ -77,7 +73,7 @@ public class JavaElementFinder extends PsiElementFinder { String packageFQN = psiPackage.getQualifiedName(); for (JetFile psiFile : collectProjectFiles(project, GlobalSearchScope.allScope(project))) { final JetNamespace rootNamespace = psiFile.getRootNamespace(); - if (packageFQN.equals(CodegenUtil.getFQName(rootNamespace))) { + if (packageFQN.equals(JetPsiUtil.getFQName(rootNamespace))) { answer.add("namespace"); for (JetDeclaration declaration : rootNamespace.getDeclarations()) { if (declaration instanceof JetClassOrObject) { @@ -100,7 +96,7 @@ public class JavaElementFinder extends PsiElementFinder { final List psiFiles = collectProjectFiles(project, GlobalSearchScope.allScope(project)); for (JetFile psiFile : psiFiles) { - if (qualifiedName.equals(CodegenUtil.getFQName(psiFile.getRootNamespace()))) { + if (qualifiedName.equals(JetPsiUtil.getFQName(psiFile.getRootNamespace()))) { return new PsiPackageImpl(psiFile.getManager(), qualifiedName); } } @@ -116,7 +112,7 @@ public class JavaElementFinder extends PsiElementFinder { String packageFQN = psiPackage.getQualifiedName(); for (JetFile file : filesInScope) { final JetNamespace rootNamespace = file.getRootNamespace(); - if (packageFQN.equals(CodegenUtil.getFQName(rootNamespace))) { + if (packageFQN.equals(JetPsiUtil.getFQName(rootNamespace))) { answer.add(new JetLightClass(psiManager, file, "namespace")); for (JetDeclaration declaration : rootNamespace.getDeclarations()) { if (declaration instanceof JetClassOrObject) { diff --git a/idea/src/org/jetbrains/jet/plugin/java/JetCodeBlockModificationListener.java b/idea/src/org/jetbrains/jet/plugin/java/JetCodeBlockModificationListener.java new file mode 100644 index 00000000000..dd26ab448c4 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/java/JetCodeBlockModificationListener.java @@ -0,0 +1,112 @@ +/* + * @author max + */ +package org.jetbrains.jet.plugin.java; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiModificationTrackerImpl; +import com.intellij.psi.impl.PsiTreeChangeEventImpl; +import com.intellij.psi.impl.PsiTreeChangePreprocessor; +import com.intellij.psi.util.PsiModificationTracker; +import org.jetbrains.jet.lang.psi.JetBlockExpression; +import org.jetbrains.jet.lang.psi.JetClass; +import org.jetbrains.jet.lang.psi.JetFile; + +public class JetCodeBlockModificationListener implements PsiTreeChangePreprocessor { + private static final Logger LOG = Logger.getInstance("#org.jetbrains.jet.plugin.java.JetCodeBlockModificationListener"); + + private final PsiModificationTrackerImpl myModificationTracker; + + public JetCodeBlockModificationListener(final PsiModificationTracker modificationTracker) { + myModificationTracker = (PsiModificationTrackerImpl) modificationTracker; + } + + @Override + public void treeChanged(final PsiTreeChangeEventImpl event) { + switch (event.getCode()) { + case BEFORE_CHILDREN_CHANGE: + case BEFORE_PROPERTY_CHANGE: + case BEFORE_CHILD_MOVEMENT: + case BEFORE_CHILD_REPLACEMENT: + case BEFORE_CHILD_ADDITION: + case BEFORE_CHILD_REMOVAL: + break; + + case CHILD_ADDED: + case CHILD_REMOVED: + case CHILD_REPLACED: + processChange(event.getParent(), event.getOldChild(), event.getChild()); + break; + + case CHILDREN_CHANGED: + // general childrenChanged() event after each change + if (!event.isGenericChildrenChange()) { + processChange(event.getParent(), event.getParent(), null); + } + break; + + case CHILD_MOVED: + case PROPERTY_CHANGED: + myModificationTracker.incCounter(); + break; + + default: + LOG.error("Unknown code:" + event.getCode()); + break; + } + } + + private void processChange(final PsiElement parent, final PsiElement child1, final PsiElement child2) { + try { + if (!isInsideCodeBlock(parent)) { + if (parent != null && parent.getContainingFile() instanceof JetFile) { + myModificationTracker.incCounter(); + } + else { + myModificationTracker.incOutOfCodeBlockModificationCounter(); + } + return; + } + + if (containsClassesInside(child1) || child2 != child1 && containsClassesInside(child2)) { + myModificationTracker.incCounter(); + } + } catch (PsiInvalidElementAccessException e) { + myModificationTracker.incCounter(); // Shall not happen actually, just a pre-release paranoia + } + } + + private static boolean containsClassesInside(final PsiElement element) { + if (element == null) return false; + if (element instanceof PsiClass) return true; + + PsiElement child = element.getFirstChild(); + while (child != null) { + if (containsClassesInside(child)) return true; + child = child.getNextSibling(); + } + + return false; + } + + private static boolean isInsideCodeBlock(PsiElement element) { + if (element instanceof PsiFileSystemItem) { + return false; + } + + if (element == null || element.getParent() == null) return true; + + PsiElement parent = element; + while (true) { + if (parent instanceof PsiFile || parent instanceof PsiDirectory || parent == null) { + return false; + } + if (parent instanceof JetClass) return false; // anonymous or local class + if (parent instanceof JetBlockExpression) { + return true; + } + parent = parent.getParent(); + } + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/java/JetLightClass.java b/idea/src/org/jetbrains/jet/plugin/java/JetLightClass.java index 561e98b164c..3d992837782 100644 --- a/idea/src/org/jetbrains/jet/plugin/java/JetLightClass.java +++ b/idea/src/org/jetbrains/jet/plugin/java/JetLightClass.java @@ -15,14 +15,18 @@ import com.intellij.psi.impl.java.stubs.impl.PsiJavaFileStubImpl; import com.intellij.psi.impl.light.AbstractLightClass; import com.intellij.psi.stubs.PsiClassHolderFileStub; import com.intellij.psi.stubs.StubElement; +import com.intellij.psi.util.CachedValue; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.util.CachedValuesManager; +import com.intellij.psi.util.PsiModificationTracker; import com.intellij.util.containers.Stack; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.codegen.ClassBuilder; import org.jetbrains.jet.codegen.ClassBuilderFactory; -import org.jetbrains.jet.codegen.CodegenUtil; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetNamespace; +import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade; import org.jetbrains.jet.lang.resolve.java.JetJavaMirrorMarker; @@ -33,7 +37,7 @@ import java.util.List; public class JetLightClass extends AbstractLightClass implements JetJavaMirrorMarker { private static final Logger LOG = Logger.getInstance("#org.jetbrains.jet.plugin.java.JetLightClass"); - private final static Key JAVA_API_STUB = Key.create("JAVA_API_STUB"); + private final static Key> JAVA_API_STUB = Key.create("JAVA_API_STUB"); private final JetFile file; private final String className; @@ -75,20 +79,30 @@ public class JetLightClass extends AbstractLightClass implements JetJavaMirrorMa return null; } - - + + @Override + public String getQualifiedName() { + String fqName = JetPsiUtil.getFQName(file.getRootNamespace()); + return fqName.length() == 0 ? className : fqName + "." + className; + } + private PsiJavaFileStub getStub() { - PsiJavaFileStub answer = file.getUserData(JAVA_API_STUB); + CachedValue answer = file.getUserData(JAVA_API_STUB); if (answer == null) { - answer = calcStub(); + answer = CachedValuesManager.getManager(getProject()).createCachedValue(new CachedValueProvider() { + @Override + public Result compute() { + return Result.create(calcStub(), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT); + } + }, false); file.putUserData(JAVA_API_STUB, answer); } - return answer; + return answer.getValue(); } private PsiJavaFileStub calcStub() { - final PsiJavaFileStubImpl answer = new PsiJavaFileStubImpl(CodegenUtil.getFQName(file.getRootNamespace()), true); + final PsiJavaFileStubImpl answer = new PsiJavaFileStubImpl(JetPsiUtil.getFQName(file.getRootNamespace()), true); final Project project = getProject(); final Stack stubStack = new Stack(); @@ -134,7 +148,7 @@ public class JetLightClass extends AbstractLightClass implements JetJavaMirrorMa finally { final StubElement pop = stubStack.pop(); if (pop != answer) { - LOG.error("Unbalanced stack operations"); + LOG.error("Unbalanced stack operations: " + pop); } } } @@ -148,5 +162,5 @@ public class JetLightClass extends AbstractLightClass implements JetJavaMirrorMa return answer; } - + } diff --git a/idea/src/org/jetbrains/jet/plugin/run/JetRunConfigurationProducer.java b/idea/src/org/jetbrains/jet/plugin/run/JetRunConfigurationProducer.java index 1f852784788..264347faffc 100644 --- a/idea/src/org/jetbrains/jet/plugin/run/JetRunConfigurationProducer.java +++ b/idea/src/org/jetbrains/jet/plugin/run/JetRunConfigurationProducer.java @@ -8,10 +8,10 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; -import org.jetbrains.jet.codegen.CodegenUtil; import org.jetbrains.jet.lang.psi.JetClass; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetNamespace; +import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.plugin.JetMainDetector; /** @@ -34,14 +34,14 @@ public class JetRunConfigurationProducer extends RuntimeConfigurationProducer im JetClass containingClass = (JetClass) location.getParentElement(JetClass.class); if (containingClass != null && JetMainDetector.hasMain(containingClass.getDeclarations())) { mySourceElement = containingClass; - return createConfigurationByQName(location.getModule(), configurationContext, CodegenUtil.getFQName(containingClass)); + return createConfigurationByQName(location.getModule(), configurationContext, JetPsiUtil.getFQName(containingClass)); } PsiFile psiFile = location.getPsiElement().getContainingFile(); if (psiFile instanceof JetFile) { JetNamespace namespace = ((JetFile) psiFile).getRootNamespace(); if (JetMainDetector.hasMain(namespace.getDeclarations())) { mySourceElement = namespace; - String fqName = CodegenUtil.getFQName(namespace); + String fqName = JetPsiUtil.getFQName(namespace); String className = fqName.length() == 0 ? "namespace" : fqName + ".namespace"; return createConfigurationByQName(location.getModule(), configurationContext, className); } diff --git a/stdlib/src/jet/typeinfo/TypeInfo.java b/stdlib/src/jet/typeinfo/TypeInfo.java index fa7abb6afa1..2fb20baa47e 100644 --- a/stdlib/src/jet/typeinfo/TypeInfo.java +++ b/stdlib/src/jet/typeinfo/TypeInfo.java @@ -669,7 +669,9 @@ public abstract class TypeInfo implements JetObject { private TypeInfo parseTypeVar(Signature signature) { TypeInfoVariance variance = parseVariance(); - String klazz = parseName(); + assert string[cur] == 'L'; + cur++; + String klazz = parseName().replace('/','.'); String name = parseName(); boolean nullable = false; if(string[cur] == '?') {