Merge remote-tracking branch 'origin/master'

This commit is contained in:
svtk
2011-12-26 18:37:27 +04:00
467 changed files with 5068 additions and 2902 deletions
@@ -3,13 +3,11 @@ package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.types.JetType;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
import org.objectweb.asm.commons.Method;
import java.util.List;
@@ -87,7 +85,8 @@ public class CallableMethod implements Callable {
else {
if(getInvokeOpcode() != Opcodes.INVOKESTATIC)
desc = desc.replace("(", "(L" + getOwner() + ";");
v.visitMethodInsn(Opcodes.INVOKESTATIC, getInvokeOpcode() == Opcodes.INVOKEINTERFACE ? getOwner() + "$$TImpl" : getOwner(), getSignature().getAsmMethod().getName() + "$default", desc);
v.visitMethodInsn(Opcodes.INVOKESTATIC, getInvokeOpcode() == Opcodes.INVOKEINTERFACE ? getOwner() + JvmAbi.TRAIT_IMPL_SUFFIX
: getOwner(), getSignature().getAsmMethod().getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, desc);
}
}
@@ -48,8 +48,6 @@ public abstract class ClassBodyCodegen {
generateSyntheticParts(accessors);
generateStaticInitializer();
v.done();
}
protected abstract void generateDeclaration();
@@ -26,6 +26,12 @@ public class ClassCodegen {
}
final CodegenContext contextForInners = context.intoClass(descriptor, OwnerKind.IMPLEMENTATION, state.getTypeMapper());
if (!classBuilder.generateCode()) {
// Outer class implementation must happen prior inner classes so we get proper scoping tree in JetLightClass's delegate
generateImplementation(context, aClass, OwnerKind.IMPLEMENTATION, contextForInners.accessors, classBuilder);
}
for (JetDeclaration declaration : aClass.getDeclarations()) {
if (declaration instanceof JetClass && !(declaration instanceof JetEnumEntry)) {
generate(contextForInners, (JetClass) declaration);
@@ -35,7 +41,11 @@ public class ClassCodegen {
}
}
generateImplementation(context, aClass, OwnerKind.IMPLEMENTATION, contextForInners.accessors, classBuilder);
if (classBuilder.generateCode()) {
generateImplementation(context, aClass, OwnerKind.IMPLEMENTATION, contextForInners.accessors, classBuilder);
}
classBuilder.done();
}
private void generateImplementation(CodegenContext context, JetClassOrObject aClass, OwnerKind kind, HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors, ClassBuilder classBuilder) {
@@ -46,6 +56,7 @@ public class ClassCodegen {
if(aClass instanceof JetClass && ((JetClass)aClass).isTrait()) {
ClassBuilder traitBuilder = state.forTraitImplementation(descriptor);
new TraitImplBodyCodegen(aClass, context.intoClass(descriptor, OwnerKind.TRAIT_IMPL, state.getTypeMapper()), traitBuilder, state).generate(null);
traitBuilder.done();
}
}
}
@@ -2410,13 +2410,19 @@ If finally block is present, its last expression is the value of try expression.
return generateTuplePatternMatch((JetTuplePattern) pattern, negated, expressionToMatch, nextEntry);
}
else if (pattern instanceof JetExpressionPattern) {
final Type subjectType = expressionToMatch.type;
expressionToMatch.dupReceiver(v);
expressionToMatch.put(subjectType, v);
JetExpression condExpression = ((JetExpressionPattern) pattern).getExpression();
Type condType = isNumberPrimitive(subjectType) ? expressionType(condExpression) : TYPE_OBJECT;
gen(condExpression, condType);
return generateEqualsForExpressionsOnStack(JetTokens.EQEQ, subjectType, condType, false, false);
if(expressionToMatch != null) {
final Type subjectType = expressionToMatch.type;
expressionToMatch.dupReceiver(v);
expressionToMatch.put(subjectType, v);
JetExpression condExpression = ((JetExpressionPattern) pattern).getExpression();
Type condType = isNumberPrimitive(subjectType) ? expressionType(condExpression) : TYPE_OBJECT;
gen(condExpression, condType);
return generateEqualsForExpressionsOnStack(JetTokens.EQEQ, subjectType, condType, false, false);
}
else {
JetExpression condExpression = ((JetExpressionPattern) pattern).getExpression();
return gen(condExpression);
}
}
else if (pattern instanceof JetWildcardPattern) {
return StackValue.constant(!negated, Type.BOOLEAN_TYPE);
@@ -2665,9 +2671,11 @@ If finally block is present, its last expression is the value of try expression.
JetExpression expr = expression.getSubjectExpression();
final Type subjectType = expressionType(expr);
final Type resultType = expressionType(expression);
final int subjectLocal = myFrameMap.enterTemp(subjectType.getSize());
gen(expr, subjectType);
v.store(subjectLocal, subjectType);
final int subjectLocal = expr != null ? myFrameMap.enterTemp(subjectType.getSize()) : -1;
if(subjectLocal != -1) {
gen(expr, subjectType);
v.store(subjectLocal, subjectType);
}
Label end = new Label();
boolean hasElse = false;
@@ -2736,7 +2744,7 @@ If finally block is present, its last expression is the value of try expression.
JetWhenConditionIsPattern patternCondition = (JetWhenConditionIsPattern) condition;
JetPattern pattern = patternCondition.getPattern();
conditionValue = generatePatternMatch(pattern, patternCondition.isNegated(),
StackValue.local(subjectLocal, subjectType), nextEntry);
subjectLocal == -1 ? null : StackValue.local(subjectLocal, subjectType), nextEntry);
}
else {
throw new UnsupportedOperationException("unsupported kind of when condition");
@@ -6,7 +6,8 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.StdlibNames;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Label;
@@ -68,6 +69,10 @@ public class FunctionCodegen {
{
flags |= ACC_VARARGS;
}
if (functionDescriptor.getModality() == Modality.FINAL) {
flags |= ACC_FINAL;
}
OwnerKind kind = context.getContextKind();
@@ -88,48 +93,48 @@ public class FunctionCodegen {
if(kind != OwnerKind.TRAIT_IMPL) {
AnnotationVisitor av = mv.visitAnnotation(JetTypeMapper.JET_METHOD_TYPE.getDescriptor(), true);
if(functionDescriptor.getReturnType().isNullable()) {
av.visit(StdlibNames.JET_METHOD_NULLABLE_RETURN_TYPE_FIELD, true);
av.visit(JvmStdlibNames.JET_METHOD_NULLABLE_RETURN_TYPE_FIELD, true);
}
if (jvmSignature.getKotlinReturnType() != null) {
av.visit(StdlibNames.JET_METHOD_RETURN_TYPE_FIELD, jvmSignature.getKotlinReturnType());
av.visit(JvmStdlibNames.JET_METHOD_RETURN_TYPE_FIELD, jvmSignature.getKotlinReturnType());
}
if (jvmSignature.getKotlinTypeParameter() != null) {
av.visit(StdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD, jvmSignature.getKotlinTypeParameter());
av.visit(JvmStdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD, jvmSignature.getKotlinTypeParameter());
}
av.visitEnd();
}
if(kind == OwnerKind.TRAIT_IMPL) {
AnnotationVisitor av = mv.visitParameterAnnotation(start++, StdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true);
av.visit(StdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, "this$self");
AnnotationVisitor av = mv.visitParameterAnnotation(start++, JvmStdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true);
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, "this$self");
av.visitEnd();
}
if(receiverParameter.exists()) {
AnnotationVisitor av = mv.visitParameterAnnotation(start++, StdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true);
av.visit(StdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, "this$receiver");
AnnotationVisitor av = mv.visitParameterAnnotation(start++, JvmStdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true);
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, "this$receiver");
if(receiverParameter.getType().isNullable()) {
av.visit(StdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true);
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true);
}
av.visit(StdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD, true);
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_RECEIVER_FIELD, true);
av.visitEnd();
}
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
AnnotationVisitor av = mv.visitParameterAnnotation(start++, StdlibNames.JET_TYPE_PARAMETER.getDescriptor(), true);
av.visit(StdlibNames.JET_TYPE_PARAMETER_NAME_FIELD, typeParameterDescriptor.getName());
AnnotationVisitor av = mv.visitParameterAnnotation(start++, JvmStdlibNames.JET_TYPE_PARAMETER.getDescriptor(), true);
av.visit(JvmStdlibNames.JET_TYPE_PARAMETER_NAME_FIELD, typeParameterDescriptor.getName());
av.visitEnd();
}
for(int i = 0; i != paramDescrs.size(); ++i) {
AnnotationVisitor av = mv.visitParameterAnnotation(i + start, StdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true);
AnnotationVisitor av = mv.visitParameterAnnotation(i + start, JvmStdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true);
ValueParameterDescriptor parameterDescriptor = paramDescrs.get(i);
av.visit(StdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, parameterDescriptor.getName());
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, parameterDescriptor.getName());
if(parameterDescriptor.hasDefaultValue()) {
av.visit(StdlibNames.JET_VALUE_PARAMETER_HAS_DEFAULT_VALUE_FIELD, true);
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_HAS_DEFAULT_VALUE_FIELD, true);
}
if(parameterDescriptor.getOutType().isNullable()) {
av.visit(StdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true);
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true);
}
if (jvmSignature.getKotlinParameterTypes() != null && jvmSignature.getKotlinParameterTypes().get(i) != null) {
av.visit(StdlibNames.JET_VALUE_PARAMETER_TYPE_FIELD, jvmSignature.getKotlinParameterTypes().get(i));
av.visit(JvmStdlibNames.JET_VALUE_PARAMETER_TYPE_FIELD, jvmSignature.getKotlinParameterTypes().get(i + start));
}
av.visitEnd();
}
@@ -300,7 +305,7 @@ public class FunctionCodegen {
boolean isConstructor = "<init>".equals(jvmSignature.getName());
if(!isStatic && !isConstructor)
descriptor = descriptor.replace("(","(L" + ownerInternalName + ";");
final MethodVisitor mv = v.newMethod(null, flags | (isConstructor ? 0 : ACC_STATIC), isConstructor ? "<init>" : jvmSignature.getName() + "$default", descriptor, null, null);
final MethodVisitor mv = v.newMethod(null, flags | (isConstructor ? 0 : ACC_STATIC), isConstructor ? "<init>" : jvmSignature.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, descriptor, null, null);
InstructionAdapter iv = new InstructionAdapter(mv);
if (v.generateCode()) {
mv.visitCode();
@@ -6,8 +6,8 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.OverridingUtil;
import org.jetbrains.jet.lang.resolve.java.StdlibNames;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeProjection;
import org.jetbrains.jet.lexer.JetTokens;
@@ -47,19 +47,41 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
boolean isAbstract = false;
boolean isInterface = false;
boolean isFinal = false;
boolean isStatic = false;
if(myClass instanceof JetClass) {
if(((JetClass) myClass).hasModifier(JetTokens.ABSTRACT_KEYWORD))
JetClass jetClass = (JetClass) myClass;
if (jetClass.hasModifier(JetTokens.ABSTRACT_KEYWORD))
isAbstract = true;
if(((JetClass) myClass).isTrait()) {
if (jetClass.isTrait()) {
isAbstract = true;
isInterface = true;
}
if (!jetClass.hasModifier(JetTokens.OPEN_KEYWORD) && !isAbstract) {
isFinal = true;
}
}
else if (myClass.getParent() instanceof JetClassObject) {
isStatic = true;
}
int access = 0;
access |= Opcodes.ACC_PUBLIC;
if (isAbstract) {
access |= Opcodes.ACC_ABSTRACT;
}
if (isInterface) {
access |= Opcodes.ACC_INTERFACE; // ACC_SUPER
}
if (isFinal) {
access |= Opcodes.ACC_FINAL;
}
if (isStatic) {
access |= Opcodes.ACC_STATIC;
}
v.defineClass(myClass, Opcodes.V1_6,
Opcodes.ACC_PUBLIC | (isAbstract ? Opcodes.ACC_ABSTRACT : 0) | (isInterface
? Opcodes.ACC_INTERFACE
: 0/*Opcodes.ACC_SUPER*/),
access,
signature.getName(),
signature.getJavaGenericSignature(),
signature.getSuperclassName(),
@@ -67,17 +89,27 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
);
v.visitSource(myClass.getContainingFile().getName(), null);
if(descriptor.getContainingDeclaration() instanceof ClassDescriptor) {
v.visitOuterClass(typeMapper.mapType(((ClassDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), null, null);
ClassDescriptor container = getContainingClassDescriptor(descriptor);
if(container != null) {
v.visitOuterClass(typeMapper.mapType(container.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), null, null);
}
if(myClass instanceof JetClass && signature.getKotlinGenericSignature() != null) {
AnnotationVisitor annotationVisitor = v.newAnnotation(myClass, StdlibNames.JET_CLASS.getDescriptor(), true);
annotationVisitor.visit(StdlibNames.JET_CLASS_SIGNATURE, signature.getKotlinGenericSignature());
AnnotationVisitor annotationVisitor = v.newAnnotation(myClass, JvmStdlibNames.JET_CLASS.getDescriptor(), true);
annotationVisitor.visit(JvmStdlibNames.JET_CLASS_SIGNATURE, signature.getKotlinGenericSignature());
annotationVisitor.visitEnd();
}
}
private static ClassDescriptor getContainingClassDescriptor(ClassDescriptor decl) {
DeclarationDescriptor container = decl.getContainingDeclaration();
while (container != null && !(container instanceof NamespaceDescriptor)) {
if (container instanceof ClassDescriptor) return (ClassDescriptor) container;
container = container.getContainingDeclaration();
}
return null;
}
private JvmClassSignature signature() {
List<String> superInterfaces;
@@ -106,7 +138,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
{ // superinterfaces
superInterfacesLinkedHashSet.add(StdlibNames.JET_OBJECT.getInternalName());
superInterfacesLinkedHashSet.add(JvmStdlibNames.JET_OBJECT.getInternalName());
for (JetDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
JetType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference());
@@ -1,5 +1,6 @@
package org.jetbrains.jet.codegen;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import jet.JetObject;
import jet.typeinfo.TypeInfo;
@@ -12,6 +13,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.JavaNamespaceDescriptor;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lexer.JetTokens;
@@ -180,7 +182,29 @@ public class JetTypeMapper {
}
private HashMap<DeclarationDescriptor,Map<DeclarationDescriptor,String>> naming = new HashMap<DeclarationDescriptor, Map<DeclarationDescriptor, String>>();
private String getStableNameForObject(JetObjectDeclaration object, DeclarationDescriptor descriptor) {
String local = getLocalNameForObject(object);
if (local == null) return null;
DeclarationDescriptor containingClass = getContainingClass(descriptor);
if (containingClass != null) {
return getFQName(containingClass) + "$" + local;
}
else {
return getFQName(getContainingNamespace(descriptor)) + "/" + local;
}
}
public static String getLocalNameForObject(JetObjectDeclaration object) {
PsiElement parent = object.getParent();
if (parent instanceof JetClassObject) {
return "ClassObject$";
}
return null;
}
public String getFQName(DeclarationDescriptor descriptor) {
descriptor = descriptor.getOriginal();
@@ -200,7 +224,17 @@ public class JetTypeMapper {
name = map.get(descriptor);
if(name == null) {
name = getFQName(container) + "$" + (map.size()+1);
PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
if (declaration instanceof JetObjectDeclaration) {
String stable = getStableNameForObject((JetObjectDeclaration) declaration, descriptor);
if (stable != null) {
name = stable;
}
}
if (name == null) {
name = getFQName(container) + "$" + (map.size()+1);
}
map.put(descriptor, name);
}
return name;
@@ -222,7 +256,19 @@ public class JetTypeMapper {
return name;
}
private static ClassDescriptor getContainingClass(DeclarationDescriptor descriptor) {
DeclarationDescriptor parent = descriptor.getContainingDeclaration();
if (parent == null || parent instanceof ClassDescriptor) return (ClassDescriptor) parent;
return getContainingClass(parent);
}
private static NamespaceDescriptor getContainingNamespace(DeclarationDescriptor descriptor) {
DeclarationDescriptor parent = descriptor.getContainingDeclaration();
if (parent == null || parent instanceof NamespaceDescriptor) return (NamespaceDescriptor) parent;
return getContainingNamespace(parent);
}
@NotNull public Type mapType(final JetType jetType) {
return mapType(jetType, (BothSignatureWriter) null);
}
@@ -280,7 +326,7 @@ public class JetTypeMapper {
if (descriptor instanceof ClassDescriptor) {
String name = getFQName(descriptor);
Type asmType = Type.getObjectType(name + (kind == OwnerKind.TRAIT_IMPL ? "$$TImpl" : ""));
Type asmType = Type.getObjectType(name + (kind == OwnerKind.TRAIT_IMPL ? JvmAbi.TRAIT_IMPL_SUFFIX : ""));
if (signatureVisitor != null) {
signatureVisitor.writeClassBegin(asmType.getInternalName(), jetType.isNullable());
@@ -738,6 +784,8 @@ public class JetTypeMapper {
}
private void initKnownTypeNames() {
knowTypeNames.put(JetStandardClasses.getAnyType(), "ANY_TYPE_INFO");
knowTypeNames.put(JetStandardClasses.getNullableAnyType(), "NULLABLE_ANY_TYPE_INFO");
knowTypeNames.put(standardLibrary.getIntType(), "INT_TYPE_INFO");
knowTypeNames.put(standardLibrary.getNullableIntType(), "NULLABLE_INT_TYPE_INFO");
knowTypeNames.put(standardLibrary.getLongType(), "LONG_TYPE_INFO");
@@ -6,6 +6,7 @@ import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lexer.JetTokens;
@@ -754,7 +755,7 @@ public abstract class StackValue {
@Override
public void put(Type type, InstructionAdapter v) {
if(isSuper && isInterface) {
v.visitMethodInsn(Opcodes.INVOKESTATIC, owner + "$$TImpl", getter.getName(), getter.getDescriptor().replace("(","(L" + owner + ";"));
v.visitMethodInsn(Opcodes.INVOKESTATIC, owner + JvmAbi.TRAIT_IMPL_SUFFIX, getter.getName(), getter.getDescriptor().replace("(","(L" + owner + ";"));
}
else {
if (getter == null) {
@@ -770,7 +771,7 @@ public abstract class StackValue {
@Override
public void store(InstructionAdapter v) {
if(isSuper && isInterface) {
v.visitMethodInsn(Opcodes.INVOKESTATIC, owner + "$$TImpl", setter.getName(), setter.getDescriptor().replace("(","(L" + owner + ";"));
v.visitMethodInsn(Opcodes.INVOKESTATIC, owner + JvmAbi.TRAIT_IMPL_SUFFIX, setter.getName(), setter.getDescriptor().replace("(","(L" + owner + ";"));
}
else {
if (setter == null) {
@@ -7,6 +7,9 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Function;
import com.intellij.util.Processor;
import jet.ExtensionFunction0;
import jet.ExtensionFunction10;
import jet.Function1;
import jet.modules.IModuleBuilder;
import jet.modules.IModuleSetBuilder;
import org.jetbrains.annotations.Nullable;
@@ -18,6 +21,7 @@ import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.plugin.JetMainDetector;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
@@ -123,6 +127,11 @@ public class CompileEnvironment {
if (rtJar.exists()) {
return rtJar;
}
File classesJar = new File(new File(javaHome).getParentFile().getAbsolutePath(), "Classes/classes.jar");
if (classesJar.exists()) {
return classesJar;
}
return null;
}
@@ -193,17 +202,19 @@ public class CompileEnvironment {
final IModuleSetBuilder moduleSetBuilder = (IModuleSetBuilder) moduleSetBuilderClass.newInstance();
Class namespaceClass = loader.loadClass("namespace");
final Method[] methods = namespaceClass.getMethods();
final Field[] fields = namespaceClass.getDeclaredFields();
boolean modulesDefined = false;
for (Method method : methods) {
if (method.getName().equals("defineModules")) {
method.invoke(null, moduleSetBuilder);
for (Field field : fields) {
if (field.getName().equals("modules")) {
field.setAccessible(true);
ExtensionFunction0 defineMudules = (ExtensionFunction0) field.get(null);
defineMudules.invoke(moduleSetBuilder);
modulesDefined = true;
break;
}
}
if (!modulesDefined) {
throw new CompileEnvironmentException("Module script " + moduleFile + " must define a defineModules() method");
throw new CompileEnvironmentException("Module script " + moduleFile + " must define a modules() property");
}
return moduleSetBuilder;
} catch (Exception e) {
@@ -37,6 +37,9 @@ public class CompileSession {
}
public void addSources(String path) {
if(path == null)
return;
VirtualFile vFile = myEnvironment.getLocalFileSystem().findFileByPath(path);
if (vFile == null) {
myErrors.add("File/directory not found: " + path);
@@ -68,15 +71,15 @@ public class CompileSession {
public void addSources(VirtualFile vFile) {
if (vFile.isDirectory()) {
for (VirtualFile virtualFile : vFile.getChildren()) {
if (virtualFile.getFileType() == JetFileType.INSTANCE) {
addSources(virtualFile);
}
addSources(virtualFile);
}
}
else {
PsiFile psiFile = PsiManager.getInstance(myEnvironment.getProject()).findFile(vFile);
if (psiFile instanceof JetFile) {
mySourceFileNamespaces.add(((JetFile) psiFile).getRootNamespace());
if (vFile.getFileType() == JetFileType.INSTANCE) {
PsiFile psiFile = PsiManager.getInstance(myEnvironment.getProject()).findFile(vFile);
if (psiFile instanceof JetFile) {
mySourceFileNamespaces.add(((JetFile) psiFile).getRootNamespace());
}
}
}
}
@@ -121,8 +124,9 @@ public class CompileSession {
else {
final File runtimeJarPath = CompileEnvironment.getRuntimeJarPath();
if (runtimeJarPath != null && runtimeJarPath.exists()) {
// todo
throw new UnsupportedOperationException("Loading of stdlib sources from jar");
VirtualFile runtimeJar = myEnvironment.getLocalFileSystem().findFileByPath(runtimeJarPath.getAbsolutePath());
VirtualFile jarRoot = myEnvironment.getJarFileSystem().findFileByPath(runtimeJar.getPath() + "!/stdlib/ktSrc");
addSources(jarRoot);
}
else {
return false;
@@ -0,0 +1,134 @@
package org.jetbrains.jet.compiler;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetQualifiedExpression;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintResolutionListener;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl;
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemSolution;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.JetScopeUtils;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.NamespaceType;
import org.jetbrains.jet.lang.types.Variance;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintType.RECEIVER;
/**
* @author Nikolay Krasko
*/
public final class TipsManager {
private TipsManager() {
}
@NotNull
public static Collection<DeclarationDescriptor> getReferenceVariants(JetSimpleNameExpression expression, BindingContext context) {
PsiElement parent = expression.getParent();
if (parent instanceof JetQualifiedExpression) {
JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) parent;
JetExpression receiverExpression = qualifiedExpression.getReceiverExpression();
final JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression);
final JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, receiverExpression);
if (expressionType != null && resolutionScope != null) {
return includeExternalCallableExtensions(
expressionType.getMemberScope().getAllDescriptors(),
resolutionScope, new ExpressionReceiver(receiverExpression, expressionType));
}
}
else {
JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, expression);
if (resolutionScope != null) {
return excludeNotCallableExtensions(resolutionScope.getAllDescriptors(), resolutionScope);
}
}
return Collections.emptyList();
}
private static Collection<DeclarationDescriptor> excludeNotCallableExtensions(
@NotNull Collection<DeclarationDescriptor> descriptors, @NotNull final JetScope scope
) {
final Set<DeclarationDescriptor> descriptorsSet = Sets.newHashSet(descriptors);
descriptorsSet.removeAll(
Collections2.filter(JetScopeUtils.getAllExtensions(scope), new Predicate<CallableDescriptor>() {
@Override
public boolean apply(CallableDescriptor callableDescriptor) {
return !checkReceiverResolution(scope.getImplicitReceiver(), callableDescriptor);
}
}));
return Lists.newArrayList(descriptorsSet);
}
private static Collection<DeclarationDescriptor> includeExternalCallableExtensions(
@NotNull Collection<DeclarationDescriptor> descriptors,
@NotNull final JetScope externalScope,
@NotNull final ReceiverDescriptor receiverDescriptor
) {
// It's impossible to add extension function for namespace
if (receiverDescriptor.getType() instanceof NamespaceType) {
return descriptors;
}
Set<DeclarationDescriptor> descriptorsSet = Sets.newHashSet(descriptors);
descriptorsSet.addAll(
Collections2.filter(JetScopeUtils.getAllExtensions(externalScope),
new Predicate<CallableDescriptor>() {
@Override
public boolean apply(CallableDescriptor callableDescriptor) {
return checkReceiverResolution(receiverDescriptor, callableDescriptor);
}
}));
return descriptorsSet;
}
/*
* Checks if receiver declaration could be resolved to call expected receiver.
*/
private static boolean checkReceiverResolution (
@NotNull ReceiverDescriptor expectedReceiver,
@NotNull CallableDescriptor receiverArgument
) {
ConstraintSystem constraintSystem = new ConstraintSystemImpl(ConstraintResolutionListener.DO_NOTHING);
for (TypeParameterDescriptor typeParameterDescriptor : receiverArgument.getTypeParameters()) {
constraintSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT);
}
ReceiverDescriptor receiverParameter = receiverArgument.getReceiverParameter();
if (expectedReceiver.exists() && receiverParameter.exists()) {
constraintSystem.addSubtypingConstraint(
RECEIVER.assertSubtyping(expectedReceiver.getType(), receiverParameter.getType()));
}
else if (expectedReceiver.exists() || receiverParameter.exists()) {
// Only one of receivers exist
return false;
}
ConstraintSystemSolution solution = constraintSystem.solve();
return solution.getStatus().isSuccessful();
}
}