Merge remote-tracking branch 'origin/master' into idea14

Conflicts:
	update_dependencies.xml
This commit is contained in:
Nikolay Krasko
2014-06-27 14:44:05 +04:00
252 changed files with 1663 additions and 1096 deletions
+1 -1
View File
@@ -139,7 +139,7 @@
<echo file="${kotlin-home}/build.txt" message="${build.number}"/> <echo file="${kotlin-home}/build.txt" message="${build.number}"/>
<chmod dir="${kotlin-home}/bin" includes="*" perm="755"/> <chmod dir="${kotlin-home}/bin" excludes="**/*.bat" perm="755"/>
</target> </target>
<target name="compilerSources"> <target name="compilerSources">
@@ -31,7 +31,6 @@ import org.jetbrains.jet.lang.psi.JetModifierListOwner;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.constants.*; import org.jetbrains.jet.lang.resolve.constants.*;
import org.jetbrains.jet.lang.resolve.constants.StringValue;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils; import org.jetbrains.jet.lang.types.TypeUtils;
@@ -174,7 +173,7 @@ public abstract class AnnotationCodegen {
return; return;
} }
boolean isNullableType = JvmCodegenUtil.isNullableType(type); boolean isNullableType = TypeUtils.isNullableType(type);
Class<?> annotationClass = isNullableType ? Nullable.class : NotNull.class; Class<?> annotationClass = isNullableType ? Nullable.class : NotNull.class;
@@ -58,6 +58,7 @@ import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.getType;
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.ABI_VERSION_FIELD_NAME; import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.ABI_VERSION_FIELD_NAME;
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass; import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass;
import static org.jetbrains.jet.lang.resolve.java.mapping.PrimitiveTypesUtil.asmTypeForPrimitive; import static org.jetbrains.jet.lang.resolve.java.mapping.PrimitiveTypesUtil.asmTypeForPrimitive;
import static org.jetbrains.jet.lang.types.TypeUtils.isNullableType;
import static org.jetbrains.org.objectweb.asm.Opcodes.*; import static org.jetbrains.org.objectweb.asm.Opcodes.*;
public class AsmUtil { public class AsmUtil {
@@ -54,6 +54,7 @@ import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.receivers.*; import org.jetbrains.jet.lang.resolve.scopes.receivers.*;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.lexer.JetTokens;
@@ -3506,7 +3507,7 @@ The "returned" value of try expression with no finally is either the last expres
value.put(boxType(value.type), v); value.put(boxType(value.type), v);
if (opToken != JetTokens.AS_SAFE) { if (opToken != JetTokens.AS_SAFE) {
if (!JvmCodegenUtil.isNullableType(rightType)) { if (!TypeUtils.isNullableType(rightType)) {
v.dup(); v.dup();
Label nonnull = new Label(); Label nonnull = new Label();
v.ifnonnull(nonnull); v.ifnonnull(nonnull);
@@ -43,6 +43,7 @@ import org.jetbrains.jet.descriptors.serialization.ProtoBuf;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DeclarationResolver;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil; import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
@@ -838,7 +839,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
iv.anew(thisDescriptorType); iv.anew(thisDescriptorType);
iv.dup(); iv.dup();
ConstructorDescriptor constructor = DescriptorUtils.getConstructorOfDataClass(descriptor); ConstructorDescriptor constructor = DeclarationResolver.getConstructorOfDataClass(descriptor);
assert function.getValueParameters().size() == constructor.getValueParameters().size() : assert function.getValueParameters().size() == constructor.getValueParameters().size() :
"Number of parameters of copy function and constructor are different. " + "Number of parameters of copy function and constructor are different. " +
"Copy: " + function.getValueParameters().size() + ", " + "Copy: " + function.getValueParameters().size() + ", " +
@@ -1124,9 +1125,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
protected void genInitSingleton(ClassDescriptor fieldTypeDescriptor, StackValue.Field field) { protected void genInitSingleton(ClassDescriptor fieldTypeDescriptor, StackValue.Field field) {
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
ConstructorDescriptor constructorDescriptor = DescriptorUtils.getConstructorOfSingletonObject(fieldTypeDescriptor); Collection<ConstructorDescriptor> constructors = fieldTypeDescriptor.getConstructors();
assert constructors.size() == 1 : "Class of singleton object must have only one constructor: " + constructors;
ExpressionCodegen codegen = createOrGetClInitCodegen(); ExpressionCodegen codegen = createOrGetClInitCodegen();
FunctionDescriptor fd = codegen.accessibleFunctionDescriptor(constructorDescriptor); FunctionDescriptor fd = codegen.accessibleFunctionDescriptor(constructors.iterator().next());
generateMethodCallTo(fd, codegen.v); generateMethodCallTo(fd, codegen.v);
field.store(field.type, codegen.v); field.store(field.type, codegen.v);
} }
@@ -16,8 +16,6 @@
package org.jetbrains.jet.codegen; package org.jetbrains.jet.codegen;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.Stack; import com.intellij.util.containers.Stack;
import kotlin.Function1; import kotlin.Function1;
import kotlin.KotlinPackage; import kotlin.KotlinPackage;
@@ -37,7 +35,6 @@ import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil; import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.util.Arrays; import java.util.Arrays;
@@ -193,20 +190,6 @@ public class JvmCodegenUtil {
); );
} }
/**
* A work-around of the generic nullability problem in the type checker
* @return true if a value of this type can be null
*/
public static boolean isNullableType(@NotNull JetType type) {
if (type.isNullable()) {
return true;
}
if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) {
return TypeUtils.hasNullableSuperType(type);
}
return false;
}
public static boolean couldUseDirectAccessToProperty( public static boolean couldUseDirectAccessToProperty(
@NotNull PropertyDescriptor propertyDescriptor, @NotNull PropertyDescriptor propertyDescriptor,
boolean forGetter, boolean forGetter,
@@ -23,17 +23,17 @@ import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.MutablePackageFragmentDescriptor; import org.jetbrains.jet.lang.descriptors.impl.MutablePackageFragmentDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl; import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl;
import org.jetbrains.jet.lang.reflect.ReflectionTypes; import org.jetbrains.jet.lang.reflect.ReflectionTypes;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.ImportPath; import org.jetbrains.jet.lang.resolve.ImportPath;
import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap; import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.util.*; import java.util.*;
public class JvmFunctionImplTypes { public class JvmRuntimeTypes {
private final ReflectionTypes reflectionTypes; private final ReflectionTypes reflectionTypes;
private final ClassDescriptor functionImpl; private final ClassDescriptor functionImpl;
@@ -42,7 +42,7 @@ public class JvmFunctionImplTypes {
private final ClassDescriptor kMemberFunctionImpl; private final ClassDescriptor kMemberFunctionImpl;
private final ClassDescriptor kExtensionFunctionImpl; private final ClassDescriptor kExtensionFunctionImpl;
public JvmFunctionImplTypes(@NotNull ReflectionTypes reflectionTypes) { public JvmRuntimeTypes(@NotNull ReflectionTypes reflectionTypes) {
this.reflectionTypes = reflectionTypes; this.reflectionTypes = reflectionTypes;
ModuleDescriptor fakeModule = new ModuleDescriptorImpl(Name.special("<fake module for functions impl>"), ModuleDescriptor fakeModule = new ModuleDescriptorImpl(Name.special("<fake module for functions impl>"),
@@ -117,7 +117,7 @@ public class JvmFunctionImplTypes {
JetType functionType = KotlinBuiltIns.getInstance().getFunctionType( JetType functionType = KotlinBuiltIns.getInstance().getFunctionType(
Annotations.EMPTY, Annotations.EMPTY,
receiverParameter == null ? null : receiverParameter.getType(), receiverParameter == null ? null : receiverParameter.getType(),
DescriptorUtils.getValueParametersTypes(descriptor.getValueParameters()), ExpressionTypingUtils.getValueParametersTypes(descriptor.getValueParameters()),
descriptor.getReturnType() descriptor.getReturnType()
); );
@@ -125,7 +125,7 @@ public class JvmFunctionImplTypes {
} }
@NotNull @NotNull
public Collection<JetType> getSupertypesForCallableReference(@NotNull FunctionDescriptor descriptor) { public Collection<JetType> getSupertypesForFunctionReference(@NotNull FunctionDescriptor descriptor) {
ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter(); ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter();
ReceiverParameterDescriptor expectedThisObject = descriptor.getExpectedThisObject(); ReceiverParameterDescriptor expectedThisObject = descriptor.getExpectedThisObject();
@@ -162,7 +162,7 @@ public class JvmFunctionImplTypes {
JetType kFunctionType = reflectionTypes.getKFunctionType( JetType kFunctionType = reflectionTypes.getKFunctionType(
Annotations.EMPTY, Annotations.EMPTY,
receiverType, receiverType,
DescriptorUtils.getValueParametersTypes(descriptor.getValueParameters()), ExpressionTypingUtils.getValueParametersTypes(descriptor.getValueParameters()),
descriptor.getReturnType(), descriptor.getReturnType(),
receiverParameter != null receiverParameter != null
); );
@@ -199,11 +199,8 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
@NotNull @NotNull
protected ExpressionCodegen createOrGetClInitCodegen() { protected ExpressionCodegen createOrGetClInitCodegen() {
DeclarationDescriptor descriptor = context.getContextDescriptor(); DeclarationDescriptor descriptor = context.getContextDescriptor();
assert state.getClassBuilderMode() == ClassBuilderMode.FULL
: "<clinit> should not be generated for light classes. Descriptor: " + descriptor;
if (clInit == null) { if (clInit == null) {
MethodVisitor mv = v.newMethod(OtherOrigin(descriptor), ACC_STATIC, "<clinit>", "()V", null, null); MethodVisitor mv = v.newMethod(OtherOrigin(descriptor), ACC_STATIC, "<clinit>", "()V", null, null);
mv.visitCode();
SimpleFunctionDescriptorImpl clInit = SimpleFunctionDescriptorImpl clInit =
SimpleFunctionDescriptorImpl.create(descriptor, Annotations.EMPTY, Name.special("<clinit>"), SYNTHESIZED); SimpleFunctionDescriptorImpl.create(descriptor, Annotations.EMPTY, Name.special("<clinit>"), SYNTHESIZED);
clInit.initialize(null, null, Collections.<TypeParameterDescriptor>emptyList(), clInit.initialize(null, null, Collections.<TypeParameterDescriptor>emptyList(),
@@ -23,7 +23,7 @@ import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.AsmUtil; import org.jetbrains.jet.codegen.AsmUtil;
import org.jetbrains.jet.codegen.JvmFunctionImplTypes; import org.jetbrains.jet.codegen.JvmRuntimeTypes;
import org.jetbrains.jet.codegen.SamCodegenUtil; import org.jetbrains.jet.codegen.SamCodegenUtil;
import org.jetbrains.jet.codegen.SamType; import org.jetbrains.jet.codegen.SamType;
import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.GenerationState;
@@ -88,13 +88,13 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
private final BindingTrace bindingTrace; private final BindingTrace bindingTrace;
private final BindingContext bindingContext; private final BindingContext bindingContext;
private final GenerationState.GenerateClassFilter filter; private final GenerationState.GenerateClassFilter filter;
private final JvmFunctionImplTypes functionImplTypes; private final JvmRuntimeTypes runtimeTypes;
public CodegenAnnotatingVisitor(@NotNull GenerationState state) { public CodegenAnnotatingVisitor(@NotNull GenerationState state) {
this.bindingTrace = state.getBindingTrace(); this.bindingTrace = state.getBindingTrace();
this.bindingContext = state.getBindingContext(); this.bindingContext = state.getBindingContext();
this.filter = state.getGenerateDeclaredClassFilter(); this.filter = state.getGenerateDeclaredClassFilter();
this.functionImplTypes = state.getJvmFunctionImplTypes(); this.runtimeTypes = state.getJvmRuntimeTypes();
} }
@NotNull @NotNull
@@ -264,7 +264,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
if (functionDescriptor == null) return; if (functionDescriptor == null) return;
String name = inventAnonymousClassName(expression); String name = inventAnonymousClassName(expression);
Collection<JetType> supertypes = functionImplTypes.getSupertypesForClosure(functionDescriptor); Collection<JetType> supertypes = runtimeTypes.getSupertypesForClosure(functionDescriptor);
ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, supertypes); ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, supertypes);
recordClosure(functionLiteral, classDescriptor, name); recordClosure(functionLiteral, classDescriptor, name);
@@ -313,7 +313,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
ResolvedCall<?> referencedFunction = bindingContext.get(RESOLVED_CALL, expression.getCallableReference()); ResolvedCall<?> referencedFunction = bindingContext.get(RESOLVED_CALL, expression.getCallableReference());
if (referencedFunction == null) return; if (referencedFunction == null) return;
Collection<JetType> supertypes = Collection<JetType> supertypes =
functionImplTypes.getSupertypesForCallableReference((FunctionDescriptor) referencedFunction.getResultingDescriptor()); runtimeTypes.getSupertypesForFunctionReference((FunctionDescriptor) referencedFunction.getResultingDescriptor());
String name = inventAnonymousClassName(expression); String name = inventAnonymousClassName(expression);
ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, supertypes); ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, supertypes);
@@ -366,7 +366,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
} }
else { else {
String name = inventAnonymousClassName(function); String name = inventAnonymousClassName(function);
Collection<JetType> supertypes = functionImplTypes.getSupertypesForClosure(functionDescriptor); Collection<JetType> supertypes = runtimeTypes.getSupertypesForClosure(functionDescriptor);
ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, supertypes); ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, supertypes);
recordClosure(function, classDescriptor, name); recordClosure(function, classDescriptor, name);
@@ -33,6 +33,7 @@ import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
import org.jetbrains.jet.lang.resolve.kotlin.PackagePartClassUtils; import org.jetbrains.jet.lang.resolve.kotlin.PackagePartClassUtils;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
@@ -42,7 +43,6 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration;
import static org.jetbrains.jet.lang.resolve.java.PackageClassUtils.getPackageClassFqName;
public final class PsiCodegenPredictor { public final class PsiCodegenPredictor {
private PsiCodegenPredictor() { private PsiCodegenPredictor() {
@@ -87,9 +87,8 @@ public final class PsiCodegenPredictor {
FqName packageFqName = declaration.getContainingJetFile().getPackageFqName(); FqName packageFqName = declaration.getContainingJetFile().getPackageFqName();
if (declaration instanceof JetNamedFunction) { if (declaration instanceof JetNamedFunction) {
FqName packageClass = getPackageClassFqName(packageFqName);
Name name = ((JetNamedFunction) declaration).getNameAsName(); Name name = ((JetNamedFunction) declaration).getNameAsName();
return name == null ? null : AsmUtil.internalNameByFqNameWithoutInnerClasses(packageClass) + "$" + name.asString(); return name == null ? null : PackageClassUtils.getPackageClassInternalName(packageFqName) + "$" + name.asString();
} }
parentInternalName = AsmUtil.internalNameByFqNameWithoutInnerClasses(packageFqName); parentInternalName = AsmUtil.internalNameByFqNameWithoutInnerClasses(packageFqName);
@@ -93,7 +93,7 @@ public class GenerationState {
@Nullable @Nullable
private List<ScriptDescriptor> earlierScriptsForReplInterpreter; private List<ScriptDescriptor> earlierScriptsForReplInterpreter;
private final JvmFunctionImplTypes functionImplTypes; private final JvmRuntimeTypes runtimeTypes;
@NotNull @NotNull
private final ModuleDescriptor module; private final ModuleDescriptor module;
@@ -153,7 +153,7 @@ public class GenerationState {
this.generateClassFilter = generateClassFilter; this.generateClassFilter = generateClassFilter;
ReflectionTypes reflectionTypes = new ReflectionTypes(module); ReflectionTypes reflectionTypes = new ReflectionTypes(module);
this.functionImplTypes = new JvmFunctionImplTypes(reflectionTypes); this.runtimeTypes = new JvmRuntimeTypes(reflectionTypes);
} }
@NotNull @NotNull
@@ -220,8 +220,8 @@ public class GenerationState {
} }
@NotNull @NotNull
public JvmFunctionImplTypes getJvmFunctionImplTypes() { public JvmRuntimeTypes getJvmRuntimeTypes() {
return functionImplTypes; return runtimeTypes;
} }
public boolean isInlineEnabled() { public boolean isInlineEnabled() {
@@ -143,7 +143,7 @@ public class JetTypeMapper {
} }
} }
return PackageClassUtils.getPackageClassFqName(packageFragment.getFqName()).asString().replace('.', '/'); return PackageClassUtils.getPackageClassInternalName(packageFragment.getFqName());
} }
@NotNull @NotNull
+17
View File
@@ -0,0 +1,17 @@
#!/bin/bash --posix
# Copyright 2010-2014 JetBrains s.r.o.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
$(dirname $0)/kotlinc-jvm "$@"
+17
View File
@@ -0,0 +1,17 @@
@echo off
rem Copyright 2010-2014 JetBrains s.r.o.
rem
rem Licensed under the Apache License, Version 2.0 (the "License");
rem you may not use this file except in compliance with the License.
rem You may obtain a copy of the License at
rem
rem http://www.apache.org/licenses/LICENSE-2.0
rem
rem Unless required by applicable law or agreed to in writing, software
rem distributed under the License is distributed on an "AS IS" BASIS,
rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rem See the License for the specific language governing permissions and
rem limitations under the License.
call %~dp0kotlinc-jvm.bat %*
@@ -20,7 +20,6 @@ import com.google.common.base.Splitter;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.intellij.openapi.Disposable; import com.intellij.openapi.Disposable;
import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.util.text.StringUtil;
import kotlin.modules.Module;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.cli.common.CLICompiler; import org.jetbrains.jet.cli.common.CLICompiler;
import org.jetbrains.jet.cli.common.CLIConfigurationKeys; import org.jetbrains.jet.cli.common.CLIConfigurationKeys;
@@ -28,7 +27,10 @@ import org.jetbrains.jet.cli.common.ExitCode;
import org.jetbrains.jet.cli.common.arguments.CompilerArgumentsUtil; import org.jetbrains.jet.cli.common.arguments.CompilerArgumentsUtil;
import org.jetbrains.jet.cli.common.arguments.K2JVMCompilerArguments; import org.jetbrains.jet.cli.common.arguments.K2JVMCompilerArguments;
import org.jetbrains.jet.cli.common.messages.*; import org.jetbrains.jet.cli.common.messages.*;
import org.jetbrains.jet.cli.jvm.compiler.*; import org.jetbrains.jet.cli.jvm.compiler.CommandLineScriptUtils;
import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentUtil;
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
import org.jetbrains.jet.cli.jvm.compiler.KotlinToJVMBytecodeCompiler;
import org.jetbrains.jet.cli.jvm.repl.ReplFromTerminal; import org.jetbrains.jet.cli.jvm.repl.ReplFromTerminal;
import org.jetbrains.jet.codegen.CompilationException; import org.jetbrains.jet.codegen.CompilationException;
import org.jetbrains.jet.codegen.inline.InlineCodegenUtil; import org.jetbrains.jet.codegen.inline.InlineCodegenUtil;
@@ -83,7 +85,8 @@ public class K2JVMCompiler extends CLICompiler<K2JVMCompilerArguments> {
if (!arguments.script && if (!arguments.script &&
arguments.module == null && arguments.module == null &&
arguments.src == null && arguments.src == null &&
arguments.freeArgs.isEmpty() arguments.freeArgs.isEmpty() &&
!arguments.version
) { ) {
ReplFromTerminal.run(rootDisposable, configuration); ReplFromTerminal.run(rootDisposable, configuration);
return ExitCode.OK; return ExitCode.OK;
@@ -32,10 +32,7 @@ import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.renderer.DescriptorRenderer; import org.jetbrains.jet.renderer.DescriptorRenderer;
import java.util.Collection; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class JavaToKotlinMethodMap { public class JavaToKotlinMethodMap {
public static final JavaToKotlinMethodMap INSTANCE = new JavaToKotlinMethodMap(); public static final JavaToKotlinMethodMap INSTANCE = new JavaToKotlinMethodMap();
@@ -55,7 +52,7 @@ public class JavaToKotlinMethodMap {
List<FunctionDescriptor> result = Lists.newArrayList(); List<FunctionDescriptor> result = Lists.newArrayList();
Set<ClassDescriptor> allSuperClasses = DescriptorUtils.getAllSuperClasses(containingClass); Set<ClassDescriptor> allSuperClasses = new HashSet<ClassDescriptor>(DescriptorUtils.getSuperclassDescriptors(containingClass));
String serializedMethod = JavaSignatureFormatter.getInstance().formatMethod(javaMethod); String serializedMethod = JavaSignatureFormatter.getInstance().formatMethod(javaMethod);
for (ClassData classData : classDatas) { for (ClassData classData : classDatas) {
@@ -21,7 +21,7 @@ import com.intellij.psi.impl.JavaConstantExpressionEvaluator;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.evaluate.ConstantExpressionEvaluator;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.constants.ConstantsPackage; import org.jetbrains.jet.lang.resolve.constants.ConstantsPackage;
import org.jetbrains.jet.lang.resolve.java.structure.JavaField; import org.jetbrains.jet.lang.resolve.java.structure.JavaField;
@@ -36,7 +36,7 @@ public class JavaPropertyInitializerEvaluatorImpl implements JavaPropertyInitial
if (evaluatedExpression != null) { if (evaluatedExpression != null) {
return ConstantsPackage.createCompileTimeConstant( return ConstantsPackage.createCompileTimeConstant(
evaluatedExpression, evaluatedExpression,
DescriptorUtils.isPropertyCompileTimeConstant(descriptor), ConstantExpressionEvaluator.object$.isPropertyCompileTimeConstant(descriptor),
false, false,
true, true,
descriptor.getType()); descriptor.getType());
@@ -58,6 +58,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ThisReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ThisReceiver;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.plugin.MainFunctionDetector; import org.jetbrains.jet.plugin.MainFunctionDetector;
@@ -591,7 +592,7 @@ public class JetFlowInformationProvider {
VariableDescriptor variableDescriptor = PseudocodeUtil.extractVariableDescriptorIfAny( VariableDescriptor variableDescriptor = PseudocodeUtil.extractVariableDescriptorIfAny(
instruction, false, trace.getBindingContext()); instruction, false, trace.getBindingContext());
if (variableDescriptor == null || !declaredVariables.contains(variableDescriptor) if (variableDescriptor == null || !declaredVariables.contains(variableDescriptor)
|| !DescriptorUtils.isLocal(variableDescriptor.getContainingDeclaration(), variableDescriptor)) { || !ExpressionTypingUtils.isLocal(variableDescriptor.getContainingDeclaration(), variableDescriptor)) {
return; return;
} }
PseudocodeVariablesData.VariableUseState variableUseState = in.get(variableDescriptor); PseudocodeVariablesData.VariableUseState variableUseState = in.get(variableDescriptor);
@@ -41,6 +41,17 @@ public class ConstantExpressionEvaluator private (val trace: BindingTrace) : Jet
val evaluator = ConstantExpressionEvaluator(trace) val evaluator = ConstantExpressionEvaluator(trace)
return evaluator.evaluate(expression, expectedType) return evaluator.evaluate(expression, expectedType)
} }
public fun isPropertyCompileTimeConstant(descriptor: VariableDescriptor): Boolean {
if (descriptor.isVar()) {
return false
}
if (DescriptorUtils.isClassObject(descriptor.getContainingDeclaration()) || DescriptorUtils.isTopLevelDeclaration(descriptor)) {
val returnType = descriptor.getType()
return KotlinBuiltIns.getInstance().isPrimitiveType(returnType) || KotlinBuiltIns.getInstance().getStringType() == returnType
}
return false
}
} }
private fun evaluate(expression: JetExpression, expectedType: JetType?): CompileTimeConstant<*>? { private fun evaluate(expression: JetExpression, expectedType: JetType?): CompileTimeConstant<*>? {
@@ -311,7 +322,7 @@ public class ConstantExpressionEvaluator private (val trace: BindingTrace) : Jet
else else
compileTimeConstant.getValue() compileTimeConstant.getValue()
return createCompileTimeConstant(value, expectedType, isPure = false, return createCompileTimeConstant(value, expectedType, isPure = false,
canBeUsedInAnnotation = DescriptorUtils.isPropertyCompileTimeConstant(callableDescriptor), canBeUsedInAnnotation = isPropertyCompileTimeConstant(callableDescriptor),
usesVariableAsConstant = true) usesVariableAsConstant = true)
} }
} }
@@ -372,7 +372,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
/* /*
* callableReference * callableReference
* : userType? "::" SimpleName * : (userType "?"*)? "::" SimpleName
* ; * ;
*/ */
private boolean parseCallableReferenceExpression() { private boolean parseCallableReferenceExpression() {
@@ -381,7 +381,9 @@ public class JetExpressionParsing extends AbstractJetParsing {
if (!at(COLONCOLON)) { if (!at(COLONCOLON)) {
PsiBuilder.Marker typeReference = mark(); PsiBuilder.Marker typeReference = mark();
myJetParsing.parseUserType(); myJetParsing.parseUserType();
typeReference = myJetParsing.parseNullableTypeSuffix(typeReference);
typeReference.done(TYPE_REFERENCE); typeReference.done(TYPE_REFERENCE);
if (!at(COLONCOLON)) { if (!at(COLONCOLON)) {
expression.rollbackTo(); expression.rollbackTo();
return false; return false;
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.parsing;
import com.intellij.lang.PsiBuilder; import com.intellij.lang.PsiBuilder;
import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet; import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.JetNodeType; import org.jetbrains.jet.JetNodeType;
import org.jetbrains.jet.lexer.JetKeywordToken; import org.jetbrains.jet.lexer.JetKeywordToken;
@@ -1478,14 +1479,7 @@ public class JetParsing extends AbstractJetParsing {
TokenSet.create(EQ, COMMA, GT, RBRACKET, DOT, RPAR, RBRACE, LBRACE, SEMICOLON), extraRecoverySet)); TokenSet.create(EQ, COMMA, GT, RBRACKET, DOT, RPAR, RBRACE, LBRACE, SEMICOLON), extraRecoverySet));
} }
while (at(QUEST)) { typeRefMarker = parseNullableTypeSuffix(typeRefMarker);
PsiBuilder.Marker precede = typeRefMarker.precede();
advance(); // QUEST
typeRefMarker.done(NULLABLE_TYPE);
typeRefMarker = precede;
}
if (at(DOT)) { if (at(DOT)) {
// This is a receiver for a function type // This is a receiver for a function type
@@ -1513,6 +1507,17 @@ public class JetParsing extends AbstractJetParsing {
return typeRefMarker; return typeRefMarker;
} }
@NotNull
PsiBuilder.Marker parseNullableTypeSuffix(@NotNull PsiBuilder.Marker typeRefMarker) {
while (at(QUEST)) {
PsiBuilder.Marker precede = typeRefMarker.precede();
advance(); // QUEST
typeRefMarker.done(NULLABLE_TYPE);
typeRefMarker = precede;
}
return typeRefMarker;
}
/* /*
* userType * userType
* : ("package" ".")? simpleUserType{"."} * : ("package" ".")? simpleUserType{"."}
@@ -89,7 +89,7 @@ public class BindingContextUtils {
public static JetFile getContainingFile(@NotNull BindingContext context, @NotNull DeclarationDescriptor declarationDescriptor) { public static JetFile getContainingFile(@NotNull BindingContext context, @NotNull DeclarationDescriptor declarationDescriptor) {
// declarationDescriptor may describe a synthesized element which doesn't have PSI // declarationDescriptor may describe a synthesized element which doesn't have PSI
// To workaround that, we find a top-level parent (which is inside a PackageFragmentDescriptor), which is guaranteed to have PSI // To workaround that, we find a top-level parent (which is inside a PackageFragmentDescriptor), which is guaranteed to have PSI
DeclarationDescriptor descriptor = DescriptorUtils.findTopLevelParent(declarationDescriptor); DeclarationDescriptor descriptor = findTopLevelParent(declarationDescriptor);
if (descriptor == null) return null; if (descriptor == null) return null;
PsiElement declaration = descriptorToDeclaration(context, descriptor); PsiElement declaration = descriptorToDeclaration(context, descriptor);
@@ -100,6 +100,18 @@ public class BindingContextUtils {
return (JetFile) containingFile; return (JetFile) containingFile;
} }
@Nullable
private static DeclarationDescriptor findTopLevelParent(@NotNull DeclarationDescriptor declarationDescriptor) {
DeclarationDescriptor descriptor = declarationDescriptor;
if (declarationDescriptor instanceof PropertyAccessorDescriptor) {
descriptor = ((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty();
}
while (!(descriptor == null || DescriptorUtils.isTopLevelDeclaration(descriptor))) {
descriptor = descriptor.getContainingDeclaration();
}
return descriptor;
}
@Nullable @Nullable
private static PsiElement doGetDescriptorToDeclaration(@NotNull BindingContext context, @NotNull DeclarationDescriptor descriptor) { private static PsiElement doGetDescriptorToDeclaration(@NotNull BindingContext context, @NotNull DeclarationDescriptor descriptor) {
return context.get(DESCRIPTOR_TO_DECLARATION, descriptor); return context.get(DESCRIPTOR_TO_DECLARATION, descriptor);
@@ -203,13 +203,20 @@ public class DeclarationResolver {
MutableClassDescriptor classDescriptor = (MutableClassDescriptor) entry.getValue(); MutableClassDescriptor classDescriptor = (MutableClassDescriptor) entry.getValue();
if (klass instanceof JetClass && klass.hasPrimaryConstructor() && KotlinBuiltIns.getInstance().isData(classDescriptor)) { if (klass instanceof JetClass && klass.hasPrimaryConstructor() && KotlinBuiltIns.getInstance().isData(classDescriptor)) {
ConstructorDescriptor constructor = DescriptorUtils.getConstructorOfDataClass(classDescriptor); ConstructorDescriptor constructor = getConstructorOfDataClass(classDescriptor);
createComponentFunctions(classDescriptor, constructor); createComponentFunctions(classDescriptor, constructor);
createCopyFunction(classDescriptor, constructor); createCopyFunction(classDescriptor, constructor);
} }
} }
} }
@NotNull
public static ConstructorDescriptor getConstructorOfDataClass(@NotNull ClassDescriptor classDescriptor) {
Collection<ConstructorDescriptor> constructors = classDescriptor.getConstructors();
assert constructors.size() == 1 : "Data class must have only one constructor: " + classDescriptor.getConstructors();
return constructors.iterator().next();
}
private void createComponentFunctions(@NotNull MutableClassDescriptor classDescriptor, @NotNull ConstructorDescriptor constructorDescriptor) { private void createComponentFunctions(@NotNull MutableClassDescriptor classDescriptor, @NotNull ConstructorDescriptor constructorDescriptor) {
int parameterIndex = 0; int parameterIndex = 0;
for (ValueParameterDescriptor parameter : constructorDescriptor.getValueParameters()) { for (ValueParameterDescriptor parameter : constructorDescriptor.getValueParameters()) {
@@ -546,7 +546,7 @@ public class DescriptorResolver {
JetType variableType = type; JetType variableType = type;
if (valueParameter.hasModifier(VARARG_KEYWORD)) { if (valueParameter.hasModifier(VARARG_KEYWORD)) {
varargElementType = type; varargElementType = type;
variableType = DescriptorUtils.getVarargParameterType(type); variableType = getVarargParameterType(type);
} }
ValueParameterDescriptorImpl valueParameterDescriptor = new ValueParameterDescriptorImpl( ValueParameterDescriptorImpl valueParameterDescriptor = new ValueParameterDescriptorImpl(
declarationDescriptor, declarationDescriptor,
@@ -563,6 +563,15 @@ public class DescriptorResolver {
return valueParameterDescriptor; return valueParameterDescriptor;
} }
@NotNull
private static JetType getVarargParameterType(@NotNull JetType elementType) {
JetType primitiveArrayType = KotlinBuiltIns.getInstance().getPrimitiveArrayJetTypeByPrimitiveJetType(elementType);
if (primitiveArrayType != null) {
return primitiveArrayType;
}
return KotlinBuiltIns.getInstance().getArrayType(Variance.INVARIANT, elementType);
}
public List<TypeParameterDescriptorImpl> resolveTypeParametersForCallableDescriptor( public List<TypeParameterDescriptorImpl> resolveTypeParametersForCallableDescriptor(
DeclarationDescriptor containingDescriptor, DeclarationDescriptor containingDescriptor,
WritableScope extensibleScope, WritableScope extensibleScope,
@@ -791,7 +800,7 @@ public class DescriptorResolver {
type = ErrorUtils.createErrorType("Annotation is absent"); type = ErrorUtils.createErrorType("Annotation is absent");
} }
if (parameter.hasModifier(VARARG_KEYWORD)) { if (parameter.hasModifier(VARARG_KEYWORD)) {
return DescriptorUtils.getVarargParameterType(type); return getVarargParameterType(type);
} }
return type; return type;
} }
@@ -1259,7 +1268,7 @@ public class DescriptorResolver {
parameterScope, parameterScope,
valueParameters, trace), valueParameters, trace),
resolveVisibilityFromModifiers(modifierList, getDefaultConstructorVisibility(classDescriptor)), resolveVisibilityFromModifiers(modifierList, getDefaultConstructorVisibility(classDescriptor)),
DescriptorUtils.isConstructorOfStaticNestedClass(constructorDescriptor)); isConstructorOfStaticNestedClass(constructorDescriptor));
if (isAnnotationClass(classDescriptor)) { if (isAnnotationClass(classDescriptor)) {
CompileTimeConstantUtils.checkConstructorParametersType(valueParameters, trace); CompileTimeConstantUtils.checkConstructorParametersType(valueParameters, trace);
} }
@@ -1425,6 +1434,19 @@ public class DescriptorResolver {
return true; return true;
} }
private static boolean isInsideOuterClassOrItsSubclass(@Nullable DeclarationDescriptor nested, @NotNull ClassDescriptor outer) {
if (nested == null) return false;
if (nested instanceof ClassDescriptor && isSubclass((ClassDescriptor) nested, outer)) return true;
return isInsideOuterClassOrItsSubclass(nested.getContainingDeclaration(), outer);
}
@Nullable
public static ClassDescriptor getContainingClass(@NotNull JetScope scope) {
return getParentOfType(scope.getContainingDeclaration(), ClassDescriptor.class, false);
}
public static void checkParameterHasNoValOrVar( public static void checkParameterHasNoValOrVar(
@NotNull BindingTrace trace, @NotNull BindingTrace trace,
@NotNull JetParameter parameter, @NotNull JetParameter parameter,
@@ -21,11 +21,11 @@ import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.OverrideResolver; import org.jetbrains.jet.lang.resolve.OverrideResolver;
import org.jetbrains.jet.lang.resolve.calls.model.MutableResolvedCall; import org.jetbrains.jet.lang.resolve.calls.model.MutableResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.model.VariableAsFunctionResolvedCall; import org.jetbrains.jet.lang.resolve.calls.model.VariableAsFunctionResolvedCall;
import org.jetbrains.jet.lang.types.BoundsSubstitutor;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils; import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
@@ -131,7 +131,7 @@ public class OverloadingConflictResolver {
if (isGenericF && !isGenericG) return false; if (isGenericF && !isGenericG) return false;
if (isGenericF && isGenericG) { if (isGenericF && isGenericG) {
return moreSpecific(DescriptorUtils.substituteBounds(f), DescriptorUtils.substituteBounds(g), false); return moreSpecific(BoundsSubstitutor.substituteBounds(f), BoundsSubstitutor.substituteBounds(g), false);
} }
} }
@@ -38,8 +38,11 @@ import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.PackageType; import org.jetbrains.jet.lang.types.PackageType;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils;
import java.util.*; import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.isOrOverridesSynthesized; import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.isOrOverridesSynthesized;
import static org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind.*; import static org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind.*;
@@ -54,7 +57,7 @@ public class TaskPrioritizer {
@NotNull Collection<ResolutionCandidate<D>> nonlocal @NotNull Collection<ResolutionCandidate<D>> nonlocal
) { ) {
for (ResolutionCandidate<D> resolvedCall : allDescriptors) { for (ResolutionCandidate<D> resolvedCall : allDescriptors) {
if (DescriptorUtils.isLocal(containerOfTheCurrentLocality, resolvedCall.getDescriptor())) { if (ExpressionTypingUtils.isLocal(containerOfTheCurrentLocality, resolvedCall.getDescriptor())) {
local.add(resolvedCall); local.add(resolvedCall);
} }
else { else {
@@ -0,0 +1,121 @@
/*
* Copyright 2010-2013 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.lang.types;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.utils.DFS;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class BoundsSubstitutor {
private static final Function<TypeProjection,JetType> PROJECTIONS_TO_TYPES = new Function<TypeProjection, JetType>() {
@Override
public JetType apply(TypeProjection projection) {
return projection.getType();
}
};
private BoundsSubstitutor() {
}
@NotNull
public static <D extends CallableDescriptor> D substituteBounds(@NotNull D functionDescriptor) {
List<TypeParameterDescriptor> typeParameters = functionDescriptor.getTypeParameters();
if (typeParameters.isEmpty()) return functionDescriptor;
// TODO: this does not handle any recursion in the bounds
@SuppressWarnings("unchecked")
D substitutedFunction = (D) functionDescriptor.substitute(createUpperBoundsSubstitutor(typeParameters));
assert substitutedFunction != null : "Substituting upper bounds should always be legal";
return substitutedFunction;
}
@NotNull
private static TypeSubstitutor createUpperBoundsSubstitutor(@NotNull List<TypeParameterDescriptor> typeParameters) {
Map<TypeConstructor, TypeProjection> mutableSubstitution = new HashMap<TypeConstructor, TypeProjection>();
TypeSubstitutor substitutor = TypeSubstitutor.create(mutableSubstitution);
// todo assert: no loops
for (TypeParameterDescriptor descriptor : topologicallySortTypeParameters(typeParameters)) {
JetType upperBoundsAsType = descriptor.getUpperBoundsAsType();
JetType substitutedUpperBoundsAsType = substitutor.substitute(upperBoundsAsType, Variance.INVARIANT);
mutableSubstitution.put(descriptor.getTypeConstructor(), new TypeProjectionImpl(substitutedUpperBoundsAsType));
}
return substitutor;
}
@NotNull
private static List<TypeParameterDescriptor> topologicallySortTypeParameters(@NotNull final List<TypeParameterDescriptor> typeParameters) {
// In the end, we want every parameter to have no references to those after it in the list
// This gives us the reversed order: the one that refers to everybody else comes first
List<TypeParameterDescriptor> topOrder = DFS.topologicalOrder(
typeParameters,
new DFS.Neighbors<TypeParameterDescriptor>() {
@NotNull
@Override
public Iterable<TypeParameterDescriptor> getNeighbors(TypeParameterDescriptor current) {
return getTypeParametersFromUpperBounds(current, typeParameters);
}
});
assert topOrder.size() == typeParameters.size() : "All type parameters must be visited, but only " + topOrder + " were";
// Now, the one that refers to everybody else stands in the last position
Collections.reverse(topOrder);
return topOrder;
}
@NotNull
private static List<TypeParameterDescriptor> getTypeParametersFromUpperBounds(
@NotNull TypeParameterDescriptor current,
@NotNull final List<TypeParameterDescriptor> typeParameters
) {
return DFS.dfs(
current.getUpperBounds(),
new DFS.Neighbors<JetType>() {
@NotNull
@Override
public Iterable<JetType> getNeighbors(JetType current) {
return Collections2.transform(current.getArguments(), PROJECTIONS_TO_TYPES);
}
},
new DFS.NodeHandlerWithListResult<JetType, TypeParameterDescriptor>() {
@Override
public boolean beforeChildren(JetType current) {
ClassifierDescriptor declarationDescriptor = current.getConstructor().getDeclarationDescriptor();
// typeParameters in a list, but it contains very few elements, so it's fine to call contains() on it
//noinspection SuspiciousMethodCalls
if (typeParameters.contains(declarationDescriptor)) {
result.add((TypeParameterDescriptor) declarationDescriptor);
}
return true;
}
}
);
}
}
@@ -498,7 +498,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
JetType type = components.reflectionTypes.getKFunctionType( JetType type = components.reflectionTypes.getKFunctionType(
Annotations.EMPTY, Annotations.EMPTY,
receiverType, receiverType,
DescriptorUtils.getValueParametersTypes(descriptor.getValueParameters()), getValueParametersTypes(descriptor.getValueParameters()),
descriptor.getReturnType(), descriptor.getReturnType(),
receiverParameter != null receiverParameter != null
); );
@@ -111,7 +111,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
functionDescriptor.setReturnType(safeReturnType); functionDescriptor.setReturnType(safeReturnType);
JetType receiver = DescriptorUtils.getReceiverParameterType(functionDescriptor.getReceiverParameter()); JetType receiver = DescriptorUtils.getReceiverParameterType(functionDescriptor.getReceiverParameter());
List<JetType> valueParametersTypes = DescriptorUtils.getValueParametersTypes(functionDescriptor.getValueParameters()); List<JetType> valueParametersTypes = ExpressionTypingUtils.getValueParametersTypes(functionDescriptor.getValueParameters());
JetType resultType = KotlinBuiltIns.getInstance().getFunctionType( JetType resultType = KotlinBuiltIns.getInstance().getFunctionType(
Annotations.EMPTY, receiver, valueParametersTypes, safeReturnType); Annotations.EMPTY, receiver, valueParametersTypes, safeReturnType);
if (!noExpectedType(expectedType) && KotlinBuiltIns.getInstance().isFunctionOrExtensionFunctionType(expectedType)) { if (!noExpectedType(expectedType) && KotlinBuiltIns.getInstance().isFunctionOrExtensionFunctionType(expectedType)) {
@@ -187,7 +187,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
} }
else { else {
if (expectedValueParameters != null && declaredValueParameters.size() != expectedValueParameters.size()) { if (expectedValueParameters != null && declaredValueParameters.size() != expectedValueParameters.size()) {
List<JetType> expectedParameterTypes = DescriptorUtils.getValueParametersTypes(expectedValueParameters); List<JetType> expectedParameterTypes = ExpressionTypingUtils.getValueParametersTypes(expectedValueParameters);
context.trace.report(EXPECTED_PARAMETERS_NUMBER_MISMATCH.on(functionLiteral, expectedParameterTypes.size(), expectedParameterTypes)); context.trace.report(EXPECTED_PARAMETERS_NUMBER_MISMATCH.on(functionLiteral, expectedParameterTypes.size(), expectedParameterTypes));
} }
for (int i = 0; i < declaredValueParameters.size(); i++) { for (int i = 0; i < declaredValueParameters.size(); i++) {
@@ -370,7 +370,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
// http://youtrack.jetbrains.net/issue/KT-527 // http://youtrack.jetbrains.net/issue/KT-527
VariableDescriptor olderVariable = context.scope.getLocalVariable(variableDescriptor.getName()); VariableDescriptor olderVariable = context.scope.getLocalVariable(variableDescriptor.getName());
if (olderVariable != null && DescriptorUtils.isLocal(context.scope.getContainingDeclaration(), olderVariable)) { if (olderVariable != null && isLocal(context.scope.getContainingDeclaration(), olderVariable)) {
PsiElement declaration = BindingContextUtils.descriptorToDeclaration(context.trace.getBindingContext(), variableDescriptor); PsiElement declaration = BindingContextUtils.descriptorToDeclaration(context.trace.getBindingContext(), variableDescriptor);
context.trace.report(Errors.NAME_SHADOWING.on(declaration, variableDescriptor.getName().asString())); context.trace.report(Errors.NAME_SHADOWING.on(declaration, variableDescriptor.getName().asString()));
} }
@@ -395,7 +395,7 @@ public class ExpressionTypingServices {
JetExpression defaultValue = jetParameter.getDefaultValue(); JetExpression defaultValue = jetParameter.getDefaultValue();
if (defaultValue != null) { if (defaultValue != null) {
getType(declaringScope, defaultValue, valueParameterDescriptor.getType(), dataFlowInfo, trace); getType(declaringScope, defaultValue, valueParameterDescriptor.getType(), dataFlowInfo, trace);
if (DescriptorUtils.isAnnotationClass(DescriptorUtils.getContainingClass(declaringScope))) { if (DescriptorUtils.isAnnotationClass(DescriptorResolver.getContainingClass(declaringScope))) {
ConstantExpressionEvaluator.object$.evaluate(defaultValue, trace, valueParameterDescriptor.getType()); ConstantExpressionEvaluator.object$.evaluate(defaultValue, trace, valueParameterDescriptor.getType());
} }
} }
@@ -427,7 +427,7 @@ public class ExpressionTypingUtils {
} }
public static void checkVariableShadowing(@NotNull ExpressionTypingContext context, @NotNull VariableDescriptor variableDescriptor, VariableDescriptor oldDescriptor) { public static void checkVariableShadowing(@NotNull ExpressionTypingContext context, @NotNull VariableDescriptor variableDescriptor, VariableDescriptor oldDescriptor) {
if (oldDescriptor != null && DescriptorUtils.isLocal(variableDescriptor.getContainingDeclaration(), oldDescriptor)) { if (oldDescriptor != null && isLocal(variableDescriptor.getContainingDeclaration(), oldDescriptor)) {
PsiElement declaration = BindingContextUtils.descriptorToDeclaration(context.trace.getBindingContext(), variableDescriptor); PsiElement declaration = BindingContextUtils.descriptorToDeclaration(context.trace.getBindingContext(), variableDescriptor);
if (declaration != null) { if (declaration != null) {
context.trace.report(Errors.NAME_SHADOWING.on(declaration, variableDescriptor.getName().asString())); context.trace.report(Errors.NAME_SHADOWING.on(declaration, variableDescriptor.getName().asString()));
@@ -486,4 +486,44 @@ public class ExpressionTypingUtils {
public static boolean isUnaryExpressionDependentOnExpectedType(@NotNull JetUnaryExpression expression) { public static boolean isUnaryExpressionDependentOnExpectedType(@NotNull JetUnaryExpression expression) {
return expression.getOperationReference().getReferencedNameElementType() == JetTokens.EXCLEXCL; return expression.getOperationReference().getReferencedNameElementType() == JetTokens.EXCLEXCL;
} }
@NotNull
public static List<JetType> getValueParametersTypes(@NotNull List<ValueParameterDescriptor> valueParameters) {
List<JetType> parameterTypes = new ArrayList<JetType>(valueParameters.size());
for (ValueParameterDescriptor parameter : valueParameters) {
parameterTypes.add(parameter.getType());
}
return parameterTypes;
}
/**
* The primary case for local extensions is the following:
*
* I had a locally declared extension function or a local variable of function type called foo
* And I called it on my x
* Now, someone added function foo() to the class of x
* My code should not change
*
* thus
*
* local extension prevail over members (and members prevail over all non-local extensions)
*/
public static boolean isLocal(DeclarationDescriptor containerOfTheCurrentLocality, DeclarationDescriptor candidate) {
if (candidate instanceof ValueParameterDescriptor) {
return true;
}
DeclarationDescriptor parent = candidate.getContainingDeclaration();
if (!(parent instanceof FunctionDescriptor)) {
return false;
}
FunctionDescriptor functionDescriptor = (FunctionDescriptor) parent;
DeclarationDescriptor current = containerOfTheCurrentLocality;
while (current != null) {
if (current == functionDescriptor) {
return true;
}
current = current.getContainingDeclaration();
}
return false;
}
} }

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