Merge remote branch 'origin/master'
This commit is contained in:
@@ -73,7 +73,7 @@ public class ClassContext {
|
||||
thisIdx++;
|
||||
}
|
||||
|
||||
final boolean hasReceiver = descriptor.getReceiver().exists();
|
||||
final boolean hasReceiver = descriptor.getReceiverParameter().exists();
|
||||
if (hasReceiver) {
|
||||
thisIdx++;
|
||||
}
|
||||
@@ -104,7 +104,7 @@ public class ClassContext {
|
||||
}
|
||||
|
||||
private ReceiverDescriptor receiver() {
|
||||
return contextType instanceof FunctionDescriptor ? ((FunctionDescriptor) contextType).getReceiver() : ReceiverDescriptor.NO_RECEIVER;
|
||||
return contextType instanceof FunctionDescriptor ? ((FunctionDescriptor) contextType).getReceiverParameter() : ReceiverDescriptor.NO_RECEIVER;
|
||||
}
|
||||
|
||||
private boolean hasReceiver() {
|
||||
|
||||
@@ -42,7 +42,7 @@ public class ClosureCodegen {
|
||||
}
|
||||
|
||||
public static Method erasedInvokeSignature(FunctionDescriptor fd) {
|
||||
boolean isExtensionFunction = fd.getReceiver().exists();
|
||||
boolean isExtensionFunction = fd.getReceiverParameter().exists();
|
||||
int paramCount = fd.getValueParameters().size();
|
||||
if (isExtensionFunction) {
|
||||
paramCount++;
|
||||
@@ -117,7 +117,7 @@ public class ClosureCodegen {
|
||||
final Type enclosingType = context.enclosingClassType(state.getTypeMapper());
|
||||
if (enclosingType == null) captureThis = false;
|
||||
|
||||
final Method constructor = generateConstructor(funClass, captureThis);
|
||||
final Method constructor = generateConstructor(funClass, captureThis, funDescriptor.getReturnType());
|
||||
|
||||
if (captureThis) {
|
||||
cv.visitField(Opcodes.ACC_PRIVATE, "this$0", enclosingType.getDescriptor(), null, null);
|
||||
@@ -151,7 +151,7 @@ public class ClosureCodegen {
|
||||
|
||||
iv.load(0, Type.getObjectType(className));
|
||||
|
||||
final ReceiverDescriptor receiver = funDescriptor.getReceiver();
|
||||
final ReceiverDescriptor receiver = funDescriptor.getReceiverParameter();
|
||||
int count = 1;
|
||||
if (receiver.exists()) {
|
||||
StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv);
|
||||
@@ -175,7 +175,7 @@ public class ClosureCodegen {
|
||||
mv.visitEnd();
|
||||
}
|
||||
|
||||
private Method generateConstructor(String funClass, boolean captureThis) {
|
||||
private Method generateConstructor(String funClass, boolean captureThis, JetType returnType) {
|
||||
int argCount = closure.size();
|
||||
|
||||
if (captureThis) {
|
||||
@@ -199,9 +199,11 @@ public class ClosureCodegen {
|
||||
final MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, "<init>", constructor.getDescriptor(), null, new String[0]);
|
||||
mv.visitCode();
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
ExpressionCodegen expressionCodegen = new ExpressionCodegen(mv, null, Type.VOID_TYPE, context, state);
|
||||
|
||||
iv.load(0, Type.getObjectType(funClass));
|
||||
iv.invokespecial(funClass, "<init>", "()V");
|
||||
expressionCodegen.generateTypeInfo(new ProjectionErasingJetType(returnType));
|
||||
iv.invokespecial(funClass, "<init>", "(Ljet/typeinfo/TypeInfo;)V");
|
||||
|
||||
i = 1;
|
||||
for (Type type : argTypes) {
|
||||
@@ -229,7 +231,7 @@ public class ClosureCodegen {
|
||||
|
||||
public static String getInternalClassName(FunctionDescriptor descriptor) {
|
||||
final int paramCount = descriptor.getValueParameters().size();
|
||||
if (descriptor.getReceiver().exists()) {
|
||||
if (descriptor.getReceiverParameter().exists()) {
|
||||
return "jet/ExtensionFunction" + paramCount;
|
||||
}
|
||||
else {
|
||||
@@ -250,7 +252,7 @@ public class ClosureCodegen {
|
||||
Method descriptor = erasedInvokeSignature(fd);
|
||||
String owner = getInternalClassName(fd);
|
||||
final CallableMethod result = new CallableMethod(owner, descriptor, Opcodes.INVOKEVIRTUAL, Arrays.asList(descriptor.getArgumentTypes()));
|
||||
if (fd.getReceiver().exists()) {
|
||||
if (fd.getReceiverParameter().exists()) {
|
||||
result.setNeedsReceiver(null);
|
||||
}
|
||||
result.requestGenerateCallee(Type.getObjectType(getInternalClassName(fd)));
|
||||
|
||||
@@ -52,8 +52,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
private final InstructionAdapter v;
|
||||
private final FrameMap myMap;
|
||||
private final JetTypeMapper typeMapper;
|
||||
|
||||
private final GenerationState state;
|
||||
private final Type returnType;
|
||||
|
||||
private final BindingContext bindingContext;
|
||||
private final Map<TypeParameterDescriptor, StackValue> typeParameterExpressions = new HashMap<TypeParameterDescriptor, StackValue>();
|
||||
private final ClassContext context;
|
||||
@@ -74,6 +76,14 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
this.intrinsics = state.getIntrinsics();
|
||||
}
|
||||
|
||||
public GenerationState getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public BindingContext getBindingContext() {
|
||||
return bindingContext;
|
||||
}
|
||||
|
||||
public JetTypeMapper getTypeMapper() {
|
||||
return state.getTypeMapper();
|
||||
}
|
||||
@@ -207,7 +217,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
else {
|
||||
assert expressionType != null;
|
||||
final DeclarationDescriptor descriptor = expressionType.getConstructor().getDeclarationDescriptor();
|
||||
if (isClass(descriptor, "IntRange")) { // TODO IntRange subclasses
|
||||
if (isClass(descriptor, "IntRange")) { // TODO IntRange subclasses (now IntRange is final)
|
||||
new ForInRangeLoopGenerator(expression, loopRangeType).invoke();
|
||||
return StackValue.none();
|
||||
}
|
||||
@@ -921,7 +931,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
callableMethod = ClosureCodegen.asCallableMethod((FunctionDescriptor) fd);
|
||||
}
|
||||
else if (fd instanceof FunctionDescriptor) {
|
||||
callableMethod = ClosureCodegen.asCallableMethod((FunctionDescriptor) fd);
|
||||
callableMethod = typeMapper.mapToCallableMethod((FunctionDescriptor) fd, null);
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("can't resolve declaration to callable: " + fd);
|
||||
@@ -2076,7 +2086,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
}
|
||||
}
|
||||
|
||||
void generateTypeInfo(JetType jetType) {
|
||||
public void generateTypeInfo(JetType jetType) {
|
||||
String knownTypeInfo = typeMapper.isKnownTypeInfo(jetType);
|
||||
if(knownTypeInfo != null) {
|
||||
v.getstatic("jet/typeinfo/TypeInfo", knownTypeInfo, "Ljet/typeinfo/TypeInfo;");
|
||||
@@ -2287,7 +2297,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
JetType jetType = bindingContext.get(BindingContext.EXPRESSION_TYPE, rangeExpression);
|
||||
assert jetType != null;
|
||||
final DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor();
|
||||
if (isClass(descriptor, "IntRange")) { // TODO IntRange subclasses
|
||||
if (isClass(descriptor, "IntRange")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -2308,7 +2318,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
|
||||
final String className = "jet/Tuple" + entries.size();
|
||||
Type tupleType = Type.getObjectType(className);
|
||||
StringBuilder signature = new StringBuilder("(");
|
||||
StringBuilder signature = new StringBuilder("(Ljet/typeinfo/TypeInfo;");
|
||||
for (int i = 0; i != entries.size(); ++i) {
|
||||
signature.append("Ljava/lang/Object;");
|
||||
}
|
||||
@@ -2316,6 +2326,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
|
||||
v.anew(tupleType);
|
||||
v.dup();
|
||||
generateTypeInfo(new ProjectionErasingJetType(bindingContext.get(BindingContext.EXPRESSION_TYPE, expression)));
|
||||
for (JetExpression entry : entries) {
|
||||
gen(entry, OBJECT_TYPE);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.jetbrains.jet.codegen;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import jet.Function1;
|
||||
import jet.JetObject;
|
||||
import jet.typeinfo.TypeInfo;
|
||||
import jet.typeinfo.TypeInfoProjection;
|
||||
@@ -58,6 +57,8 @@ public class JetTypeMapper {
|
||||
|
||||
private final HashMap<JetType,String> knowTypes = new HashMap<JetType, String>();
|
||||
public static final Type TYPE_FUNCTION1 = Type.getObjectType("jet/Function1");
|
||||
public static final Type TYPE_ITERATOR = Type.getObjectType("jet/Iterator");
|
||||
public static final Type TYPE_INT_RANGE = Type.getObjectType("jet/IntRange");
|
||||
|
||||
public JetTypeMapper(JetStandardLibrary standardLibrary, BindingContext bindingContext) {
|
||||
this.standardLibrary = standardLibrary;
|
||||
@@ -317,6 +318,9 @@ public class JetTypeMapper {
|
||||
if (jetType.equals(JetStandardClasses.getUnitType()) || jetType.equals(JetStandardClasses.getNothingType())) {
|
||||
return Type.VOID_TYPE;
|
||||
}
|
||||
if (jetType.equals(JetStandardClasses.getNullableNothingType())) {
|
||||
return TYPE_OBJECT;
|
||||
}
|
||||
return mapType(jetType, kind);
|
||||
}
|
||||
|
||||
@@ -461,17 +465,16 @@ public class JetTypeMapper {
|
||||
}
|
||||
|
||||
|
||||
private Method mapSignature(JetNamedFunction f, List<Type> valueParameterTypes, OwnerKind kind) {
|
||||
final JetTypeReference receiverTypeRef = f.getReceiverTypeRef();
|
||||
final JetType receiverType = receiverTypeRef == null ? null : bindingContext.get(BindingContext.TYPE, receiverTypeRef);
|
||||
final List<JetParameter> parameters = f.getValueParameters();
|
||||
private Method mapSignature(FunctionDescriptor f, List<Type> valueParameterTypes, OwnerKind kind) {
|
||||
final ReceiverDescriptor receiverTypeRef = f.getReceiverParameter();
|
||||
final JetType receiverType = !receiverTypeRef.exists() ? null : receiverTypeRef.getType();
|
||||
final List<ValueParameterDescriptor> parameters = f.getValueParameters();
|
||||
List<Type> parameterTypes = new ArrayList<Type>();
|
||||
if (receiverType != null) {
|
||||
parameterTypes.add(mapType(receiverType));
|
||||
}
|
||||
FunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, f);
|
||||
if(kind == OwnerKind.TRAIT_IMPL) {
|
||||
ClassDescriptor containingDeclaration = (ClassDescriptor) functionDescriptor.getContainingDeclaration();
|
||||
ClassDescriptor containingDeclaration = (ClassDescriptor) f.getContainingDeclaration();
|
||||
JetType jetType = TraitImplBodyCodegen.getSuperClass(containingDeclaration, bindingContext);
|
||||
Type type = mapType(jetType);
|
||||
if(type.getInternalName().equals("java/lang/Object")) {
|
||||
@@ -481,24 +484,15 @@ public class JetTypeMapper {
|
||||
valueParameterTypes.add(type);
|
||||
parameterTypes.add(type);
|
||||
}
|
||||
for (JetParameter parameter : parameters) {
|
||||
final Type type = mapType(bindingContext.get(BindingContext.TYPE, parameter.getTypeReference()));
|
||||
for (ValueParameterDescriptor parameter : parameters) {
|
||||
final Type type = mapType(parameter.getOutType());
|
||||
valueParameterTypes.add(type);
|
||||
parameterTypes.add(type);
|
||||
}
|
||||
for (int n = f.getTypeParameters().size(); n > 0; n--) {
|
||||
parameterTypes.add(TYPE_TYPEINFO);
|
||||
}
|
||||
final JetTypeReference returnTypeRef = f.getReturnTypeRef();
|
||||
Type returnType;
|
||||
if (returnTypeRef == null) {
|
||||
assert functionDescriptor != null;
|
||||
final JetType type = functionDescriptor.getReturnType();
|
||||
returnType = mapReturnType(type);
|
||||
}
|
||||
else {
|
||||
returnType = mapReturnType(bindingContext.get(BindingContext.TYPE, returnTypeRef));
|
||||
}
|
||||
Type returnType = mapReturnType(f.getReturnType());
|
||||
return new Method(f.getName(), returnType, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
||||
}
|
||||
|
||||
@@ -512,9 +506,13 @@ public class JetTypeMapper {
|
||||
JetNamedFunction f = (JetNamedFunction) declaration;
|
||||
final FunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, f);
|
||||
assert functionDescriptor != null;
|
||||
return mapToCallableMethod(functionDescriptor, kind);
|
||||
}
|
||||
|
||||
public CallableMethod mapToCallableMethod(FunctionDescriptor functionDescriptor, OwnerKind kind) {
|
||||
final DeclarationDescriptor functionParent = functionDescriptor.getContainingDeclaration();
|
||||
final List<Type> valueParameterTypes = new ArrayList<Type>();
|
||||
Method descriptor = mapSignature(f, valueParameterTypes, kind);
|
||||
Method descriptor = mapSignature(functionDescriptor.getOriginal(), valueParameterTypes, kind);
|
||||
String owner;
|
||||
int invokeOpcode;
|
||||
boolean needsReceiver;
|
||||
@@ -522,7 +520,7 @@ public class JetTypeMapper {
|
||||
if (functionParent instanceof NamespaceDescriptor) {
|
||||
owner = NamespaceCodegen.getJVMClassName(DescriptorRenderer.getFQName(functionParent));
|
||||
invokeOpcode = Opcodes.INVOKESTATIC;
|
||||
needsReceiver = f.getReceiverTypeRef() != null;
|
||||
needsReceiver = functionDescriptor.getReceiverParameter().exists();
|
||||
}
|
||||
else if (functionParent instanceof ClassDescriptor) {
|
||||
ClassDescriptor containingClass = (ClassDescriptor) functionParent;
|
||||
@@ -546,7 +544,7 @@ public class JetTypeMapper {
|
||||
}
|
||||
|
||||
public Method mapSignature(String name, FunctionDescriptor f) {
|
||||
final ReceiverDescriptor receiver = f.getReceiver();
|
||||
final ReceiverDescriptor receiver = f.getReceiverParameter();
|
||||
final List<ValueParameterDescriptor> parameters = f.getValueParameters();
|
||||
List<Type> parameterTypes = new ArrayList<Type>();
|
||||
if (receiver.exists()) {
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeConstructor;
|
||||
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||
import org.jetbrains.jet.lang.types.Variance;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author alex.tkachman
|
||||
*
|
||||
* Utility class used by back-end to
|
||||
*/
|
||||
public class ProjectionErasingJetType implements JetType {
|
||||
private final JetType delegate;
|
||||
private List<TypeProjection> arguments;
|
||||
|
||||
public ProjectionErasingJetType(JetType delegate) {
|
||||
this.delegate = delegate;
|
||||
arguments = new ArrayList<TypeProjection>();
|
||||
for(TypeProjection tp : delegate.getArguments()) {
|
||||
arguments.add(new TypeProjection(Variance.INVARIANT, tp.getType()));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TypeConstructor getConstructor() {
|
||||
return delegate.getConstructor();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<TypeProjection> getArguments() {
|
||||
return arguments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNullable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetScope getMemberScope() {
|
||||
return delegate.getMemberScope();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AnnotationDescriptor> getAnnotations() {
|
||||
return delegate.getAnnotations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return ((obj instanceof ProjectionErasingJetType) && delegate.equals(((ProjectionErasingJetType)obj).delegate)) || delegate.equals(obj);
|
||||
}
|
||||
}
|
||||
@@ -197,6 +197,9 @@ public abstract class StackValue {
|
||||
if (type.getSort() == Type.BOOLEAN) {
|
||||
v.checkcast(JetTypeMapper.JL_BOOLEAN_TYPE);
|
||||
}
|
||||
else if (type.getSort() == Type.CHAR) {
|
||||
v.checkcast(JetTypeMapper.JL_CHAR_TYPE);
|
||||
}
|
||||
else {
|
||||
v.checkcast(JetTypeMapper.JL_NUMBER_TYPE);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.jet.codegen.ExpressionCodegen;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ArrayIndices implements IntrinsicMethod {
|
||||
@Override
|
||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
|
||||
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
|
||||
v.arraylength();
|
||||
v.invokestatic("jet/IntRange", "count", "(I)Ljet/IntRange;");
|
||||
return StackValue.onStack(JetTypeMapper.TYPE_INT_RANGE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.jet.codegen.ExpressionCodegen;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
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.psi.JetCallExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author alex.tkachman
|
||||
*/
|
||||
public class ArrayIterator implements IntrinsicMethod {
|
||||
@Override
|
||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
|
||||
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
|
||||
JetCallExpression call = (JetCallExpression) element;
|
||||
FunctionDescriptor funDescriptor = (FunctionDescriptor) codegen.getBindingContext().get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) call.getCalleeExpression());
|
||||
ClassDescriptor containingDeclaration = (ClassDescriptor) funDescriptor.getContainingDeclaration().getOriginal();
|
||||
JetStandardLibrary standardLibrary = codegen.getState().getStandardLibrary();
|
||||
if(containingDeclaration.equals(standardLibrary.getArray())) {
|
||||
codegen.generateTypeInfo(funDescriptor.getReturnType().getArguments().get(0).getType());
|
||||
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([Ljava/lang/Object;Ljet/typeinfo/TypeInfo;)Ljet/Iterator;");
|
||||
}
|
||||
else if(containingDeclaration.equals(standardLibrary.getByteArrayClass())) {
|
||||
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([B)Ljet/Iterator;");
|
||||
}
|
||||
else if(containingDeclaration.equals(standardLibrary.getShortArrayClass())) {
|
||||
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([S)Ljet/Iterator;");
|
||||
}
|
||||
else if(containingDeclaration.equals(standardLibrary.getIntArrayClass())) {
|
||||
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([I)Ljet/Iterator;");
|
||||
}
|
||||
else if(containingDeclaration.equals(standardLibrary.getLongArrayClass())) {
|
||||
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([J)Ljet/Iterator;");
|
||||
}
|
||||
else if(containingDeclaration.equals(standardLibrary.getFloatArrayClass())) {
|
||||
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([F)Ljet/Iterator;");
|
||||
}
|
||||
else if(containingDeclaration.equals(standardLibrary.getDoubleArrayClass())) {
|
||||
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([D)Ljet/Iterator;");
|
||||
}
|
||||
else if(containingDeclaration.equals(standardLibrary.getCharArrayClass())) {
|
||||
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([C)Ljet/Iterator;");
|
||||
}
|
||||
else if(containingDeclaration.equals(standardLibrary.getBooleanArrayClass())) {
|
||||
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([Z)Ljet/Iterator;");
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException(containingDeclaration.toString());
|
||||
}
|
||||
return StackValue.onStack(JetTypeMapper.TYPE_ITERATOR);
|
||||
}
|
||||
}
|
||||
@@ -29,11 +29,13 @@ public class IntrinsicMethods {
|
||||
private static final IntrinsicMethod DEC = new Increment(-1);
|
||||
|
||||
private static final List<String> PRIMITIVE_NUMBER_TYPES = ImmutableList.of("Boolean", "Byte", "Char", "Short", "Int", "Float", "Long", "Double");
|
||||
public static final ArraySize ARRAY_SIZE = new ArraySize();
|
||||
public static final IntrinsicMethod ARRAY_SIZE = new ArraySize();
|
||||
public static final IntrinsicMethod ARRAY_INDICES = new ArrayIndices();
|
||||
|
||||
private final Project myProject;
|
||||
private final JetStandardLibrary myStdLib;
|
||||
private final Map<DeclarationDescriptor, IntrinsicMethod> myMethods = new HashMap<DeclarationDescriptor, IntrinsicMethod>();
|
||||
private static final IntrinsicMethod ARRAY_ITERATOR = new ArrayIterator();
|
||||
|
||||
public IntrinsicMethods(Project project, JetStandardLibrary stdlib) {
|
||||
myProject = project;
|
||||
@@ -87,6 +89,30 @@ public class IntrinsicMethods {
|
||||
declareIntrinsicProperty("DoubleArray", "size", ARRAY_SIZE);
|
||||
declareIntrinsicProperty("CharArray", "size", ARRAY_SIZE);
|
||||
declareIntrinsicProperty("BooleanArray", "size", ARRAY_SIZE);
|
||||
|
||||
declareIntrinsicProperty("Array", "indices", ARRAY_INDICES);
|
||||
declareIntrinsicProperty("ByteArray", "indices", ARRAY_INDICES);
|
||||
declareIntrinsicProperty("ShortArray", "indices", ARRAY_INDICES);
|
||||
declareIntrinsicProperty("IntArray", "indices", ARRAY_INDICES);
|
||||
declareIntrinsicProperty("LongArray", "indices", ARRAY_INDICES);
|
||||
declareIntrinsicProperty("FloatArray", "indices", ARRAY_INDICES);
|
||||
declareIntrinsicProperty("DoubleArray", "indices", ARRAY_INDICES);
|
||||
declareIntrinsicProperty("CharArray", "indices", ARRAY_INDICES);
|
||||
declareIntrinsicProperty("BooleanArray", "indices", ARRAY_INDICES);
|
||||
|
||||
declareIterator(myStdLib.getArray());
|
||||
declareIterator(myStdLib.getByteArrayClass());
|
||||
declareIterator(myStdLib.getShortArrayClass());
|
||||
declareIterator(myStdLib.getIntArrayClass());
|
||||
declareIterator(myStdLib.getLongArrayClass());
|
||||
declareIterator(myStdLib.getFloatArrayClass());
|
||||
declareIterator(myStdLib.getDoubleArrayClass());
|
||||
declareIterator(myStdLib.getCharArrayClass());
|
||||
declareIterator(myStdLib.getBooleanArrayClass());
|
||||
}
|
||||
|
||||
private void declareIterator(ClassDescriptor classDescriptor) {
|
||||
declareOverload(classDescriptor.getDefaultType().getMemberScope().getFunctions("iterator"), 0, ARRAY_ITERATOR);
|
||||
}
|
||||
|
||||
private void declareIntrinsicStringMethods() {
|
||||
|
||||
@@ -16,21 +16,15 @@ import java.util.List;
|
||||
* @author yole
|
||||
*/
|
||||
public class RangeTo implements IntrinsicMethod {
|
||||
private static final String INT_RANGE_CONSTRUCTOR_DESCRIPTOR = "(II)V";
|
||||
private static final Type INT_RANGE_TYPE = Type.getType(IntRange.class);
|
||||
private static final String CLASS_INT_RANGE = "jet/IntRange";
|
||||
|
||||
@Override
|
||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
|
||||
JetBinaryExpression expression = (JetBinaryExpression) element;
|
||||
final Type leftType = codegen.expressionType(expression.getLeft());
|
||||
if (JetTypeMapper.isIntPrimitive(leftType)) {
|
||||
v.anew(INT_RANGE_TYPE);
|
||||
v.dup();
|
||||
codegen.gen(expression.getLeft(), Type.INT_TYPE);
|
||||
codegen.gen(expression.getRight(), Type.INT_TYPE);
|
||||
v.invokespecial(CLASS_INT_RANGE, "<init>", INT_RANGE_CONSTRUCTOR_DESCRIPTOR);
|
||||
return StackValue.onStack(INT_RANGE_TYPE);
|
||||
v.invokestatic("jet/IntRange", "rangeTo", "(II)Ljet/IntRange;");
|
||||
return StackValue.onStack(JetTypeMapper.TYPE_INT_RANGE);
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("ranges are only supported for int objects");
|
||||
|
||||
+15
-17
@@ -3,14 +3,12 @@ package org.jetbrains.jet.lang.resolve.java;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -22,7 +20,7 @@ public class JavaClassDescriptor extends MutableDeclarationDescriptor implements
|
||||
|
||||
private TypeConstructor typeConstructor;
|
||||
private JavaClassMembersScope unsubstitutedMemberScope;
|
||||
private JetType classObjectType;
|
||||
// private JetType classObjectType;
|
||||
private final Set<FunctionDescriptor> constructors = Sets.newLinkedHashSet();
|
||||
private Modality modality;
|
||||
private Visibility visibility;
|
||||
@@ -52,19 +50,19 @@ public class JavaClassDescriptor extends MutableDeclarationDescriptor implements
|
||||
this.unsubstitutedMemberScope = memberScope;
|
||||
}
|
||||
|
||||
public void setClassObjectMemberScope(JavaClassMembersScope memberScope) {
|
||||
classObjectType = new JetTypeImpl(
|
||||
new TypeConstructorImpl(
|
||||
JavaDescriptorResolver.JAVA_CLASS_OBJECT,
|
||||
Collections.<AnnotationDescriptor>emptyList(),
|
||||
true,
|
||||
"Class object emulation for " + getName(),
|
||||
Collections.<TypeParameterDescriptor>emptyList(),
|
||||
Collections.<JetType>emptyList()
|
||||
),
|
||||
memberScope
|
||||
);
|
||||
}
|
||||
// public void setClassObjectMemberScope(JavaClassMembersScope memberScope) {
|
||||
// classObjectType = new JetTypeImpl(
|
||||
// new TypeConstructorImpl(
|
||||
// JavaDescriptorResolver.JAVA_CLASS_OBJECT,
|
||||
// Collections.<AnnotationDescriptor>emptyList(),
|
||||
// true,
|
||||
// "Class object emulation for " + getName(),
|
||||
// Collections.<TypeParameterDescriptor>emptyList(),
|
||||
// Collections.<JetType>emptyList()
|
||||
// ),
|
||||
// memberScope
|
||||
// );
|
||||
// }
|
||||
|
||||
public void addConstructor(ConstructorDescriptor constructorDescriptor) {
|
||||
this.constructors.add(constructorDescriptor);
|
||||
@@ -133,7 +131,7 @@ public class JavaClassDescriptor extends MutableDeclarationDescriptor implements
|
||||
|
||||
@Override
|
||||
public JetType getClassObjectType() {
|
||||
return classObjectType;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-4
@@ -27,8 +27,8 @@ public class JavaClassMembersScope implements JetScope {
|
||||
private final Map<String, ClassifierDescriptor> classifiers = Maps.newHashMap();
|
||||
private Collection<DeclarationDescriptor> allDescriptors;
|
||||
|
||||
public JavaClassMembersScope(@NotNull DeclarationDescriptor classDescriptor, PsiClass psiClass, JavaSemanticServices semanticServices, boolean staticMembers) {
|
||||
this.containingDeclaration = classDescriptor;
|
||||
public JavaClassMembersScope(@NotNull DeclarationDescriptor classOrNamespaceDescriptor, PsiClass psiClass, JavaSemanticServices semanticServices, boolean staticMembers) {
|
||||
this.containingDeclaration = classOrNamespaceDescriptor;
|
||||
this.psiClass = psiClass;
|
||||
this.semanticServices = semanticServices;
|
||||
this.staticMembers = staticMembers;
|
||||
@@ -161,11 +161,11 @@ public class JavaClassMembersScope implements JetScope {
|
||||
@NotNull
|
||||
@Override
|
||||
public ReceiverDescriptor getImplicitReceiver() {
|
||||
throw new UnsupportedOperationException(); // Should never occur, we don't sit in a Java class...
|
||||
return ReceiverDescriptor.NO_RECEIVER; // Should never occur, we don't sit in a Java class...
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getImplicitReceiversHierarchy(@NotNull List<ReceiverDescriptor> result) {
|
||||
throw new UnsupportedOperationException(); // Should never occur, we don't sit in a Java class...
|
||||
// we cannot really be scoped inside here
|
||||
}
|
||||
}
|
||||
|
||||
+18
-13
@@ -12,6 +12,7 @@ import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
|
||||
import java.util.*;
|
||||
@@ -53,7 +54,7 @@ public class JavaDescriptorResolver {
|
||||
protected final Map<PsiTypeParameter, TypeParameterDescriptor> typeParameterDescriptorCache = Maps.newHashMap();
|
||||
protected final Map<PsiMethod, FunctionDescriptor> methodDescriptorCache = Maps.newHashMap();
|
||||
protected final Map<PsiField, VariableDescriptor> fieldDescriptorCache = Maps.newHashMap();
|
||||
protected final Map<PsiPackage, NamespaceDescriptor> namespaceDescriptorCache = Maps.newHashMap();
|
||||
protected final Map<PsiElement, NamespaceDescriptor> namespaceDescriptorCache = Maps.newHashMap();
|
||||
protected final JavaPsiFacade javaFacade;
|
||||
protected final GlobalSearchScope javaSearchScope;
|
||||
protected final JavaSemanticServices semanticServices;
|
||||
@@ -108,7 +109,6 @@ public class JavaDescriptorResolver {
|
||||
name,
|
||||
typeParameters,
|
||||
supertypes
|
||||
|
||||
));
|
||||
classDescriptor.setModality(Modality.convertFromFlags(
|
||||
psiClass.hasModifierProperty(PsiModifier.ABSTRACT) || psiClass.isInterface(),
|
||||
@@ -117,7 +117,7 @@ public class JavaDescriptorResolver {
|
||||
classDescriptor.setVisibility(resolveVisibilityFromPsiModifiers(semanticServices.getTrace(), psiClass));
|
||||
classDescriptorCache.put(psiClass.getQualifiedName(), classDescriptor);
|
||||
classDescriptor.setUnsubstitutedMemberScope(new JavaClassMembersScope(classDescriptor, psiClass, semanticServices, false));
|
||||
classDescriptor.setClassObjectMemberScope(new JavaClassMembersScope(classDescriptor, psiClass, semanticServices, true));
|
||||
// classDescriptor.setClassObjectMemberScope(new JavaClassMembersScope(classDescriptor, psiClass, semanticServices, true));
|
||||
// UGLY HACK
|
||||
supertypes.addAll(getSupertypes(psiClass));
|
||||
if (psiClass.isInterface()) {
|
||||
@@ -238,7 +238,9 @@ public class JavaDescriptorResolver {
|
||||
public NamespaceDescriptor resolveNamespace(String qualifiedName) {
|
||||
PsiPackage psiPackage = javaFacade.findPackage(qualifiedName);
|
||||
if (psiPackage == null) {
|
||||
return null;
|
||||
PsiClass psiClass = javaFacade.findClass(qualifiedName, javaSearchScope);
|
||||
if (psiClass == null) return null;
|
||||
return resolveNamespace(psiClass);
|
||||
}
|
||||
return resolveNamespace(psiPackage);
|
||||
}
|
||||
@@ -246,20 +248,21 @@ public class JavaDescriptorResolver {
|
||||
private NamespaceDescriptor resolveNamespace(@NotNull PsiPackage psiPackage) {
|
||||
NamespaceDescriptor namespaceDescriptor = namespaceDescriptorCache.get(psiPackage);
|
||||
if (namespaceDescriptor == null) {
|
||||
// TODO : packages
|
||||
|
||||
// PsiClass psiClass = javaFacade.findClass(qualifiedName, javaSearchScope);
|
||||
// if (psiClass != null) {
|
||||
// namespaceDescriptor = createJavaNamespaceDescriptor(psiClass);
|
||||
// }
|
||||
// else {
|
||||
namespaceDescriptor = createJavaNamespaceDescriptor(psiPackage);
|
||||
// }
|
||||
namespaceDescriptor = createJavaNamespaceDescriptor(psiPackage);
|
||||
namespaceDescriptorCache.put(psiPackage, namespaceDescriptor);
|
||||
}
|
||||
return namespaceDescriptor;
|
||||
}
|
||||
|
||||
private NamespaceDescriptor resolveNamespace(@NotNull PsiClass psiClass) {
|
||||
NamespaceDescriptor namespaceDescriptor = namespaceDescriptorCache.get(psiClass);
|
||||
if (namespaceDescriptor == null) {
|
||||
namespaceDescriptor = createJavaNamespaceDescriptor(psiClass);
|
||||
namespaceDescriptorCache.put(psiClass, namespaceDescriptor);
|
||||
}
|
||||
return namespaceDescriptor;
|
||||
}
|
||||
|
||||
private NamespaceDescriptor createJavaNamespaceDescriptor(@NotNull PsiPackage psiPackage) {
|
||||
String name = psiPackage.getName();
|
||||
JavaNamespaceDescriptor namespaceDescriptor = new JavaNamespaceDescriptor(
|
||||
@@ -325,6 +328,7 @@ public class JavaDescriptorResolver {
|
||||
resolveVisibilityFromPsiModifiers(semanticServices.getTrace(), field),
|
||||
!isFinal,
|
||||
null,
|
||||
DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration),
|
||||
field.getName(),
|
||||
isFinal ? null : type,
|
||||
type);
|
||||
@@ -399,6 +403,7 @@ public class JavaDescriptorResolver {
|
||||
methodDescriptorCache.put(method, functionDescriptorImpl);
|
||||
functionDescriptorImpl.initialize(
|
||||
null,
|
||||
DescriptorUtils.getExpectedThisObjectIfNeeded(owner),
|
||||
resolveTypeParameters(functionDescriptorImpl, method.getTypeParameters()),
|
||||
semanticServices.getDescriptorResolver().resolveParameterDescriptors(functionDescriptorImpl, parameters),
|
||||
semanticServices.getTypeTransformer().transformToType(returnType),
|
||||
|
||||
@@ -11,7 +11,6 @@ import java.util.Set;
|
||||
* @author abreslav
|
||||
*/
|
||||
public class JavaPackageScope extends JetScopeImpl {
|
||||
|
||||
private final JavaSemanticServices semanticServices;
|
||||
private final DeclarationDescriptor containingDescriptor;
|
||||
private final String packagePrefix;
|
||||
|
||||
@@ -42,7 +42,7 @@ fun Any?.toString() : String// = this === other
|
||||
|
||||
trait Iterator<out T> {
|
||||
fun next() : T
|
||||
abstract fun hasNext() : Boolean
|
||||
fun hasNext() : Boolean
|
||||
}
|
||||
|
||||
trait Iterable<out T> {
|
||||
@@ -54,6 +54,8 @@ class Array<T>(val size : Int, init : fun(Int) : T = null ) {
|
||||
fun set(index : Int, value : T) : Unit
|
||||
|
||||
fun iterator() : Iterator<T>
|
||||
|
||||
val indices : IntRange
|
||||
}
|
||||
|
||||
class ByteArray(val size : Int) {
|
||||
@@ -61,6 +63,8 @@ class ByteArray(val size : Int) {
|
||||
fun set(index : Int, value : Byte) : Unit
|
||||
|
||||
fun iterator() : Iterator<Byte>
|
||||
|
||||
val indices : IntRange
|
||||
}
|
||||
|
||||
class ShortArray(val size : Int) {
|
||||
@@ -68,6 +72,8 @@ class ShortArray(val size : Int) {
|
||||
fun set(index : Int, value : Short) : Unit
|
||||
|
||||
fun iterator() : Iterator<Short>
|
||||
|
||||
val indices : IntRange
|
||||
}
|
||||
|
||||
class IntArray(val size : Int) {
|
||||
@@ -75,6 +81,8 @@ class IntArray(val size : Int) {
|
||||
fun set(index : Int, value : Int) : Unit
|
||||
|
||||
fun iterator() : Iterator<Int>
|
||||
|
||||
val indices : IntRange
|
||||
}
|
||||
|
||||
class LongArray(val size : Int) {
|
||||
@@ -82,6 +90,8 @@ class LongArray(val size : Int) {
|
||||
fun set(index : Int, value : Long) : Unit
|
||||
|
||||
fun iterator() : Iterator<Long>
|
||||
|
||||
val indices : IntRange
|
||||
}
|
||||
|
||||
class FloatArray(val size : Int) {
|
||||
@@ -89,6 +99,8 @@ class FloatArray(val size : Int) {
|
||||
fun set(index : Int, value : Float) : Unit
|
||||
|
||||
fun iterator() : Iterator<Float>
|
||||
|
||||
val indices : IntRange
|
||||
}
|
||||
|
||||
class DoubleArray(val size : Int) {
|
||||
@@ -96,6 +108,8 @@ class DoubleArray(val size : Int) {
|
||||
fun set(index : Int, value : Double) : Unit
|
||||
|
||||
fun iterator() : Iterator<Double>
|
||||
|
||||
val indices : IntRange
|
||||
}
|
||||
|
||||
class CharArray(val size : Int) {
|
||||
@@ -103,6 +117,8 @@ class CharArray(val size : Int) {
|
||||
fun set(index : Int, value : Char) : Unit
|
||||
|
||||
fun iterator() : Iterator<Char>
|
||||
|
||||
val indices : IntRange
|
||||
}
|
||||
|
||||
class BooleanArray(val size : Int) {
|
||||
@@ -110,6 +126,8 @@ class BooleanArray(val size : Int) {
|
||||
fun set(index : Int, value : Boolean) : Unit
|
||||
|
||||
fun iterator() : Iterator<Boolean>
|
||||
|
||||
val indices : IntRange
|
||||
}
|
||||
|
||||
trait Comparable<in T> {
|
||||
@@ -152,8 +170,28 @@ trait Range<in T : Comparable<T>> {
|
||||
fun contains(item : T) : Boolean
|
||||
}
|
||||
|
||||
class IntRange<T : Comparable<T>>(val start : Int, val end : Int) : Range<T>, Iterable<T> {
|
||||
class IntRange(val start : Int, size : Int, reversed : Boolean = false) : Range<Int>, Iterable<Int> {
|
||||
fun iterator () : Iterator<Int>
|
||||
|
||||
fun contains (elem: Int) : Boolean
|
||||
|
||||
val size : Int
|
||||
|
||||
val end : Int
|
||||
|
||||
val reversed : Boolean
|
||||
}
|
||||
|
||||
class LongRange(val start : Long, size : Long, reversed : Boolean = false) : Range<Long>, Iterable<Long> {
|
||||
fun iterator () : Iterator<Long>
|
||||
|
||||
fun contains (elem: Long) : Boolean
|
||||
|
||||
val size : Long
|
||||
|
||||
val end : Long
|
||||
|
||||
val reversed : Boolean
|
||||
}
|
||||
|
||||
abstract class Number : Hashable {
|
||||
@@ -349,11 +387,11 @@ class Long : Number, Comparable<Long> {
|
||||
|
||||
fun rangeTo(other : Double) : Range<Double>
|
||||
fun rangeTo(other : Float) : Range<Double>
|
||||
fun rangeTo(other : Long) : IntRange<Long>
|
||||
fun rangeTo(other : Int) : IntRange<Long>
|
||||
fun rangeTo(other : Short) : IntRange<Long>
|
||||
fun rangeTo(other : Byte) : IntRange<Long>
|
||||
fun rangeTo(other : Char) : IntRange<Long>
|
||||
fun rangeTo(other : Long) : LongRange
|
||||
fun rangeTo(other : Int) : LongRange
|
||||
fun rangeTo(other : Short) : LongRange
|
||||
fun rangeTo(other : Byte) : LongRange
|
||||
fun rangeTo(other : Char) : LongRange
|
||||
|
||||
fun inc() : Long
|
||||
fun dec() : Long
|
||||
@@ -420,11 +458,11 @@ class Int : Number, Comparable<Int> {
|
||||
|
||||
fun rangeTo(other : Double) : Range<Double>
|
||||
fun rangeTo(other : Float) : Range<Double>
|
||||
fun rangeTo(other : Long) : IntRange<Long>
|
||||
fun rangeTo(other : Int) : IntRange<Int>
|
||||
fun rangeTo(other : Short) : IntRange<Int>
|
||||
fun rangeTo(other : Byte) : IntRange<Int>
|
||||
fun rangeTo(other : Char) : IntRange<Int>
|
||||
fun rangeTo(other : Long) : LongRange
|
||||
fun rangeTo(other : Int) : IntRange
|
||||
fun rangeTo(other : Short) : IntRange
|
||||
fun rangeTo(other : Byte) : IntRange
|
||||
fun rangeTo(other : Char) : IntRange
|
||||
|
||||
fun inc() : Int
|
||||
fun dec() : Int
|
||||
@@ -491,11 +529,11 @@ class Char : Number, Comparable<Char> {
|
||||
|
||||
fun rangeTo(other : Double) : Range<Double>
|
||||
fun rangeTo(other : Float) : Range<Float>
|
||||
fun rangeTo(other : Long) : IntRange<Long>
|
||||
fun rangeTo(other : Int) : IntRange<Int>
|
||||
fun rangeTo(other : Short) : IntRange<Short>
|
||||
fun rangeTo(other : Byte) : IntRange<Byte>
|
||||
fun rangeTo(other : Char) : IntRange<Char>
|
||||
fun rangeTo(other : Long) : LongRange
|
||||
fun rangeTo(other : Int) : IntRange
|
||||
fun rangeTo(other : Short) : IntRange
|
||||
fun rangeTo(other : Byte) : IntRange
|
||||
fun rangeTo(other : Char) : IntRange
|
||||
|
||||
fun inc() : Char
|
||||
fun dec() : Char
|
||||
@@ -554,11 +592,11 @@ class Short : Number, Comparable<Short> {
|
||||
|
||||
fun rangeTo(other : Double) : Range<Double>
|
||||
fun rangeTo(other : Float) : Range<Float>
|
||||
fun rangeTo(other : Long) : IntRange<Long>
|
||||
fun rangeTo(other : Int) : IntRange<Int>
|
||||
fun rangeTo(other : Short) : IntRange<Short>
|
||||
fun rangeTo(other : Byte) : IntRange<Short>
|
||||
fun rangeTo(other : Char) : IntRange<Int>
|
||||
fun rangeTo(other : Long) : LongRange
|
||||
fun rangeTo(other : Int) : IntRange
|
||||
fun rangeTo(other : Short) : IntRange
|
||||
fun rangeTo(other : Byte) : IntRange
|
||||
fun rangeTo(other : Char) : IntRange
|
||||
|
||||
fun inc() : Short
|
||||
fun dec() : Short
|
||||
@@ -617,11 +655,11 @@ class Byte : Number, Comparable<Byte> {
|
||||
|
||||
fun rangeTo(other : Double) : Range<Double>
|
||||
fun rangeTo(other : Float) : Range<Float>
|
||||
fun rangeTo(other : Long) : IntRange<Long>
|
||||
fun rangeTo(other : Int) : IntRange<Int>
|
||||
fun rangeTo(other : Short) : IntRange<Short>
|
||||
fun rangeTo(other : Byte) : IntRange<Byte>
|
||||
fun rangeTo(other : Char) : IntRange<Int>
|
||||
fun rangeTo(other : Long) : LongRange
|
||||
fun rangeTo(other : Int) : IntRange
|
||||
fun rangeTo(other : Short) : IntRange
|
||||
fun rangeTo(other : Byte) : IntRange
|
||||
fun rangeTo(other : Char) : IntRange
|
||||
|
||||
fun inc() : Byte
|
||||
fun dec() : Byte
|
||||
|
||||
@@ -44,8 +44,8 @@ public class JetSemanticServices {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetTypeInferrer.Services getTypeInferrerServices(@NotNull BindingTrace trace, @NotNull JetFlowInformationProvider flowInformationProvider) {
|
||||
return new JetTypeInferrer(flowInformationProvider, this).getServices(trace);
|
||||
public JetTypeInferrer.Services getTypeInferrerServices(@NotNull BindingTrace trace) {
|
||||
return new JetTypeInferrer(this).getServices(trace);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -25,6 +25,7 @@ public interface JetControlFlowBuilder {
|
||||
void jumpOnTrue(@NotNull Label label);
|
||||
void nondeterministicJump(Label label); // Maybe, jump to label
|
||||
void jumpToError(JetThrowExpression expression);
|
||||
void jumpToError(JetExpression nothingExpression);
|
||||
|
||||
// Entry/exit points
|
||||
Label getEntryPoint(@NotNull JetElement labelElement);
|
||||
|
||||
@@ -62,6 +62,11 @@ public class JetControlFlowBuilderAdapter implements JetControlFlowBuilder {
|
||||
builder.jumpToError(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpToError(JetExpression nothingExpression) {
|
||||
builder.jumpToError(nothingExpression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Label getEntryPoint(@NotNull JetElement labelElement) {
|
||||
return builder.getEntryPoint(labelElement);
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
package org.jetbrains.jet.lang.cfg;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.JetTypeInferrer;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
@@ -18,7 +22,7 @@ import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||
*/
|
||||
public class JetControlFlowProcessor {
|
||||
|
||||
private final Map<String, Stack<JetElement>> labeledElements = new HashMap<String, Stack<JetElement>>();
|
||||
// private final Map<String, Stack<JetElement>> labeledElements = new HashMap<String, Stack<JetElement>>();
|
||||
|
||||
private final JetControlFlowBuilder builder;
|
||||
private final BindingTrace trace;
|
||||
@@ -33,10 +37,10 @@ public class JetControlFlowProcessor {
|
||||
}
|
||||
|
||||
public void generateSubroutineControlFlow(@NotNull JetElement subroutineElement, @NotNull List<? extends JetElement> body) {
|
||||
if (subroutineElement instanceof JetNamedDeclaration) {
|
||||
JetNamedDeclaration namedDeclaration = (JetNamedDeclaration) subroutineElement;
|
||||
enterLabeledElement(JetPsiUtil.safeName(namedDeclaration.getName()), namedDeclaration);
|
||||
}
|
||||
// if (subroutineElement instanceof JetNamedDeclaration) {
|
||||
// JetNamedDeclaration namedDeclaration = (JetNamedDeclaration) subroutineElement;
|
||||
// enterLabeledElement(JetPsiUtil.safeName(namedDeclaration.getName()), namedDeclaration);
|
||||
// }
|
||||
boolean functionLiteral = subroutineElement instanceof JetFunctionLiteralExpression;
|
||||
builder.enterSubroutine(subroutineElement, functionLiteral);
|
||||
for (JetElement statement : body) {
|
||||
@@ -45,57 +49,55 @@ public class JetControlFlowProcessor {
|
||||
builder.exitSubroutine(subroutineElement, functionLiteral);
|
||||
}
|
||||
|
||||
private void enterLabeledElement(@NotNull String labelName, @NotNull JetElement labeledElement) {
|
||||
Stack<JetElement> stack = labeledElements.get(labelName);
|
||||
if (stack == null) {
|
||||
stack = new Stack<JetElement>();
|
||||
labeledElements.put(labelName, stack);
|
||||
}
|
||||
stack.push(labeledElement);
|
||||
}
|
||||
// private void enterLabeledElement(@NotNull String labelName, @NotNull JetElement labeledElement) {
|
||||
// Stack<JetElement> stack = labeledElements.get(labelName);
|
||||
// if (stack == null) {
|
||||
// stack = new Stack<JetElement>();
|
||||
// labeledElements.put(labelName, stack);
|
||||
// }
|
||||
// stack.push(labeledElement);
|
||||
// }
|
||||
//
|
||||
// private void exitElement(JetElement element) {
|
||||
// // TODO : really suboptimal
|
||||
// for (Iterator<Map.Entry<String, Stack<JetElement>>> mapIter = labeledElements.entrySet().iterator(); mapIter.hasNext(); ) {
|
||||
// Map.Entry<String, Stack<JetElement>> entry = mapIter.next();
|
||||
// Stack<JetElement> stack = entry.getValue();
|
||||
// for (Iterator<JetElement> stackIter = stack.iterator(); stackIter.hasNext(); ) {
|
||||
// JetElement recorded = stackIter.next();
|
||||
// if (recorded == element) {
|
||||
// stackIter.remove();
|
||||
// }
|
||||
// }
|
||||
// if (stack.isEmpty()) {
|
||||
// mapIter.remove();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
private void exitElement(JetElement element) {
|
||||
// TODO : really suboptimal
|
||||
for (Iterator<Map.Entry<String, Stack<JetElement>>> mapIter = labeledElements.entrySet().iterator(); mapIter.hasNext(); ) {
|
||||
Map.Entry<String, Stack<JetElement>> entry = mapIter.next();
|
||||
Stack<JetElement> stack = entry.getValue();
|
||||
for (Iterator<JetElement> stackIter = stack.iterator(); stackIter.hasNext(); ) {
|
||||
JetElement recorded = stackIter.next();
|
||||
if (recorded == element) {
|
||||
stackIter.remove();
|
||||
}
|
||||
}
|
||||
if (stack.isEmpty()) {
|
||||
mapIter.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JetElement resolveLabel(@NotNull String labelName, @NotNull JetSimpleNameExpression labelExpression, boolean reportUnresolved) {
|
||||
Stack<JetElement> stack = labeledElements.get(labelName);
|
||||
if (stack == null || stack.isEmpty()) {
|
||||
if (reportUnresolved) {
|
||||
trace.report(UNRESOLVED_REFERENCE.on(labelExpression));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
else if (stack.size() > 1) {
|
||||
// trace.getErrorHandler().genericWarning(labelExpression.getNode(), "There is more than one label with such a name in this scope");
|
||||
trace.report(LABEL_NAME_CLASH.on(labelExpression));
|
||||
}
|
||||
|
||||
JetElement result = stack.peek();
|
||||
trace.record(BindingContext.LABEL_TARGET, labelExpression, result);
|
||||
return result;
|
||||
}
|
||||
// @Nullable
|
||||
// private JetElement resolveLabel(@NotNull String labelName, @NotNull JetSimpleNameExpression labelExpression, boolean reportUnresolved) {
|
||||
// Stack<JetElement> stack = labeledElements.get(labelName);
|
||||
// if (stack == null || stack.isEmpty()) {
|
||||
// if (reportUnresolved) {
|
||||
//// trace.report(UNRESOLVED_REFERENCE.on(labelExpression));
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
// else if (stack.size() > 1) {
|
||||
//// trace.getErrorHandler().genericWarning(labelExpression.getNode(), "There is more than one label with such a name in this scope");
|
||||
//// trace.report(LABEL_NAME_CLASH.on(labelExpression));
|
||||
// }
|
||||
//
|
||||
// JetElement result = stack.peek();
|
||||
//// trace.record(BindingContext.LABEL_TARGET, labelExpression, result);
|
||||
// return result;
|
||||
// }
|
||||
|
||||
private class CFPVisitor extends JetVisitorVoid {
|
||||
// private final boolean preferBlock;
|
||||
private final boolean inCondition;
|
||||
|
||||
private CFPVisitor(boolean inCondition) {
|
||||
// this.preferBlock = preferBlock;
|
||||
this.inCondition = inCondition;
|
||||
}
|
||||
|
||||
@@ -109,7 +111,7 @@ public class JetControlFlowProcessor {
|
||||
visitor = new CFPVisitor(inCondition);
|
||||
}
|
||||
element.accept(visitor);
|
||||
exitElement(element);
|
||||
// exitElement(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -122,12 +124,12 @@ public class JetControlFlowProcessor {
|
||||
|
||||
@Override
|
||||
public void visitThisExpression(JetThisExpression expression) {
|
||||
JetSimpleNameExpression targetLabel = expression.getTargetLabel();
|
||||
if (targetLabel != null) {
|
||||
String labelName = expression.getLabelName();
|
||||
assert labelName != null;
|
||||
resolveLabel(labelName, targetLabel, false);
|
||||
}
|
||||
// JetSimpleNameExpression targetLabel = expression.getTargetLabel();
|
||||
// if (targetLabel != null) {
|
||||
// String labelName = expression.getLabelName();
|
||||
// assert labelName != null;
|
||||
// resolveLabel(labelName, targetLabel, false);
|
||||
// }
|
||||
builder.read(expression);
|
||||
}
|
||||
|
||||
@@ -139,6 +141,12 @@ public class JetControlFlowProcessor {
|
||||
@Override
|
||||
public void visitSimpleNameExpression(JetSimpleNameExpression expression) {
|
||||
builder.read(expression);
|
||||
if (trace.get(BindingContext.PROCESSED, expression)) {
|
||||
JetType type = trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression);
|
||||
if (type != null && JetStandardClasses.isNothing(type)) {
|
||||
builder.jumpToError(expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -153,7 +161,7 @@ public class JetControlFlowProcessor {
|
||||
private void visitLabeledExpression(@NotNull String labelName, @NotNull JetExpression labeledExpression) {
|
||||
JetExpression deparenthesized = JetPsiUtil.deparenthesize(labeledExpression);
|
||||
if (deparenthesized != null) {
|
||||
enterLabeledElement(labelName, deparenthesized);
|
||||
// enterLabeledElement(labelName, deparenthesized);
|
||||
value(labeledExpression, inCondition);
|
||||
}
|
||||
}
|
||||
@@ -437,12 +445,20 @@ public class JetControlFlowProcessor {
|
||||
if (labelName != null) {
|
||||
JetSimpleNameExpression targetLabel = expression.getTargetLabel();
|
||||
assert targetLabel != null;
|
||||
loop = resolveLabel(labelName, targetLabel, true);
|
||||
if (!isLoop(loop)) {
|
||||
// trace.getErrorHandler().genericError(expression.getNode(), "The label '" + targetLabel.getText() + "' does not denote a loop");
|
||||
PsiElement labeledElement = BindingContextUtils.resolveToDeclarationPsiElement(trace.getBindingContext(), targetLabel);
|
||||
if (labeledElement instanceof JetLoopExpression) {
|
||||
loop = (JetLoopExpression) labeledElement;
|
||||
}
|
||||
else {
|
||||
trace.report(NOT_A_LOOP_LABEL.on(expression, targetLabel.getText()));
|
||||
loop = null;
|
||||
}
|
||||
// loop = resolveLabel(labelName, targetLabel, true);
|
||||
// if (!isLoop(loop)) {
|
||||
//// trace.getErrorHandler().genericError(expression.getNode(), "The label '" + targetLabel.getText() + "' does not denote a loop");
|
||||
// trace.report(NOT_A_LOOP_LABEL.on(expression, targetLabel.getText()));
|
||||
// loop = null;
|
||||
// }
|
||||
}
|
||||
else {
|
||||
loop = builder.getCurrentLoop();
|
||||
@@ -454,11 +470,11 @@ public class JetControlFlowProcessor {
|
||||
return loop;
|
||||
}
|
||||
|
||||
private boolean isLoop(JetElement loop) {
|
||||
return loop instanceof JetWhileExpression ||
|
||||
loop instanceof JetDoWhileExpression ||
|
||||
loop instanceof JetForExpression;
|
||||
}
|
||||
// private boolean isLoop(JetElement loop) {
|
||||
// return loop instanceof JetWhileExpression ||
|
||||
// loop instanceof JetDoWhileExpression ||
|
||||
// loop instanceof JetForExpression;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void visitReturnExpression(JetReturnExpression expression) {
|
||||
@@ -471,13 +487,21 @@ public class JetControlFlowProcessor {
|
||||
if (labelElement != null) {
|
||||
String labelName = expression.getLabelName();
|
||||
assert labelName != null;
|
||||
subroutine = resolveLabel(labelName, labelElement, true);
|
||||
PsiElement labeledElement = BindingContextUtils.resolveToDeclarationPsiElement(trace.getBindingContext(), labelElement);
|
||||
if (labeledElement != null) {
|
||||
assert labeledElement instanceof JetElement;
|
||||
subroutine = (JetElement) labeledElement;
|
||||
}
|
||||
else {
|
||||
subroutine = null;
|
||||
}
|
||||
//subroutine = resolveLabel(labelName, labelElement, true);
|
||||
}
|
||||
else {
|
||||
subroutine = builder.getCurrentSubroutine();
|
||||
// TODO : a context check
|
||||
}
|
||||
if (subroutine != null) {
|
||||
if (subroutine instanceof JetFunction || subroutine instanceof JetFunctionLiteralExpression) {
|
||||
if (returnedExpression == null) {
|
||||
builder.returnNoValue(expression, subroutine);
|
||||
}
|
||||
@@ -485,6 +509,11 @@ public class JetControlFlowProcessor {
|
||||
builder.returnValue(expression, subroutine);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (labelElement != null) {
|
||||
trace.report(NOT_A_RETURN_LABEL.on(expression, expression.getLabelName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -524,6 +553,12 @@ public class JetControlFlowProcessor {
|
||||
value(selectorExpression, false);
|
||||
}
|
||||
builder.read(expression);
|
||||
if (trace.get(BindingContext.PROCESSED, expression)) {
|
||||
JetType type = trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression);
|
||||
if (type != null && JetStandardClasses.isNothing(type)) {
|
||||
builder.jumpToError(expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void visitCall(JetCallElement call) {
|
||||
@@ -549,6 +584,12 @@ public class JetControlFlowProcessor {
|
||||
|
||||
value(expression.getCalleeExpression(), false);
|
||||
builder.read(expression);
|
||||
if (trace.get(BindingContext.PROCESSED, expression)) {
|
||||
JetType type = trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression);
|
||||
if (type != null && JetStandardClasses.isNothing(type)) {
|
||||
builder.jumpToError(expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
|
||||
@@ -11,61 +11,61 @@ import java.util.Collection;
|
||||
* @author abreslav
|
||||
*/
|
||||
public interface JetFlowInformationProvider {
|
||||
JetFlowInformationProvider THROW_EXCEPTION = new JetFlowInformationProvider() {
|
||||
@Override
|
||||
public void collectReturnedInformation(@NotNull JetElement subroutine, @NotNull Collection<JetExpression> returnedExpressions, @NotNull Collection<JetElement> elementsReturningUnit) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectReturnExpressions(@NotNull JetElement subroutine, @NotNull Collection<JetExpression> returnedExpressions) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectUnreachableExpressions(@NotNull JetElement subroutine, @NotNull Collection<JetElement> unreachableElements) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectDominatedExpressions(@NotNull JetExpression dominator, @NotNull Collection<JetElement> dominated) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBreakable(JetLoopExpression loop) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
JetFlowInformationProvider NONE = new JetFlowInformationProvider() {
|
||||
@Override
|
||||
public void collectReturnedInformation(@NotNull JetElement subroutine, @NotNull Collection<JetExpression> returnedExpressions, @NotNull Collection<JetElement> elementsReturningUnit) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectReturnExpressions(@NotNull JetElement subroutine, @NotNull Collection<JetExpression> returnedExpressions) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectUnreachableExpressions(@NotNull JetElement subroutine, @NotNull Collection<JetElement> unreachableElements) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectDominatedExpressions(@NotNull JetExpression dominator, @NotNull Collection<JetElement> dominated) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBreakable(JetLoopExpression loop) {
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
// JetFlowInformationProvider THROW_EXCEPTION = new JetFlowInformationProvider() {
|
||||
// @Override
|
||||
// public void collectReturnedInformation(@NotNull JetElement subroutine, @NotNull Collection<JetExpression> returnedExpressions, @NotNull Collection<JetElement> elementsReturningUnit) {
|
||||
// throw new UnsupportedOperationException();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void collectReturnExpressions(@NotNull JetElement subroutine, @NotNull Collection<JetExpression> returnedExpressions) {
|
||||
// throw new UnsupportedOperationException();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void collectUnreachableExpressions(@NotNull JetElement subroutine, @NotNull Collection<JetElement> unreachableElements) {
|
||||
// throw new UnsupportedOperationException();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void collectDominatedExpressions(@NotNull JetExpression dominator, @NotNull Collection<JetElement> dominated) {
|
||||
// throw new UnsupportedOperationException();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isBreakable(JetLoopExpression loop) {
|
||||
// throw new UnsupportedOperationException();
|
||||
// }
|
||||
//
|
||||
// };
|
||||
//
|
||||
// JetFlowInformationProvider NONE = new JetFlowInformationProvider() {
|
||||
// @Override
|
||||
// public void collectReturnedInformation(@NotNull JetElement subroutine, @NotNull Collection<JetExpression> returnedExpressions, @NotNull Collection<JetElement> elementsReturningUnit) {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void collectReturnExpressions(@NotNull JetElement subroutine, @NotNull Collection<JetExpression> returnedExpressions) {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void collectUnreachableExpressions(@NotNull JetElement subroutine, @NotNull Collection<JetElement> unreachableElements) {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void collectDominatedExpressions(@NotNull JetExpression dominator, @NotNull Collection<JetElement> dominated) {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isBreakable(JetLoopExpression loop) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// };
|
||||
|
||||
/**
|
||||
* Collects expressions returned from the given subroutine and 'return;' expressions
|
||||
|
||||
+5
@@ -250,6 +250,11 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
||||
public void jumpToError(JetThrowExpression expression) {
|
||||
add(new UnconditionalJumpInstruction(error));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpToError(JetExpression nothingExpression) {
|
||||
add(new UnconditionalJumpInstruction(error));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterTryFinally(@NotNull GenerationTrigger generationTrigger) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.jetbrains.jet.lang.descriptors;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ImplicitReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||
@@ -14,7 +13,10 @@ import java.util.Set;
|
||||
*/
|
||||
public interface CallableDescriptor extends DeclarationDescriptor {
|
||||
@NotNull
|
||||
ReceiverDescriptor getReceiver();
|
||||
ReceiverDescriptor getReceiverParameter();
|
||||
|
||||
@NotNull
|
||||
ReceiverDescriptor getExpectedThisObject();
|
||||
|
||||
@NotNull
|
||||
List<TypeParameterDescriptor> getTypeParameters();
|
||||
|
||||
+16
-3
@@ -3,6 +3,8 @@ package org.jetbrains.jet.lang.descriptors;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -28,16 +30,27 @@ public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public FunctionDescriptorImpl initialize(@Nullable JetType receiverType, @NotNull List<TypeParameterDescriptor> typeParameters, @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters, @Nullable JetType unsubstitutedReturnType, Modality modality, @NotNull Visibility visibility) {
|
||||
public FunctionDescriptorImpl initialize(@Nullable JetType receiverType, @NotNull ReceiverDescriptor expectedThisObject, @NotNull List<TypeParameterDescriptor> typeParameters, @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters, @Nullable JetType unsubstitutedReturnType, Modality modality, @NotNull Visibility visibility) {
|
||||
assert receiverType == null;
|
||||
return super.initialize(null, typeParameters, unsubstitutedValueParameters, unsubstitutedReturnType, modality, visibility);
|
||||
return super.initialize(null, expectedThisObject, typeParameters, unsubstitutedValueParameters, unsubstitutedReturnType, modality, visibility);
|
||||
}
|
||||
|
||||
public ConstructorDescriptorImpl initialize(@NotNull List<TypeParameterDescriptor> typeParameters, @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters, Modality modality, Visibility visibility) {
|
||||
super.initialize(null, typeParameters, unsubstitutedValueParameters, null, modality, visibility);
|
||||
super.initialize(null, getExpectedThisObject(getContainingDeclaration()), typeParameters, unsubstitutedValueParameters, null, modality, visibility);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ReceiverDescriptor getExpectedThisObject(@NotNull DeclarationDescriptor descriptor) {
|
||||
if (descriptor instanceof ConstructorDescriptor) {
|
||||
ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) descriptor;
|
||||
ClassDescriptor classDescriptor = constructorDescriptor.getContainingDeclaration();
|
||||
return getExpectedThisObject(classDescriptor);
|
||||
}
|
||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||
return DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ClassDescriptor getContainingDeclaration() {
|
||||
|
||||
+25
-4
@@ -8,6 +8,7 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver;
|
||||
import org.jetbrains.jet.lang.types.DescriptorSubstitutor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||
@@ -27,6 +28,7 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
|
||||
private List<ValueParameterDescriptor> unsubstitutedValueParameters;
|
||||
private JetType unsubstitutedReturnType;
|
||||
private ReceiverDescriptor receiver;
|
||||
private ReceiverDescriptor expectedThisObject;
|
||||
|
||||
private Modality modality;
|
||||
private Visibility visibility;
|
||||
@@ -51,6 +53,7 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
|
||||
|
||||
public FunctionDescriptorImpl initialize(
|
||||
@Nullable JetType receiverType,
|
||||
@NotNull ReceiverDescriptor expectedThisObject,
|
||||
@NotNull List<TypeParameterDescriptor> typeParameters,
|
||||
@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
|
||||
@Nullable JetType unsubstitutedReturnType,
|
||||
@@ -62,6 +65,7 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
|
||||
this.modality = modality;
|
||||
this.visibility = visibility;
|
||||
this.receiver = receiverType == null ? NO_RECEIVER : new ExtensionReceiver(this, receiverType);
|
||||
this.expectedThisObject = expectedThisObject;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -71,10 +75,16 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ReceiverDescriptor getReceiver() {
|
||||
public ReceiverDescriptor getReceiverParameter() {
|
||||
return receiver;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ReceiverDescriptor getExpectedThisObject() {
|
||||
return expectedThisObject;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<? extends FunctionDescriptor> getOverriddenDescriptors() {
|
||||
@@ -132,12 +142,21 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
|
||||
TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(getTypeParameters(), originalSubstitutor, substitutedDescriptor, substitutedTypeParameters);
|
||||
|
||||
JetType substitutedReceiverType = null;
|
||||
if (receiver != NO_RECEIVER) {
|
||||
substitutedReceiverType = substitutor.substitute(getReceiver().getType(), Variance.IN_VARIANCE);
|
||||
if (receiver.exists()) {
|
||||
substitutedReceiverType = substitutor.substitute(getReceiverParameter().getType(), Variance.IN_VARIANCE);
|
||||
if (substitutedReceiverType == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
ReceiverDescriptor substitutedExpectedThis = NO_RECEIVER;
|
||||
if (expectedThisObject.exists()) {
|
||||
JetType substitutedType = substitutor.substitute(expectedThisObject.getType(), Variance.INVARIANT);
|
||||
if (substitutedType == null) {
|
||||
return null;
|
||||
}
|
||||
substitutedExpectedThis = new TransientReceiver(substitutedType);
|
||||
}
|
||||
|
||||
List<ValueParameterDescriptor> substitutedValueParameters = FunctionDescriptorUtil.getSubstitutedValueParameters(substitutedDescriptor, this, substitutor);
|
||||
if (substitutedValueParameters == null) {
|
||||
@@ -151,6 +170,7 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
|
||||
|
||||
substitutedDescriptor.initialize(
|
||||
substitutedReceiverType,
|
||||
substitutedExpectedThis,
|
||||
substitutedTypeParameters,
|
||||
substitutedValueParameters,
|
||||
substitutedReturnType,
|
||||
@@ -181,7 +201,8 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
|
||||
public FunctionDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract) {
|
||||
FunctionDescriptorImpl copy = new FunctionDescriptorImpl(newOwner, Lists.newArrayList(getAnnotations()), getName());
|
||||
copy.initialize(
|
||||
getReceiver().exists() ? getReceiver().getType() : null,
|
||||
getReceiverParameter().exists() ? getReceiverParameter().getType() : null,
|
||||
expectedThisObject,
|
||||
DescriptorUtils.copyTypeParameters(copy, typeParameters),
|
||||
DescriptorUtils.copyValueParameters(copy, unsubstitutedValueParameters),
|
||||
unsubstitutedReturnType,
|
||||
|
||||
+1
-1
@@ -95,7 +95,7 @@ public class FunctionDescriptorUtil {
|
||||
@NotNull
|
||||
public static JetScope getFunctionInnerScope(@NotNull JetScope outerScope, @NotNull FunctionDescriptor descriptor, @NotNull BindingTrace trace) {
|
||||
WritableScope parameterScope = new WritableScopeImpl(outerScope, descriptor, new TraceBasedRedeclarationHandler(trace)).setDebugName("Function inner scope");
|
||||
ReceiverDescriptor receiver = descriptor.getReceiver();
|
||||
ReceiverDescriptor receiver = descriptor.getReceiverParameter();
|
||||
if (receiver.exists()) {
|
||||
parameterScope.setImplicitReceiver(receiver);
|
||||
}
|
||||
|
||||
+13
@@ -2,6 +2,7 @@ package org.jetbrains.jet.lang.descriptors;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -77,6 +78,18 @@ public abstract class PropertyAccessorDescriptor extends DeclarationDescriptorIm
|
||||
return correspondingProperty;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ReceiverDescriptor getReceiverParameter() {
|
||||
return getCorrespondingProperty().getReceiverParameter();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ReceiverDescriptor getExpectedThisObject() {
|
||||
return getCorrespondingProperty().getExpectedThisObject();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PropertyAccessorDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract) {
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||
import org.jetbrains.jet.lang.types.Variance;
|
||||
@@ -24,6 +25,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
||||
private final Visibility visibility;
|
||||
private final boolean isVar;
|
||||
private final ReceiverDescriptor receiver;
|
||||
private final ReceiverDescriptor expectedThisObject;
|
||||
private final Set<PropertyDescriptor> overriddenProperties = Sets.newLinkedHashSet();
|
||||
private final List<TypeParameterDescriptor> typeParemeters = Lists.newArrayListWithCapacity(0);
|
||||
private final PropertyDescriptor original;
|
||||
@@ -38,6 +40,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
||||
@NotNull Visibility visibility,
|
||||
boolean isVar,
|
||||
@Nullable JetType receiverType,
|
||||
@NotNull ReceiverDescriptor expectedThisObject,
|
||||
@NotNull String name,
|
||||
@Nullable JetType inType,
|
||||
@NotNull JetType outType) {
|
||||
@@ -48,6 +51,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
||||
this.modality = modality;
|
||||
this.visibility = visibility;
|
||||
this.receiver = receiverType == null ? ReceiverDescriptor.NO_RECEIVER : new ExtensionReceiver(this, receiverType);
|
||||
this.expectedThisObject = expectedThisObject;
|
||||
this.original = original == null ? this : original.getOriginal();
|
||||
}
|
||||
|
||||
@@ -58,15 +62,17 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
||||
@NotNull Visibility visibility,
|
||||
boolean isVar,
|
||||
@Nullable JetType receiverType,
|
||||
@NotNull ReceiverDescriptor expectedThisObject,
|
||||
@NotNull String name,
|
||||
@Nullable JetType inType,
|
||||
@NotNull JetType outType) {
|
||||
this(null, containingDeclaration, annotations, modality, visibility, isVar, receiverType, name, inType, outType);
|
||||
this(null, containingDeclaration, annotations, modality, visibility, isVar, receiverType, expectedThisObject, name, inType, outType);
|
||||
}
|
||||
|
||||
private PropertyDescriptor(
|
||||
@NotNull PropertyDescriptor original,
|
||||
@Nullable JetType receiverType,
|
||||
@NotNull ReceiverDescriptor expectedThisObject,
|
||||
@Nullable JetType inType,
|
||||
@NotNull JetType outType) {
|
||||
this(
|
||||
@@ -77,6 +83,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
||||
original.getVisibility(),
|
||||
original.isVar,
|
||||
receiverType,
|
||||
expectedThisObject,
|
||||
original.getName(),
|
||||
inType,
|
||||
outType);
|
||||
@@ -95,10 +102,16 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ReceiverDescriptor getReceiver() {
|
||||
public ReceiverDescriptor getReceiverParameter() {
|
||||
return receiver;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ReceiverDescriptor getExpectedThisObject() {
|
||||
return expectedThisObject;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetType getReturnType() {
|
||||
@@ -132,7 +145,6 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
||||
return setter;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PropertyDescriptor substitute(TypeSubstitutor substitutor) {
|
||||
JetType originalInType = getInType();
|
||||
@@ -142,9 +154,18 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
||||
if (inType == null && outType == null) {
|
||||
return null; // TODO : tell the user that the property was projected out
|
||||
}
|
||||
JetType substitutedReceiverType;
|
||||
if (receiver.exists()) {
|
||||
substitutedReceiverType = substitutor.substitute(receiver.getType(), Variance.IN_VARIANCE);
|
||||
if (substitutedReceiverType == null) return null;
|
||||
}
|
||||
else {
|
||||
substitutedReceiverType = null;
|
||||
}
|
||||
return new PropertyDescriptor(
|
||||
this,
|
||||
receiver.exists() ? substitutor.substitute(receiver.getType(), Variance.IN_VARIANCE) : null,
|
||||
substitutedReceiverType,
|
||||
expectedThisObject.exists() ? new TransientReceiver(substitutor.substitute(expectedThisObject.getType(), Variance.IN_VARIANCE)) : expectedThisObject,
|
||||
inType,
|
||||
outType
|
||||
);
|
||||
@@ -171,6 +192,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
||||
return overriddenProperties;
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PropertyDescriptor copy(DeclarationDescriptor newOwner, boolean makeNonAbstract) {
|
||||
@@ -178,7 +200,9 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
||||
newOwner,
|
||||
Lists.newArrayList(getAnnotations()),
|
||||
DescriptorUtils.convertModality(modality, makeNonAbstract), visibility, isVar,
|
||||
receiver.exists() ? receiver.getType() : null, getName(), getInType(), getOutType());
|
||||
receiver.exists() ? receiver.getType() : null,
|
||||
expectedThisObject,
|
||||
getName(), getInType(), getOutType());
|
||||
PropertyGetterDescriptor newGetter = getter == null ? null : new PropertyGetterDescriptor(
|
||||
propertyDescriptor, Lists.newArrayList(getter.getAnnotations()),
|
||||
DescriptorUtils.convertModality(getter.getModality(), makeNonAbstract), getter.getVisibility(),
|
||||
|
||||
@@ -33,12 +33,6 @@ public class PropertyGetterDescriptor extends PropertyAccessorDescriptor {
|
||||
overriddenGetters.add(overriddenGetter);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ReceiverDescriptor getReceiver() {
|
||||
return getCorrespondingProperty().getReceiver();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<ValueParameterDescriptor> getValueParameters() {
|
||||
|
||||
@@ -3,7 +3,6 @@ package org.jetbrains.jet.lang.descriptors;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
@@ -42,12 +41,6 @@ public class PropertySetterDescriptor extends PropertyAccessorDescriptor {
|
||||
overriddenSetters.add(overriddenSetter);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ReceiverDescriptor getReceiver() {
|
||||
return getCorrespondingProperty().getReceiver();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<ValueParameterDescriptor> getValueParameters() {
|
||||
|
||||
+2
-1
@@ -2,6 +2,7 @@ package org.jetbrains.jet.lang.descriptors;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
@@ -16,7 +17,7 @@ public class VariableAsFunctionDescriptor extends FunctionDescriptorImpl {
|
||||
assert outType != null;
|
||||
assert JetStandardClasses.isFunctionType(outType);
|
||||
VariableAsFunctionDescriptor result = new VariableAsFunctionDescriptor(variableDescriptor);
|
||||
result.initialize(JetStandardClasses.getReceiverType(outType), Collections.<TypeParameterDescriptor>emptyList(), JetStandardClasses.getValueParameters(result, outType), JetStandardClasses.getReturnType(outType), Modality.FINAL, Visibility.LOCAL);
|
||||
result.initialize(JetStandardClasses.getReceiverType(outType), ReceiverDescriptor.NO_RECEIVER, Collections.<TypeParameterDescriptor>emptyList(), JetStandardClasses.getValueParameters(result, outType), JetStandardClasses.getReturnType(outType), Modality.FINAL, Visibility.LOCAL);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ public interface VariableDescriptor extends CallableDescriptor {
|
||||
@NotNull
|
||||
DeclarationDescriptor getContainingDeclaration();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
VariableDescriptor substitute(TypeSubstitutor substitutor);
|
||||
|
||||
|
||||
+7
-1
@@ -74,7 +74,13 @@ public abstract class VariableDescriptorImpl extends DeclarationDescriptorImpl i
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ReceiverDescriptor getReceiver() {
|
||||
public ReceiverDescriptor getReceiverParameter() {
|
||||
return ReceiverDescriptor.NO_RECEIVER;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ReceiverDescriptor getExpectedThisObject() {
|
||||
return ReceiverDescriptor.NO_RECEIVER;
|
||||
}
|
||||
|
||||
|
||||
+6
-5
@@ -1,7 +1,8 @@
|
||||
package org.jetbrains.jet.lang.diagnostics;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -9,7 +10,7 @@ import java.util.Collection;
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class AmbiguousDescriptorDiagnosticFactory extends ParameterizedDiagnosticFactory1<Collection<? extends CallableDescriptor>> {
|
||||
public class AmbiguousDescriptorDiagnosticFactory extends ParameterizedDiagnosticFactory1<Collection<? extends ResolvedCall<? extends DeclarationDescriptor>>> {
|
||||
public static AmbiguousDescriptorDiagnosticFactory create(String messageTemplate) {
|
||||
return new AmbiguousDescriptorDiagnosticFactory(messageTemplate);
|
||||
}
|
||||
@@ -19,10 +20,10 @@ public class AmbiguousDescriptorDiagnosticFactory extends ParameterizedDiagnosti
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String makeMessageFor(@NotNull Collection<? extends CallableDescriptor> argument) {
|
||||
protected String makeMessageFor(@NotNull Collection<? extends ResolvedCall<? extends DeclarationDescriptor>> argument) {
|
||||
StringBuilder stringBuilder = new StringBuilder("\n");
|
||||
for (CallableDescriptor descriptor : argument) {
|
||||
stringBuilder.append(DescriptorRenderer.TEXT.render(descriptor)).append("\n");
|
||||
for (ResolvedCall<? extends DeclarationDescriptor> call : argument) {
|
||||
stringBuilder.append(DescriptorRenderer.TEXT.render(call.getResultingDescriptor())).append("\n");
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ public interface Errors {
|
||||
return sb.toString();
|
||||
}
|
||||
};
|
||||
ParameterizedDiagnosticFactory1<JetKeywordToken> ILLEGAL_MODIFIER = ParameterizedDiagnosticFactory1.create(ERROR, "Illegal modifier ''{0}''");
|
||||
DiagnosticWithParameterFactory<JetModifierList, JetKeywordToken> ILLEGAL_MODIFIER = DiagnosticWithParameterFactory.create(ERROR, "Illegal modifier ''{0}''", DiagnosticParameters.MODIFIER);
|
||||
|
||||
PsiElementOnlyDiagnosticFactory2<JetModifierList, JetKeywordToken, JetKeywordToken> REDUNDANT_MODIFIER = new PsiElementOnlyDiagnosticFactory2<JetModifierList, JetKeywordToken, JetKeywordToken>(Severity.WARNING, "Modifier {0} is redundant because {1} is present") {
|
||||
@NotNull
|
||||
@@ -69,6 +69,7 @@ public interface Errors {
|
||||
}
|
||||
};
|
||||
DiagnosticWithParameterFactory<JetModifierList, JetKeywordToken> REDUNDANT_MODIFIER_IN_TRAIT = DiagnosticWithParameterFactory.create(WARNING, "Modifier ''{0}'' is redundant in trait", DiagnosticParameters.MODIFIER);
|
||||
DiagnosticWithParameterFactory<JetModifierList, JetKeywordToken> REDUNDANT_MODIFIER_IN_GETTER = DiagnosticWithParameterFactory.create(WARNING, "Visibility modifiers are redundant in getter", DiagnosticParameters.MODIFIER);
|
||||
SimplePsiElementOnlyDiagnosticFactory<JetClass> TRAIT_CAN_NOT_BE_FINAL = SimplePsiElementOnlyDiagnosticFactory.create(ERROR, "Trait can not be final");
|
||||
SimpleDiagnosticFactory SAFE_CALLS_ARE_NOT_ALLOWED_ON_NAMESPACES = SimpleDiagnosticFactory.create(ERROR, "Safe calls are not allowed on namespaces");
|
||||
SimpleDiagnosticFactory TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM = SimpleDiagnosticFactory.create(ERROR, "Type checking has run into a recursive problem"); // TODO: message
|
||||
@@ -94,6 +95,8 @@ public interface Errors {
|
||||
DiagnosticWithParameterFactory<JetProperty, JetType> ABSTRACT_PROPERTY_WITH_INITIALIZER = DiagnosticWithParameterFactory.create(ERROR, "Property with initializer cannot be abstract", DiagnosticParameters.TYPE);
|
||||
DiagnosticWithParameterFactory<JetProperty, JetType> ABSTRACT_PROPERTY_WITH_GETTER = DiagnosticWithParameterFactory.create(ERROR, "Property with getter implementation cannot be abstract", DiagnosticParameters.TYPE);
|
||||
DiagnosticWithParameterFactory<JetProperty, JetType> ABSTRACT_PROPERTY_WITH_SETTER = DiagnosticWithParameterFactory.create(ERROR, "Property with setter implementation cannot be abstract", DiagnosticParameters.TYPE);
|
||||
|
||||
DiagnosticWithParameterFactory<JetModifierList, JetKeywordToken> GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY = DiagnosticWithParameterFactory.create(ERROR, "Getter visibility must be the same as property visibility", DiagnosticParameters.MODIFIER);
|
||||
SimpleDiagnosticFactory BACKING_FIELD_IN_TRAIT = SimpleDiagnosticFactory.create(ERROR, "Property in a trait cannot have a backing field");
|
||||
SimpleDiagnosticFactory MUST_BE_INITIALIZED = SimpleDiagnosticFactory.create(ERROR, "Property must be initialized");
|
||||
SimplePsiElementOnlyDiagnosticFactory<JetModifierListOwner> MUST_BE_INITIALIZED_OR_BE_ABSTRACT = SimplePsiElementOnlyDiagnosticFactory.create(ERROR, "Property must be initialized or be abstract");
|
||||
@@ -106,22 +109,21 @@ public interface Errors {
|
||||
return super.on(elementToBlame, textRangeToMark, s, classDescriptor, aClass).add(DiagnosticParameters.CLASS, aClass);
|
||||
}
|
||||
};
|
||||
PsiElementOnlyDiagnosticFactory3<JetFunctionOrPropertyAccessor, String, ClassDescriptor, JetClass> ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS = new PsiElementOnlyDiagnosticFactory3<JetFunctionOrPropertyAccessor, String, ClassDescriptor, JetClass>(ERROR, "Abstract function {0} in non-abstract class {1}") {
|
||||
PsiElementOnlyDiagnosticFactory3<JetFunction, String, ClassDescriptor, JetClass> ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS = new PsiElementOnlyDiagnosticFactory3<JetFunction, String, ClassDescriptor, JetClass>(ERROR, "Abstract function {0} in non-abstract class {1}") {
|
||||
@NotNull
|
||||
public DiagnosticWithPsiElement<JetFunctionOrPropertyAccessor> on(@NotNull JetFunctionOrPropertyAccessor elementToBlame, @NotNull ASTNode nodeToMark, @NotNull String s, @NotNull ClassDescriptor classDescriptor, @NotNull JetClass modifierListOwner) {
|
||||
public DiagnosticWithPsiElement<JetFunction> on(@NotNull JetFunction elementToBlame, @NotNull ASTNode nodeToMark, @NotNull String s, @NotNull ClassDescriptor classDescriptor, @NotNull JetClass modifierListOwner) {
|
||||
return super.on(elementToBlame, nodeToMark, s, classDescriptor, modifierListOwner).add(DiagnosticParameters.CLASS, modifierListOwner);
|
||||
}
|
||||
};
|
||||
PsiElementOnlyDiagnosticFactory1<JetFunctionOrPropertyAccessor, FunctionDescriptor> ABSTRACT_FUNCTION_WITH_BODY = PsiElementOnlyDiagnosticFactory1.create(ERROR, "A function {0} with body cannot be abstract");
|
||||
PsiElementOnlyDiagnosticFactory1<JetFunctionOrPropertyAccessor, FunctionDescriptor> NON_ABSTRACT_FUNCTION_WITH_NO_BODY = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Method {0} without a body must be abstract");
|
||||
PsiElementOnlyDiagnosticFactory1<JetFunction, FunctionDescriptor> ABSTRACT_FUNCTION_WITH_BODY = PsiElementOnlyDiagnosticFactory1.create(ERROR, "A function {0} with body cannot be abstract");
|
||||
PsiElementOnlyDiagnosticFactory1<JetFunction, FunctionDescriptor> NON_ABSTRACT_FUNCTION_WITH_NO_BODY = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Method {0} without a body must be abstract");
|
||||
PsiElementOnlyDiagnosticFactory1<JetModifierListOwner, FunctionDescriptor> NON_MEMBER_ABSTRACT_FUNCTION = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Function {0} is not a class or trait member and cannot be abstract");
|
||||
SimplePsiElementOnlyDiagnosticFactory<JetModifierListOwner> NON_MEMBER_ABSTRACT_ACCESSOR = SimplePsiElementOnlyDiagnosticFactory.create(ERROR, "This property is not a class or trait member and thus cannot have abstract accessors"); // TODO : Better message
|
||||
|
||||
PsiElementOnlyDiagnosticFactory1<JetFunctionOrPropertyAccessor, FunctionDescriptor> NON_MEMBER_FUNCTION_NO_BODY = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Function {0} must have a body");
|
||||
PsiElementOnlyDiagnosticFactory1<JetFunction, FunctionDescriptor> NON_MEMBER_FUNCTION_NO_BODY = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Function {0} must have a body");
|
||||
|
||||
DiagnosticWithParameterFactory<JetNamedDeclaration, JetClass> NON_FINAL_MEMBER_IN_FINAL_CLASS = DiagnosticWithParameterFactory.create(ERROR, "Non final member in a final class", DiagnosticParameters.CLASS);
|
||||
DiagnosticWithParameterFactory<JetPropertyAccessor, JetProperty> NON_FINAL_ACCESSOR_OF_FINAL_PROPERTY = DiagnosticWithParameterFactory.create(ERROR, "Non final accessor of a final property", DiagnosticParameters.PROPERTY);
|
||||
DiagnosticWithParameterFactory<JetPropertyAccessor, JetProperty> ABSTRACT_ACCESSOR_OF_NON_ABSTRACT_PROPERTY = DiagnosticWithParameterFactory.create(ERROR, "Abstract accessor of a final property", DiagnosticParameters.PROPERTY);
|
||||
|
||||
DiagnosticWithParameterFactory<JetNamedDeclaration, JetType> PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE = DiagnosticWithParameterFactory.create(ERROR, "Public member should specify a type", DiagnosticParameters.TYPE);
|
||||
|
||||
SimpleDiagnosticFactory PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT = SimpleDiagnosticFactory.create(ERROR, "Projections are not allowed on type arguments of functions and properties"); // TODO : better positioning
|
||||
SimpleDiagnosticFactory SUPERTYPE_NOT_INITIALIZED = SimpleDiagnosticFactory.create(ERROR, "This type has a constructor, and thus must be initialized here");
|
||||
@@ -130,7 +132,7 @@ public interface Errors {
|
||||
SimpleDiagnosticFactory BY_IN_SECONDARY_CONSTRUCTOR = SimpleDiagnosticFactory.create(ERROR, "'by'-clause is only supported for primary constructors");
|
||||
SimpleDiagnosticFactory INITIALIZER_WITH_NO_ARGUMENTS = SimpleDiagnosticFactory.create(ERROR, "Constructor arguments required");
|
||||
SimpleDiagnosticFactory MANY_CALLS_TO_THIS = SimpleDiagnosticFactory.create(ERROR, "Only one call to 'this(...)' is allowed");
|
||||
PsiElementOnlyDiagnosticFactory1<JetModifierListOwner, CallableMemberDescriptor> NOTHING_TO_OVERRIDE = PsiElementOnlyDiagnosticFactory1.create(ERROR, "{0} overrides nothing", DescriptorRenderer.TEXT);
|
||||
PsiElementOnlyDiagnosticFactory1<JetModifierList, CallableMemberDescriptor> NOTHING_TO_OVERRIDE = PsiElementOnlyDiagnosticFactory1.create(ERROR, "{0} overrides nothing", DescriptorRenderer.TEXT);
|
||||
PsiElementOnlyDiagnosticFactory1<JetClass, PropertyDescriptor> PRIMARY_CONSTRUCTOR_MISSING_STATEFUL_PROPERTY = PsiElementOnlyDiagnosticFactory1.create(ERROR, "This class must have a primary constructor, because property {0} has a backing field");
|
||||
ParameterizedDiagnosticFactory1<JetClassOrObject> PRIMARY_CONSTRUCTOR_MISSING_SUPER_CONSTRUCTOR_CALL = new ParameterizedDiagnosticFactory1<JetClassOrObject>(ERROR, "Class {0} must have a constructor in order to be able to initialize supertypes") {
|
||||
@Override
|
||||
@@ -141,7 +143,6 @@ public interface Errors {
|
||||
PsiElementOnlyDiagnosticFactory3<JetModifierListOwner, CallableMemberDescriptor, CallableMemberDescriptor, DeclarationDescriptor> VIRTUAL_MEMBER_HIDDEN = PsiElementOnlyDiagnosticFactory3.create(ERROR, "''{0}'' hides ''{1}'' in class {2} and needs 'override' modifier", DescriptorRenderer.TEXT);
|
||||
|
||||
SimpleDiagnosticFactory UNREACHABLE_CODE = SimpleDiagnosticFactory.create(ERROR, "Unreachable code");
|
||||
ParameterizedDiagnosticFactory1<String> UNREACHABLE_BECAUSE_OF_NOTHING = ParameterizedDiagnosticFactory1.create(ERROR, "This code is unreachable, because ''{0}'' never terminates normally");
|
||||
|
||||
SimpleDiagnosticFactory MANY_CLASS_OBJECTS = SimpleDiagnosticFactory.create(ERROR, "Only one class object is allowed per class");
|
||||
SimpleDiagnosticFactory CLASS_OBJECT_NOT_ALLOWED = SimpleDiagnosticFactory.create(ERROR, "A class object is not allowed here");
|
||||
@@ -189,6 +190,7 @@ public interface Errors {
|
||||
SimpleDiagnosticFactory RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY = SimpleDiagnosticFactory.create(ERROR, "Returns are not allowed for functions with expression body. Use block body in '{...}'");
|
||||
SimpleDiagnosticFactory NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY = SimpleDiagnosticFactory.create(ERROR, "A 'return' expression required in a function with a block body ('{...}')");
|
||||
ParameterizedDiagnosticFactory1<JetType> RETURN_TYPE_MISMATCH = ParameterizedDiagnosticFactory1.create(ERROR, "This function must return a value of type {0}");
|
||||
ParameterizedDiagnosticFactory1<JetType> EXPECTED_TYPE_MISMATCH = ParameterizedDiagnosticFactory1.create(ERROR, "Expected a value of type {0}");
|
||||
|
||||
ParameterizedDiagnosticFactory1<JetType> UPPER_BOUND_VIOLATED = ParameterizedDiagnosticFactory1.create(ERROR, "An upper bound {0} is violated"); // TODO : Message
|
||||
ParameterizedDiagnosticFactory1<JetType> FINAL_CLASS_OBJECT_UPPER_BOUND = ParameterizedDiagnosticFactory1.create(ERROR, "{0} is a final type, and thus a class object cannot extend it");
|
||||
@@ -219,6 +221,7 @@ public interface Errors {
|
||||
SimpleDiagnosticFactory VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION = SimpleDiagnosticFactory.create(ERROR, "A type annotation is required on a value parameter");
|
||||
SimpleDiagnosticFactory BREAK_OR_CONTINUE_OUTSIDE_A_LOOP = SimpleDiagnosticFactory.create(ERROR, "'break' and 'continue' are only allowed inside a loop");
|
||||
ParameterizedDiagnosticFactory1<String> NOT_A_LOOP_LABEL = ParameterizedDiagnosticFactory1.create(ERROR, "The label ''{0}'' does not denote a loop");
|
||||
ParameterizedDiagnosticFactory1<String> NOT_A_RETURN_LABEL = ParameterizedDiagnosticFactory1.create(ERROR, "The label ''{0}'' does not reference to a context from which we can return");
|
||||
|
||||
SimpleDiagnosticFactory ANONYMOUS_INITIALIZER_WITHOUT_CONSTRUCTOR = SimpleDiagnosticFactory.create(ERROR, "Anonymous initializers are only allowed in the presence of a primary constructor");
|
||||
SimpleDiagnosticFactory NULLABLE_SUPERTYPE = SimpleDiagnosticFactory.create(ERROR, "A supertype cannot be nullable");
|
||||
@@ -237,7 +240,7 @@ public interface Errors {
|
||||
return constraintOwner.getName();
|
||||
}
|
||||
};
|
||||
ParameterizedDiagnosticFactory2<JetType, VariableDescriptor> AUTOCAST_IMPOSSIBLE = ParameterizedDiagnosticFactory2.create(ERROR, "Automatic cast to {0} is impossible, because variable {1} is mutable", NAME);
|
||||
ParameterizedDiagnosticFactory2<JetType, String> AUTOCAST_IMPOSSIBLE = ParameterizedDiagnosticFactory2.create(ERROR, "Automatic cast to {0} is impossible, because {1} could have changed since the is-check");
|
||||
|
||||
ParameterizedDiagnosticFactory2<JetType, JetType> TYPE_MISMATCH_IN_FOR_LOOP = ParameterizedDiagnosticFactory2.create(ERROR, "The loop iterates over values of type {0} but the parameter is declared to be {1}");
|
||||
ParameterizedDiagnosticFactory1<JetType> TYPE_MISMATCH_IN_CONDITION = ParameterizedDiagnosticFactory1.create(ERROR, "Condition must be of type Boolean, but was of type {0}");
|
||||
@@ -348,10 +351,10 @@ public interface Errors {
|
||||
};
|
||||
|
||||
ParameterizedDiagnosticFactory3<String, JetType, JetType> RESULT_TYPE_MISMATCH = ParameterizedDiagnosticFactory3.create(ERROR, "{0} must return {1} but returns {2}");
|
||||
ParameterizedDiagnosticFactory3<String, String, String> UNSAFE_INFIX_CALL = ParameterizedDiagnosticFactory3.create(ERROR, "Infix call corresponds to a dot-qualified call ''{0}.{1}({2})' which is not allowed on a nullable receiver ''{0}''. Use '?.'-qualified call instead");
|
||||
ParameterizedDiagnosticFactory3<String, String, String> UNSAFE_INFIX_CALL = ParameterizedDiagnosticFactory3.create(ERROR, "Infix call corresponds to a dot-qualified call ''{0}.{1}({2})'' which is not allowed on a nullable receiver ''{0}''. Use '?.'-qualified call instead");
|
||||
|
||||
ParameterizedDiagnosticFactory1<Collection<? extends CallableDescriptor>> OVERLOAD_RESOLUTION_AMBIGUITY = new AmbiguousDescriptorDiagnosticFactory("Overload resolution ambiguity: {0}");
|
||||
ParameterizedDiagnosticFactory1<Collection<? extends CallableDescriptor>> NONE_APPLICABLE = new AmbiguousDescriptorDiagnosticFactory("None of the following functions can be called with the arguments supplied: {0}");
|
||||
AmbiguousDescriptorDiagnosticFactory OVERLOAD_RESOLUTION_AMBIGUITY = new AmbiguousDescriptorDiagnosticFactory("Overload resolution ambiguity: {0}");
|
||||
AmbiguousDescriptorDiagnosticFactory NONE_APPLICABLE = new AmbiguousDescriptorDiagnosticFactory("None of the following functions can be called with the arguments supplied: {0}");
|
||||
ParameterizedDiagnosticFactory1<ValueParameterDescriptor> NO_VALUE_FOR_PARAMETER = ParameterizedDiagnosticFactory1.create(ERROR, "No value passed for parameter {0}", DescriptorRenderer.TEXT);
|
||||
ParameterizedDiagnosticFactory1<JetType> MISSING_RECEIVER = ParameterizedDiagnosticFactory1.create(ERROR, "A receiver of type {0} is required");
|
||||
SimpleDiagnosticFactory NO_RECEIVER_ADMITTED = SimpleDiagnosticFactory.create(ERROR, "No receiver can be passed to this function or property");
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package org.jetbrains.jet.lang.psi;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -9,6 +12,14 @@ import java.util.List;
|
||||
* @author abreslav
|
||||
*/
|
||||
public interface Call {
|
||||
|
||||
// SAFE_ACCESS or DOT or so
|
||||
@Nullable
|
||||
ASTNode getCallOperationNode();
|
||||
|
||||
@NotNull
|
||||
ReceiverDescriptor getExplicitReceiver();
|
||||
|
||||
@Nullable
|
||||
JetExpression getCalleeExpression();
|
||||
|
||||
@@ -26,4 +37,10 @@ public interface Call {
|
||||
|
||||
@Nullable
|
||||
JetTypeArgumentList getTypeArgumentList();
|
||||
|
||||
@NotNull
|
||||
ASTNode getCallNode();
|
||||
|
||||
@Nullable
|
||||
PsiElement getCallElement();
|
||||
}
|
||||
|
||||
@@ -9,6 +9,22 @@ import java.util.List;
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public interface JetCallElement extends PsiElement, Call {
|
||||
public interface JetCallElement extends PsiElement {
|
||||
@Nullable
|
||||
JetExpression getCalleeExpression();
|
||||
|
||||
@Nullable
|
||||
JetValueArgumentList getValueArgumentList();
|
||||
|
||||
@NotNull
|
||||
List<? extends ValueArgument> getValueArguments();
|
||||
|
||||
@NotNull
|
||||
List<JetExpression> getFunctionLiteralArguments();
|
||||
|
||||
@NotNull
|
||||
List<JetTypeProjection> getTypeArguments();
|
||||
|
||||
@Nullable
|
||||
JetTypeArgumentList getTypeArgumentList();
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import org.jetbrains.jet.JetNodeType;
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public class JetExpression extends JetElement {
|
||||
public abstract class JetExpression extends JetElement {
|
||||
public JetExpression(@NotNull ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import java.util.List;
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
abstract public class JetFunction extends JetTypeParameterListOwner implements JetFunctionOrPropertyAccessor {
|
||||
abstract public class JetFunction extends JetTypeParameterListOwner implements JetDeclarationWithBody, JetModifierListOwner {
|
||||
public JetFunction(@NotNull ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
package org.jetbrains.jet.lang.psi;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public interface JetFunctionOrPropertyAccessor extends JetDeclarationWithBody, JetModifierListOwner {
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import java.util.List;
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public class JetPropertyAccessor extends JetDeclaration implements JetFunctionOrPropertyAccessor {
|
||||
public class JetPropertyAccessor extends JetDeclaration implements JetDeclarationWithBody, JetModifierListOwner {
|
||||
public JetPropertyAccessor(@NotNull ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,796 @@
|
||||
package org.jetbrains.jet.lang.psi;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class JetTreeVisitor<D> extends JetVisitor<Void, D> {
|
||||
@Override
|
||||
public Void visitNamespace(JetNamespace namespace, D data) {
|
||||
List<JetImportDirective> importDirectives = namespace.getImportDirectives();
|
||||
for (JetImportDirective directive : importDirectives) {
|
||||
directive.visit(this, data);
|
||||
}
|
||||
List<JetDeclaration> declarations = namespace.getDeclarations();
|
||||
for (JetDeclaration declaration : declarations) {
|
||||
declaration.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitClass(JetClass klass, D data) {
|
||||
List<JetDeclaration> declarations = klass.getDeclarations();
|
||||
for (JetDeclaration declaration : declarations) {
|
||||
declaration.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitClassObject(JetClassObject classObject, D data) {
|
||||
JetObjectDeclaration objectDeclaration = classObject.getObjectDeclaration();
|
||||
if (objectDeclaration != null) {
|
||||
objectDeclaration.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitConstructor(JetConstructor constructor, D data) {
|
||||
visitDeclarationWithBody(constructor, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitNamedFunction(JetNamedFunction function, D data) {
|
||||
visitDeclarationWithBody(function, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitProperty(JetProperty property, D data) {
|
||||
List<JetPropertyAccessor> accessors = property.getAccessors();
|
||||
for (JetPropertyAccessor accessor : accessors) {
|
||||
accessor.visit(this, data);
|
||||
}
|
||||
JetExpression initializer = property.getInitializer();
|
||||
if (initializer != null) {
|
||||
initializer.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitTypedef(JetTypedef typedef, D data) {
|
||||
return super.visitTypedef(typedef, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitJetFile(JetFile file, D data) {
|
||||
JetNamespace rootNamespace = file.getRootNamespace();
|
||||
return rootNamespace.visit(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitImportDirective(JetImportDirective importDirective, D data) {
|
||||
return super.visitImportDirective(importDirective, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitClassBody(JetClassBody classBody, D data) {
|
||||
List<JetDeclaration> declarations = classBody.getDeclarations();
|
||||
for (JetDeclaration declaration : declarations) {
|
||||
declaration.visit(this, data);
|
||||
}
|
||||
List<JetConstructor> secondaryConstructors = classBody.getSecondaryConstructors();
|
||||
for (JetConstructor constructor : secondaryConstructors) {
|
||||
constructor.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitNamespaceBody(JetNamespaceBody body, D data) {
|
||||
List<JetDeclaration> declarations = body.getDeclarations();
|
||||
for (JetDeclaration declaration : declarations) {
|
||||
declaration.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitModifierList(JetModifierList list, D data) {
|
||||
return super.visitModifierList(list, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitAnnotation(JetAnnotation annotation, D data) {
|
||||
return super.visitAnnotation(annotation, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitAnnotationEntry(JetAnnotationEntry annotationEntry, D data) {
|
||||
return super.visitAnnotationEntry(annotationEntry, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitTypeParameterList(JetTypeParameterList list, D data) {
|
||||
List<JetTypeParameter> parameters = list.getParameters();
|
||||
for (JetTypeParameter parameter : parameters) {
|
||||
parameter.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitTypeParameter(JetTypeParameter parameter, D data) {
|
||||
return super.visitTypeParameter(parameter, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitEnumEntry(JetEnumEntry enumEntry, D data) {
|
||||
List<JetDelegationSpecifier> delegationSpecifiers = enumEntry.getDelegationSpecifiers();
|
||||
for (JetDelegationSpecifier delegationSpecifier : delegationSpecifiers) {
|
||||
delegationSpecifier.visit(this, data);
|
||||
}
|
||||
JetModifierList modifierList = enumEntry.getModifierList();
|
||||
if (modifierList != null) {
|
||||
modifierList.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitParameterList(JetParameterList list, D data) {
|
||||
List<JetParameter> parameters = list.getParameters();
|
||||
for (JetParameter parameter : parameters) {
|
||||
parameter.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitParameter(JetParameter parameter, D data) {
|
||||
return super.visitParameter(parameter, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitDelegationSpecifierList(JetDelegationSpecifierList list, D data) {
|
||||
List<JetDelegationSpecifier> delegationSpecifiers = list.getDelegationSpecifiers();
|
||||
for (JetDelegationSpecifier delegationSpecifier : delegationSpecifiers) {
|
||||
delegationSpecifier.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitDelegationSpecifier(JetDelegationSpecifier specifier, D data) {
|
||||
return super.visitDelegationSpecifier(specifier, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitDelegationByExpressionSpecifier(JetDelegatorByExpressionSpecifier specifier, D data) {
|
||||
return super.visitDelegationByExpressionSpecifier(specifier, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitDelegationToSuperCallSpecifier(JetDelegatorToSuperCall call, D data) {
|
||||
return super.visitDelegationToSuperCallSpecifier(call, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitDelegationToSuperClassSpecifier(JetDelegatorToSuperClass specifier, D data) {
|
||||
return super.visitDelegationToSuperClassSpecifier(specifier, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitDelegationToThisCall(JetDelegatorToThisCall thisCall, D data) {
|
||||
return super.visitDelegationToThisCall(thisCall, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitTypeReference(JetTypeReference typeReference, D data) {
|
||||
return super.visitTypeReference(typeReference, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitValueArgumentList(JetValueArgumentList list, D data) {
|
||||
List<JetValueArgument> arguments = list.getArguments();
|
||||
for (JetValueArgument argument : arguments) {
|
||||
argument.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitArgument(JetValueArgument argument, D data) {
|
||||
return super.visitArgument(argument, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitLoopExpression(JetLoopExpression loopExpression, D data) {
|
||||
JetExpression body = loopExpression.getBody();
|
||||
if (body != null) {
|
||||
body.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitConstantExpression(JetConstantExpression expression, D data) {
|
||||
return super.visitConstantExpression(expression, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitSimpleNameExpression(JetSimpleNameExpression expression, D data) {
|
||||
return super.visitSimpleNameExpression(expression, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitReferenceExpression(JetReferenceExpression expression, D data) {
|
||||
return super.visitReferenceExpression(expression, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitTupleExpression(JetTupleExpression expression, D data) {
|
||||
return super.visitTupleExpression(expression, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitPrefixExpression(JetPrefixExpression expression, D data) {
|
||||
JetExpression baseExpression = expression.getBaseExpression();
|
||||
if (baseExpression != null) {
|
||||
baseExpression.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitPostfixExpression(JetPostfixExpression expression, D data) {
|
||||
JetExpression baseExpression = expression.getBaseExpression();
|
||||
baseExpression.visit(this, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitUnaryExpression(JetUnaryExpression expression, D data) {
|
||||
JetExpression baseExpression = expression.getBaseExpression();
|
||||
assert baseExpression != null;
|
||||
baseExpression.visit(this, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitBinaryExpression(JetBinaryExpression expression, D data) {
|
||||
JetExpression left = expression.getLeft();
|
||||
left.visit(this, data);
|
||||
JetExpression right = expression.getRight();
|
||||
if (right != null) {
|
||||
right.visit(this, data);
|
||||
}
|
||||
return super.visitBinaryExpression(expression, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitReturnExpression(JetReturnExpression expression, D data) {
|
||||
JetExpression returnedExpression = expression.getReturnedExpression();
|
||||
if (returnedExpression != null) {
|
||||
returnedExpression.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitLabelQualifiedExpression(JetLabelQualifiedExpression expression, D data) {
|
||||
JetExpression labeledExpression = expression.getLabeledExpression();
|
||||
if (labeledExpression != null) {
|
||||
labeledExpression.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitThrowExpression(JetThrowExpression expression, D data) {
|
||||
JetExpression thrownExpression = expression.getThrownExpression();
|
||||
if (thrownExpression != null) {
|
||||
thrownExpression.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitBreakExpression(JetBreakExpression expression, D data) {
|
||||
return super.visitBreakExpression(expression, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitContinueExpression(JetContinueExpression expression, D data) {
|
||||
return super.visitContinueExpression(expression, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitIfExpression(JetIfExpression expression, D data) {
|
||||
JetExpression condition = expression.getCondition();
|
||||
if (condition != null) {
|
||||
condition.visit(this, data);
|
||||
}
|
||||
JetExpression then = expression.getThen();
|
||||
if (then != null) {
|
||||
then.visit(this, data);
|
||||
}
|
||||
JetExpression anElse = expression.getElse();
|
||||
if (anElse != null) {
|
||||
anElse.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitWhenExpression(JetWhenExpression expression, D data) {
|
||||
List<JetWhenEntry> entries = expression.getEntries();
|
||||
for (JetWhenEntry entry : entries) {
|
||||
entry.visit(this, data);
|
||||
}
|
||||
JetExpression subjectExpression = expression.getSubjectExpression();
|
||||
if (subjectExpression != null) {
|
||||
subjectExpression.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitTryExpression(JetTryExpression expression, D data) {
|
||||
JetBlockExpression tryBlock = expression.getTryBlock();
|
||||
tryBlock.visit(this, data);
|
||||
List<JetCatchClause> catchClauses = expression.getCatchClauses();
|
||||
for (JetCatchClause catchClause : catchClauses) {
|
||||
catchClause.visit(this, data);
|
||||
}
|
||||
JetFinallySection finallyBlock = expression.getFinallyBlock();
|
||||
if (finallyBlock != null) {
|
||||
finallyBlock.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitForExpression(JetForExpression expression, D data) {
|
||||
JetParameter loopParameter = expression.getLoopParameter();
|
||||
if (loopParameter != null) {
|
||||
loopParameter.visit(this, data);
|
||||
}
|
||||
JetExpression loopRange = expression.getLoopRange();
|
||||
if (loopRange != null) {
|
||||
loopRange.visit(this, data);
|
||||
}
|
||||
visitLoopExpression(expression, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitWhileExpression(JetWhileExpression expression, D data) {
|
||||
JetExpression condition = expression.getCondition();
|
||||
if (condition != null) {
|
||||
condition.visit(this, data);
|
||||
}
|
||||
visitLoopExpression(expression, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitDoWhileExpression(JetDoWhileExpression expression, D data) {
|
||||
JetExpression condition = expression.getCondition();
|
||||
if (condition != null) {
|
||||
condition.visit(this, data);
|
||||
}
|
||||
visitLoopExpression(expression, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression, D data) {
|
||||
JetFunctionLiteral functionLiteral = expression.getFunctionLiteral();
|
||||
functionLiteral.visit(this, data);
|
||||
visitDeclarationWithBody(expression, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitAnnotatedExpression(JetAnnotatedExpression expression, D data) {
|
||||
JetExpression baseExpression = expression.getBaseExpression();
|
||||
baseExpression.visit(this, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitCallExpression(JetCallExpression expression, D data) {
|
||||
JetExpression calleeExpression = expression.getCalleeExpression();
|
||||
if (calleeExpression != null) {
|
||||
calleeExpression.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitArrayAccessExpression(JetArrayAccessExpression expression, D data) {
|
||||
JetExpression arrayExpression = expression.getArrayExpression();
|
||||
arrayExpression.visit(this, data);
|
||||
List<JetExpression> indexExpressions = expression.getIndexExpressions();
|
||||
for (JetExpression indexExpression : indexExpressions) {
|
||||
indexExpression.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitQualifiedExpression(JetQualifiedExpression expression, D data) {
|
||||
JetExpression receiver = expression.getReceiverExpression();
|
||||
receiver.visit(this, data);
|
||||
JetExpression selector = expression.getSelectorExpression();
|
||||
if (selector != null) {
|
||||
selector.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitHashQualifiedExpression(JetHashQualifiedExpression expression, D data) {
|
||||
visitQualifiedExpression(expression, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitDotQualifiedExpression(JetDotQualifiedExpression expression, D data) {
|
||||
visitQualifiedExpression(expression, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitPredicateExpression(JetPredicateExpression expression, D data) {
|
||||
visitQualifiedExpression(expression, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitSafeQualifiedExpression(JetSafeQualifiedExpression expression, D data) {
|
||||
visitQualifiedExpression(expression, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitObjectLiteralExpression(JetObjectLiteralExpression expression, D data) {
|
||||
JetObjectDeclaration objectDeclaration = expression.getObjectDeclaration();
|
||||
objectDeclaration.visit(this, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitRootNamespaceExpression(JetRootNamespaceExpression expression, D data) {
|
||||
return super.visitRootNamespaceExpression(expression, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitBlockExpression(JetBlockExpression expression, D data) {
|
||||
List<JetElement> statements = expression.getStatements();
|
||||
for (JetElement statement : statements) {
|
||||
statement.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitCatchSection(JetCatchClause catchClause, D data) {
|
||||
JetParameter catchParameter = catchClause.getCatchParameter();
|
||||
if (catchParameter != null) {
|
||||
catchParameter.visit(this, data);
|
||||
}
|
||||
JetExpression catchBody = catchClause.getCatchBody();
|
||||
if (catchBody != null) {
|
||||
catchBody.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitFinallySection(JetFinallySection finallySection, D data) {
|
||||
JetBlockExpression finalExpression = finallySection.getFinalExpression();
|
||||
finalExpression.visit(this, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitTypeArgumentList(JetTypeArgumentList typeArgumentList, D data) {
|
||||
List<JetTypeProjection> arguments = typeArgumentList.getArguments();
|
||||
for (JetTypeProjection argument : arguments) {
|
||||
argument.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitThisExpression(JetThisExpression expression, D data) {
|
||||
JetReferenceExpression thisReference = expression.getThisReference();
|
||||
thisReference.visit(this, data);
|
||||
JetTypeReference superTypeQualifier = expression.getSuperTypeQualifier();
|
||||
if (superTypeQualifier != null) {
|
||||
superTypeQualifier.visit(this, data);
|
||||
}
|
||||
visitLabelQualifiedExpression(expression, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitParenthesizedExpression(JetParenthesizedExpression expression, D data) {
|
||||
JetExpression innerExpression = expression.getExpression();
|
||||
if (innerExpression != null) {
|
||||
innerExpression.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitInitializerList(JetInitializerList list, D data) {
|
||||
List<JetDelegationSpecifier> initializers = list.getInitializers();
|
||||
for (JetDelegationSpecifier initializer : initializers) {
|
||||
initializer.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitAnonymousInitializer(JetClassInitializer initializer, D data) {
|
||||
JetExpression body = initializer.getBody();
|
||||
body.visit(this, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitPropertyAccessor(JetPropertyAccessor accessor, D data) {
|
||||
visitDeclarationWithBody(accessor, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitTypeConstraintList(JetTypeConstraintList list, D data) {
|
||||
List<JetTypeConstraint> constraints = list.getConstraints();
|
||||
for (JetTypeConstraint constraint : constraints) {
|
||||
constraint.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitTypeConstraint(JetTypeConstraint constraint, D data) {
|
||||
JetSimpleNameExpression subjectTypeParameterName = constraint.getSubjectTypeParameterName();
|
||||
if (subjectTypeParameterName != null) {
|
||||
subjectTypeParameterName.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitUserType(JetUserType type, D data) {
|
||||
return super.visitUserType(type, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitTupleType(JetTupleType type, D data) {
|
||||
return super.visitTupleType(type, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitFunctionType(JetFunctionType type, D data) {
|
||||
return super.visitFunctionType(type, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitSelfType(JetSelfType type, D data) {
|
||||
return super.visitSelfType(type, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitBinaryWithTypeRHSExpression(JetBinaryExpressionWithTypeRHS expression, D data) {
|
||||
JetExpression left = expression.getLeft();
|
||||
left.visit(this, data);
|
||||
JetTypeReference right = expression.getRight();
|
||||
if (right != null) {
|
||||
right.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitStringTemplateExpression(JetStringTemplateExpression expression, D data) {
|
||||
JetStringTemplateEntry[] entries = expression.getEntries();
|
||||
for (JetStringTemplateEntry entry : entries) {
|
||||
entry.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitNamedDeclaration(JetNamedDeclaration declaration, D data) {
|
||||
return super.visitNamedDeclaration(declaration, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitNullableType(JetNullableType nullableType, D data) {
|
||||
return super.visitNullableType(nullableType, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitTypeProjection(JetTypeProjection typeProjection, D data) {
|
||||
return super.visitTypeProjection(typeProjection, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitWhenEntry(JetWhenEntry jetWhenEntry, D data) {
|
||||
JetExpression expression = jetWhenEntry.getExpression();
|
||||
if (expression != null) {
|
||||
expression.visit(this, data);
|
||||
}
|
||||
JetWhenCondition[] conditions = jetWhenEntry.getConditions();
|
||||
for (JetWhenCondition condition : conditions) {
|
||||
condition.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitIsExpression(JetIsExpression expression, D data) {
|
||||
JetExpression leftHandSide = expression.getLeftHandSide();
|
||||
leftHandSide.visit(this, data);
|
||||
JetSimpleNameExpression operationReference = expression.getOperationReference();
|
||||
operationReference.visit(this, data);
|
||||
JetPattern pattern = expression.getPattern();
|
||||
if (pattern != null) {
|
||||
pattern.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitWhenConditionCall(JetWhenConditionCall condition, D data) {
|
||||
JetExpression callSuffixExpression = condition.getCallSuffixExpression();
|
||||
if (callSuffixExpression != null) {
|
||||
callSuffixExpression.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitWhenConditionIsPattern(JetWhenConditionIsPattern condition, D data) {
|
||||
JetPattern pattern = condition.getPattern();
|
||||
if (pattern != null) {
|
||||
pattern.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitWhenConditionInRange(JetWhenConditionInRange condition, D data) {
|
||||
JetSimpleNameExpression operationReference = condition.getOperationReference();
|
||||
operationReference.visit(this, data);
|
||||
JetExpression rangeExpression = condition.getRangeExpression();
|
||||
if (rangeExpression != null) {
|
||||
rangeExpression.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitTypePattern(JetTypePattern pattern, D data) {
|
||||
return super.visitTypePattern(pattern, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitWildcardPattern(JetWildcardPattern pattern, D data) {
|
||||
return super.visitWildcardPattern(pattern, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitExpressionPattern(JetExpressionPattern pattern, D data) {
|
||||
JetExpression expression = pattern.getExpression();
|
||||
if (expression != null) {
|
||||
expression.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitTuplePattern(JetTuplePattern pattern, D data) {
|
||||
List<JetTuplePatternEntry> entries = pattern.getEntries();
|
||||
for (JetTuplePatternEntry entry : entries) {
|
||||
entry.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitDecomposerPattern(JetDecomposerPattern pattern, D data) {
|
||||
JetTuplePattern argumentList = pattern.getArgumentList();
|
||||
argumentList.visit(this, data);
|
||||
JetExpression decomposerExpression = pattern.getDecomposerExpression();
|
||||
if (decomposerExpression != null) {
|
||||
decomposerExpression.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitObjectDeclaration(JetObjectDeclaration objectDeclaration, D data) {
|
||||
List<JetDeclaration> declarations = objectDeclaration.getDeclarations();
|
||||
for (JetDeclaration declaration : declarations) {
|
||||
declaration.visit(this, data);
|
||||
}
|
||||
JetDelegationSpecifierList delegationSpecifierList = objectDeclaration.getDelegationSpecifierList();
|
||||
if (delegationSpecifierList != null) {
|
||||
delegationSpecifierList.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitBindingPattern(JetBindingPattern pattern, D data) {
|
||||
JetWhenCondition condition = pattern.getCondition();
|
||||
if (condition != null) {
|
||||
condition.visit(this, data);
|
||||
}
|
||||
JetProperty variableDeclaration = pattern.getVariableDeclaration();
|
||||
variableDeclaration.visit(this, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitStringTemplateEntry(JetStringTemplateEntry entry, D data) {
|
||||
JetExpression expression = entry.getExpression();
|
||||
if (expression != null) {
|
||||
expression.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitStringTemplateEntryWithExpression(JetStringTemplateEntryWithExpression entry, D data) {
|
||||
visitStringTemplateEntry(entry, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitBlockStringTemplateEntry(JetBlockStringTemplateEntry entry, D data) {
|
||||
visitStringTemplateEntry(entry, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitSimpleNameStringTemplateEntry(JetSimpleNameStringTemplateEntry entry, D data) {
|
||||
visitStringTemplateEntry(entry, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitLiteralStringTemplateEntry(JetLiteralStringTemplateEntry entry, D data) {
|
||||
visitStringTemplateEntry(entry, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitEscapeStringTemplateEntry(JetEscapeStringTemplateEntry entry, D data) {
|
||||
visitStringTemplateEntry(entry, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
private Void visitDeclarationWithBody(JetDeclarationWithBody declaration, D data) {
|
||||
JetExpression bodyExpression = declaration.getBodyExpression();
|
||||
if (bodyExpression != null) {
|
||||
bodyExpression.visit(this, data);
|
||||
}
|
||||
List<JetParameter> valueParameters = declaration.getValueParameters();
|
||||
for (JetParameter valueParameter : valueParameters) {
|
||||
valueParameter.visit(this, data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -9,12 +9,11 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetAnnotationEntry;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetModifierList;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.JetTypeInferrer;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -27,11 +26,15 @@ import static org.jetbrains.jet.lang.types.JetTypeInferrer.NO_EXPECTED_TYPE;
|
||||
public class AnnotationResolver {
|
||||
|
||||
private final BindingTrace trace;
|
||||
private final JetTypeInferrer typeInferrer;
|
||||
// private final JetTypeInferrer typeInferrer;
|
||||
private final CallResolver callResolver;
|
||||
// private final JetTypeInferrer.Services services;
|
||||
|
||||
public AnnotationResolver(JetSemanticServices semanticServices, BindingTrace trace) {
|
||||
this.typeInferrer = new JetTypeInferrer(JetFlowInformationProvider.THROW_EXCEPTION, semanticServices);
|
||||
this.trace = trace;
|
||||
// this.typeInferrer = new JetTypeInferrer(JetFlowInformationProvider.THROW_EXCEPTION, semanticServices);
|
||||
// this.services = typeInferrer.getServices(this.trace);
|
||||
this.callResolver = new CallResolver(semanticServices, new JetTypeInferrer(semanticServices), DataFlowInfo.getEmpty());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -47,7 +50,7 @@ public class AnnotationResolver {
|
||||
}
|
||||
|
||||
public void resolveAnnotationStub(@NotNull JetScope scope, @NotNull JetAnnotationEntry entryElement, @NotNull AnnotationDescriptor descriptor) {
|
||||
JetType jetType = typeInferrer.getCallResolver().resolveCall(trace, scope, ReceiverDescriptor.NO_RECEIVER, entryElement, NO_EXPECTED_TYPE);
|
||||
JetType jetType = callResolver.resolveCall(trace, scope, CallMaker.makeCall(ReceiverDescriptor.NO_RECEIVER, null, entryElement), NO_EXPECTED_TYPE);
|
||||
descriptor.setAnnotationType(jetType == null ? ErrorUtils.createErrorType("Unresolved annotation type") : jetType);
|
||||
}
|
||||
|
||||
@@ -112,4 +115,4 @@ public class AnnotationResolver {
|
||||
}
|
||||
return createAnnotationStubs(modifierList.getAnnotationEntries());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@ import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.DeferredType;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.util.CommonSuppliers;
|
||||
@@ -20,15 +20,16 @@ import java.util.Collection;
|
||||
* @author abreslav
|
||||
*/
|
||||
public interface BindingContext {
|
||||
WritableSlice<JetElement, ReceiverDescriptor> RECEIVER = Slices.createSimpleSlice("RECEIVER");
|
||||
|
||||
WritableSlice<JetAnnotationEntry, AnnotationDescriptor> ANNOTATION = Slices.createSimpleSlice("ANNOTATION");
|
||||
|
||||
WritableSlice<JetExpression, CompileTimeConstant<?>> COMPILE_TIME_VALUE = Slices.createSimpleSlice("COMPILE_TIME_VALUE");
|
||||
WritableSlice<JetTypeReference, JetType> TYPE = Slices.createSimpleSlice("TYPE");
|
||||
WritableSlice<JetExpression, JetType> EXPRESSION_TYPE = new BasicWritableSlice<JetExpression, JetType>("EXPRESSION_TYPE", RewritePolicy.DO_NOTHING);
|
||||
|
||||
WritableSlice<JetReferenceExpression, DeclarationDescriptor> REFERENCE_TARGET = new BasicWritableSlice<JetReferenceExpression, DeclarationDescriptor>("REFERENCE_TARGET", RewritePolicy.DO_NOTHING);
|
||||
WritableSlice<JetReferenceExpression, Collection<? extends DeclarationDescriptor>> AMBIGUOUS_REFERENCE_TARGET = new BasicWritableSlice<JetReferenceExpression, Collection<? extends DeclarationDescriptor>>("AMBIGUOUS_REFERENCE_TARGET", RewritePolicy.DO_NOTHING);
|
||||
WritableSlice<JetElement, ResolvedCall<? extends CallableDescriptor>> RESOLVED_CALL = new BasicWritableSlice<JetElement, ResolvedCall<? extends CallableDescriptor>>("RESOLVED_CALL", RewritePolicy.DO_NOTHING);
|
||||
|
||||
WritableSlice<JetReferenceExpression, Collection<? extends ResolvedCall<? extends DeclarationDescriptor>>> AMBIGUOUS_REFERENCE_TARGET = new BasicWritableSlice<JetReferenceExpression, Collection<? extends ResolvedCall<? extends DeclarationDescriptor>>>("AMBIGUOUS_REFERENCE_TARGET", RewritePolicy.DO_NOTHING);
|
||||
|
||||
WritableSlice<JetExpression, FunctionDescriptor> LOOP_RANGE_ITERATOR = Slices.createSimpleSlice("LOOP_RANGE_ITERATOR");
|
||||
WritableSlice<JetExpression, CallableDescriptor> LOOP_RANGE_HAS_NEXT = Slices.createSimpleSlice("LOOP_RANGE_HAS_NEXT");
|
||||
@@ -43,9 +44,12 @@ public interface BindingContext {
|
||||
WritableSlice<JetExpression, Boolean> PROCESSED = Slices.createSimpleSetSlice("PROCESSED");
|
||||
WritableSlice<JetElement, Boolean> STATEMENT = Slices.createRemovableSetSlice("STATEMENT");
|
||||
WritableSlice<CallableMemberDescriptor, Boolean> DELEGATED = Slices.createRemovableSetSlice("DELEGATED");
|
||||
|
||||
WritableSlice<VariableDescriptor, Boolean> MUST_BE_WRAPPED_IN_A_REF = Slices.createSimpleSetSlice("MUST_BE_WRAPPED_IN_A_REF");
|
||||
|
||||
enum DeferredTypeKey {DEFERRED_TYPE_KEY}
|
||||
WritableSlice<DeferredTypeKey, Collection<DeferredType>> DEFERRED_TYPES = Slices.createSimpleSlice("DEFERRED_TYPES");
|
||||
|
||||
WritableSlice<DeferredTypeKey, DeferredType> DEFERRED_TYPE = new CollectionSliceWrapper<DeferredTypeKey, DeferredType>(DEFERRED_TYPES, CommonSuppliers.<DeferredType>getArrayListSupplier());
|
||||
|
||||
WritableSlice<PropertyDescriptor, Boolean> BACKING_FIELD_REQUIRED = new Slices.SetSlice<PropertyDescriptor>("BACKING_FIELD_REQUIRED", RewritePolicy.DO_NOTHING) {
|
||||
|
||||
@@ -125,7 +125,7 @@ public class BodyResolver {
|
||||
final JetScope scopeForConstructor = primaryConstructor == null
|
||||
? null
|
||||
: getInnerScopeForConstructor(primaryConstructor, descriptor.getScopeForMemberResolution(), true);
|
||||
final JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors, JetFlowInformationProvider.NONE); // TODO : flow
|
||||
final JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors); // TODO : flow
|
||||
|
||||
final Map<JetTypeReference, JetType> supertypes = Maps.newLinkedHashMap();
|
||||
JetVisitorVoid visitor = new JetVisitorVoid() {
|
||||
@@ -172,7 +172,9 @@ public class BodyResolver {
|
||||
JetTypeReference typeReference = call.getTypeReference();
|
||||
if (typeReference != null) {
|
||||
if (descriptor.getUnsubstitutedPrimaryConstructor() != null) {
|
||||
JetType supertype = typeInferrer.getCallResolver().resolveCall(context.getTrace(), scopeForConstructor, ReceiverDescriptor.NO_RECEIVER, call, NO_EXPECTED_TYPE);
|
||||
JetType supertype = typeInferrer.getCallResolver().resolveCall(
|
||||
context.getTrace(), scopeForConstructor,
|
||||
CallMaker.makeCall(ReceiverDescriptor.NO_RECEIVER, null, call), NO_EXPECTED_TYPE);
|
||||
if (supertype != null) {
|
||||
recordSupertype(typeReference, supertype);
|
||||
ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
|
||||
@@ -290,7 +292,7 @@ public class BodyResolver {
|
||||
ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
|
||||
assert primaryConstructor != null;
|
||||
final JetScope scopeForConstructor = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution(), true);
|
||||
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(createFieldAssignTrackingTrace(), JetFlowInformationProvider.NONE); // TODO : flow
|
||||
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(createFieldAssignTrackingTrace()); // TODO : flow
|
||||
for (JetClassInitializer anonymousInitializer : anonymousInitializers) {
|
||||
typeInferrer.getType(scopeForConstructor, anonymousInitializer.getBody(), NO_EXPECTED_TYPE);
|
||||
}
|
||||
@@ -316,7 +318,7 @@ public class BodyResolver {
|
||||
private void resolveSecondaryConstructorBody(JetConstructor declaration, final ConstructorDescriptor descriptor, final JetScope declaringScope) {
|
||||
final JetScope functionInnerScope = getInnerScopeForConstructor(descriptor, declaringScope, false);
|
||||
|
||||
final JetTypeInferrer.Services typeInferrerForInitializers = context.getSemanticServices().getTypeInferrerServices(traceForConstructors, JetFlowInformationProvider.NONE);
|
||||
final JetTypeInferrer.Services typeInferrerForInitializers = context.getSemanticServices().getTypeInferrerServices(traceForConstructors);
|
||||
|
||||
JetClass containingClass = PsiTreeUtil.getParentOfType(declaration, JetClass.class);
|
||||
assert containingClass != null : "This must be guaranteed by the parser";
|
||||
@@ -334,7 +336,8 @@ public class BodyResolver {
|
||||
public void visitDelegationToSuperCallSpecifier(JetDelegatorToSuperCall call) {
|
||||
JetTypeReference typeReference = call.getTypeReference();
|
||||
if (typeReference != null) {
|
||||
typeInferrerForInitializers.getCallResolver().resolveCall(context.getTrace(), functionInnerScope, null, call, NO_EXPECTED_TYPE);
|
||||
typeInferrerForInitializers.getCallResolver().resolveCall(context.getTrace(), functionInnerScope,
|
||||
CallMaker.makeCall(ReceiverDescriptor.NO_RECEIVER, null, call), NO_EXPECTED_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -346,7 +349,7 @@ public class BodyResolver {
|
||||
|
||||
typeInferrerForInitializers.getCallResolver().resolveCall(context.getTrace(),
|
||||
functionInnerScope,
|
||||
ReceiverDescriptor.NO_RECEIVER, call, NO_EXPECTED_TYPE);
|
||||
CallMaker.makeCall(ReceiverDescriptor.NO_RECEIVER, null, call), NO_EXPECTED_TYPE);
|
||||
// call.getThisReference(),
|
||||
// classDescriptor,
|
||||
// classDescriptor.getDefaultType(),
|
||||
@@ -377,11 +380,11 @@ public class BodyResolver {
|
||||
}
|
||||
JetExpression bodyExpression = declaration.getBodyExpression();
|
||||
if (bodyExpression != null) {
|
||||
context.getClassDescriptorResolver().computeFlowData(declaration, bodyExpression);
|
||||
JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(declaration, bodyExpression);
|
||||
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors, flowInformationProvider);
|
||||
//context.getClassDescriptorResolver().computeFlowData(declaration, bodyExpression);
|
||||
//JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(declaration, bodyExpression);
|
||||
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors);
|
||||
|
||||
typeInferrer.checkFunctionReturnType(functionInnerScope, declaration, JetStandardClasses.getUnitType());
|
||||
typeInferrer.checkFunctionReturnType(functionInnerScope, declaration, descriptor, JetStandardClasses.getUnitType());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -456,7 +459,7 @@ public class BodyResolver {
|
||||
for (TypeParameterDescriptor typeParameterDescriptor : propertyDescriptor.getTypeParameters()) {
|
||||
result.addTypeParameterDescriptor(typeParameterDescriptor);
|
||||
}
|
||||
ReceiverDescriptor receiver = propertyDescriptor.getReceiver();
|
||||
ReceiverDescriptor receiver = propertyDescriptor.getReceiverParameter();
|
||||
if (receiver.exists()) {
|
||||
result.setImplicitReceiver(receiver);
|
||||
}
|
||||
@@ -516,8 +519,8 @@ public class BodyResolver {
|
||||
}
|
||||
|
||||
private void resolvePropertyInitializer(JetProperty property, PropertyDescriptor propertyDescriptor, JetExpression initializer, JetScope scope) {
|
||||
JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(property, initializer); // TODO : flow JET-15
|
||||
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors, flowInformationProvider);
|
||||
//JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(property, initializer); // TODO : flow JET-15
|
||||
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors);
|
||||
JetType type = typeInferrer.getType(getPropertyDeclarationInnerScope(scope, propertyDescriptor), initializer, NO_EXPECTED_TYPE);
|
||||
|
||||
JetType expectedType = propertyDescriptor.getInType();
|
||||
@@ -552,13 +555,13 @@ public class BodyResolver {
|
||||
|
||||
JetExpression bodyExpression = function.getBodyExpression();
|
||||
if (bodyExpression != null) {
|
||||
JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(function.asElement(), bodyExpression);
|
||||
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(trace, flowInformationProvider);
|
||||
//JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(function.asElement(), bodyExpression);
|
||||
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(trace);
|
||||
|
||||
typeInferrer.checkFunctionReturnType(declaringScope, function, functionDescriptor);
|
||||
}
|
||||
|
||||
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(trace, JetFlowInformationProvider.THROW_EXCEPTION);
|
||||
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(trace);
|
||||
List<JetParameter> valueParameters = function.getValueParameters();
|
||||
for (int i = 0; i < valueParameters.size(); i++) {
|
||||
ValueParameterDescriptor valueParameterDescriptor = functionDescriptor.getValueParameters().get(i);
|
||||
|
||||
@@ -178,8 +178,8 @@ public class ClassDescriptorResolver {
|
||||
returnType = DeferredType.create(trace, new LazyValueWithDefault<JetType>(ErrorUtils.createErrorType("Recursive dependency")) {
|
||||
@Override
|
||||
protected JetType compute() {
|
||||
JetFlowInformationProvider flowInformationProvider = computeFlowData(function, bodyExpression);
|
||||
return semanticServices.getTypeInferrerServices(trace, flowInformationProvider).inferFunctionReturnType(scope, function, functionDescriptor);
|
||||
//JetFlowInformationProvider flowInformationProvider = computeFlowData(function, bodyExpression);
|
||||
return semanticServices.getTypeInferrerServices(trace).inferFunctionReturnType(scope, function, functionDescriptor);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -195,6 +195,7 @@ public class ClassDescriptorResolver {
|
||||
Visibility visibility = resolveVisibilityFromModifiers(function.getModifierList());
|
||||
functionDescriptor.initialize(
|
||||
receiverType,
|
||||
DescriptorUtils.getExpectedThisObjectIfNeeded(containingDescriptor),
|
||||
typeParameterDescriptors,
|
||||
valueParameterDescriptors,
|
||||
returnType,
|
||||
@@ -438,6 +439,7 @@ public class ClassDescriptorResolver {
|
||||
resolveVisibilityFromModifiers(objectDeclaration.getModifierList()),
|
||||
false,
|
||||
null,
|
||||
DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration),
|
||||
JetPsiUtil.safeName(objectDeclaration.getName()),
|
||||
null,
|
||||
classDescriptor.getDefaultType());
|
||||
@@ -481,17 +483,7 @@ public class ClassDescriptorResolver {
|
||||
|
||||
JetType type = getVariableType(scopeWithTypeParameters, property, true);
|
||||
|
||||
boolean hasBody = property.getInitializer() != null;
|
||||
if (!hasBody) {
|
||||
JetPropertyAccessor getter = property.getGetter();
|
||||
if (getter != null && getter.getBodyExpression() != null) {
|
||||
hasBody = true;
|
||||
}
|
||||
JetPropertyAccessor setter = property.getSetter();
|
||||
if (!hasBody && setter != null && setter.getBodyExpression() != null) {
|
||||
hasBody = true;
|
||||
}
|
||||
}
|
||||
boolean hasBody = hasBody(property);
|
||||
Modality defaultModality = getDefaultModality(containingDeclaration, hasBody);
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
|
||||
containingDeclaration,
|
||||
@@ -500,6 +492,7 @@ public class ClassDescriptorResolver {
|
||||
resolveVisibilityFromModifiers(property.getModifierList()),
|
||||
isVar,
|
||||
receiverType,
|
||||
DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration),
|
||||
JetPsiUtil.safeName(property.getName()),
|
||||
isVar ? type : null,
|
||||
type);
|
||||
@@ -513,6 +506,21 @@ public class ClassDescriptorResolver {
|
||||
return propertyDescriptor;
|
||||
}
|
||||
|
||||
/*package*/ static boolean hasBody(JetProperty property) {
|
||||
boolean hasBody = property.getInitializer() != null;
|
||||
if (!hasBody) {
|
||||
JetPropertyAccessor getter = property.getGetter();
|
||||
if (getter != null && getter.getBodyExpression() != null) {
|
||||
hasBody = true;
|
||||
}
|
||||
JetPropertyAccessor setter = property.getSetter();
|
||||
if (!hasBody && setter != null && setter.getBodyExpression() != null) {
|
||||
hasBody = true;
|
||||
}
|
||||
}
|
||||
return hasBody;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JetType getVariableType(@NotNull final JetScope scope, @NotNull final JetProperty property, boolean allowDeferred) {
|
||||
// TODO : receiver?
|
||||
@@ -532,8 +540,8 @@ public class ClassDescriptorResolver {
|
||||
LazyValue<JetType> lazyValue = new LazyValueWithDefault<JetType>(ErrorUtils.createErrorType("Recursive dependency")) {
|
||||
@Override
|
||||
protected JetType compute() {
|
||||
JetFlowInformationProvider flowInformationProvider = computeFlowData(property, initializer);
|
||||
return semanticServices.getTypeInferrerServices(trace, flowInformationProvider).safeGetType(scope, initializer, JetTypeInferrer.NO_EXPECTED_TYPE);
|
||||
//JetFlowInformationProvider flowInformationProvider = computeFlowData(property, initializer);
|
||||
return semanticServices.getTypeInferrerServices(trace).safeGetType(scope, initializer, JetTypeInferrer.NO_EXPECTED_TYPE);
|
||||
}
|
||||
};
|
||||
if (allowDeferred) {
|
||||
@@ -756,6 +764,7 @@ public class ClassDescriptorResolver {
|
||||
resolveVisibilityFromModifiers(parameter.getModifierList()),
|
||||
isMutable,
|
||||
null,
|
||||
DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor),
|
||||
name == null ? "<no name>" : name,
|
||||
isMutable ? type : null,
|
||||
type);
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
package org.jetbrains.jet.lang.resolve;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider;
|
||||
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.JetTypeInferrer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||
import static org.jetbrains.jet.lang.types.JetTypeInferrer.NO_EXPECTED_TYPE;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class ControlFlowAnalyzer {
|
||||
private TopDownAnalysisContext context;
|
||||
private JetTypeInferrer.Services typeInferrer;
|
||||
|
||||
public ControlFlowAnalyzer(TopDownAnalysisContext context) {
|
||||
this.context = context;
|
||||
typeInferrer = context.getSemanticServices().getTypeInferrerServices(context.getTrace());
|
||||
}
|
||||
|
||||
public void process() {
|
||||
for (Map.Entry<JetNamedFunction, FunctionDescriptorImpl> entry : context.getFunctions().entrySet()) {
|
||||
JetNamedFunction function = entry.getKey();
|
||||
FunctionDescriptorImpl functionDescriptor = entry.getValue();
|
||||
|
||||
final JetType expectedReturnType = !function.hasBlockBody() && !function.hasDeclaredReturnType() ? NO_EXPECTED_TYPE : functionDescriptor.getReturnType();
|
||||
checkFunction(function, functionDescriptor, expectedReturnType);
|
||||
}
|
||||
|
||||
for (Map.Entry<JetDeclaration, ConstructorDescriptor> entry : this.context.getConstructors().entrySet()) {
|
||||
JetDeclaration declaration = entry.getKey();
|
||||
assert declaration instanceof JetConstructor;
|
||||
JetConstructor constructor = (JetConstructor) declaration;
|
||||
ConstructorDescriptor descriptor = entry.getValue();
|
||||
|
||||
checkFunction(constructor, descriptor, JetStandardClasses.getUnitType());
|
||||
}
|
||||
|
||||
for (JetProperty property : context.getProperties().keySet()) {
|
||||
checkProperty(property);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkFunction(JetDeclarationWithBody function, FunctionDescriptor functionDescriptor, final @NotNull JetType expectedReturnType) {
|
||||
JetExpression bodyExpression = function.getBodyExpression();
|
||||
if (bodyExpression == null) return;
|
||||
JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData((JetElement) function, bodyExpression);
|
||||
|
||||
final boolean blockBody = function.hasBlockBody();
|
||||
List<JetElement> unreachableElements = Lists.newArrayList();
|
||||
flowInformationProvider.collectUnreachableExpressions(function.asElement(), unreachableElements);
|
||||
|
||||
// This is needed in order to highlight only '1 < 2' and not '1', '<' and '2' as well
|
||||
final Set<JetElement> rootUnreachableElements = JetPsiUtil.findRootExpressions(unreachableElements);
|
||||
|
||||
for (JetElement element : rootUnreachableElements) {
|
||||
context.getTrace().report(UNREACHABLE_CODE.on(element));
|
||||
}
|
||||
|
||||
List<JetExpression> returnedExpressions = Lists.newArrayList();
|
||||
flowInformationProvider.collectReturnExpressions(function.asElement(), returnedExpressions);
|
||||
|
||||
boolean nothingReturned = returnedExpressions.isEmpty();
|
||||
|
||||
returnedExpressions.remove(function); // This will be the only "expression" if the body is empty
|
||||
|
||||
final JetScope scope = this.context.getDeclaringScopes().get(function);
|
||||
|
||||
if (expectedReturnType != NO_EXPECTED_TYPE && !JetStandardClasses.isUnit(expectedReturnType) && returnedExpressions.isEmpty() && !nothingReturned) {
|
||||
context.getTrace().report(RETURN_TYPE_MISMATCH.on(bodyExpression, expectedReturnType));
|
||||
}
|
||||
|
||||
for (JetExpression returnedExpression : returnedExpressions) {
|
||||
returnedExpression.accept(new JetVisitorVoid() {
|
||||
@Override
|
||||
public void visitReturnExpression(JetReturnExpression expression) {
|
||||
if (!blockBody) {
|
||||
context.getTrace().report(RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY.on(expression));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitExpression(JetExpression expression) {
|
||||
if (blockBody && expectedReturnType != NO_EXPECTED_TYPE && !JetStandardClasses.isUnit(expectedReturnType) && !rootUnreachableElements.contains(expression)) {
|
||||
JetType type = typeInferrer.getType(scope, expression, expectedReturnType);
|
||||
if (type == null || !JetStandardClasses.isNothing(type)) {
|
||||
context.getTrace().report(NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY.on(expression));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void checkProperty(JetProperty property) {
|
||||
JetExpression initializer = property.getInitializer();
|
||||
if (initializer == null) return;
|
||||
context.getClassDescriptorResolver().computeFlowData(property, initializer);
|
||||
}
|
||||
}
|
||||
@@ -117,9 +117,9 @@ public class DeclarationResolver {
|
||||
@Override
|
||||
public void visitEnumEntry(JetEnumEntry enumEntry) {
|
||||
if (enumEntry.getPrimaryConstructorParameterList() == null) {
|
||||
PropertyDescriptor propertyDescriptor = context.getClassDescriptorResolver().resolveObjectDeclarationAsPropertyDescriptor(namespaceLike, enumEntry, context.getClasses().get(enumEntry));
|
||||
MutableClassDescriptor classObjectDescriptor = ((MutableClassDescriptor) namespaceLike).getClassObjectDescriptor();
|
||||
assert classObjectDescriptor != null;
|
||||
PropertyDescriptor propertyDescriptor = context.getClassDescriptorResolver().resolveObjectDeclarationAsPropertyDescriptor(classObjectDescriptor, enumEntry, context.getClasses().get(enumEntry));
|
||||
classObjectDescriptor.addPropertyDescriptor(propertyDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jet.lang.resolve;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
@@ -10,7 +11,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.types.DeferredType;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
||||
@@ -20,7 +20,6 @@ import org.jetbrains.jet.lexer.JetTokens;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||
|
||||
@@ -114,7 +113,7 @@ public class DeclarationsChecker {
|
||||
|
||||
|
||||
private void checkObject(JetObjectDeclaration objectDeclaration, MutableClassDescriptor classDescriptor) {
|
||||
checkIllegalInThisContextModifiers(objectDeclaration.getModifierList(), JetTokens.ABSTRACT_KEYWORD, JetTokens.OPEN_KEYWORD, JetTokens.OVERRIDE_KEYWORD);
|
||||
checkIllegalInThisContextModifiers(objectDeclaration.getModifierList(), Sets.newHashSet(JetTokens.ABSTRACT_KEYWORD, JetTokens.OPEN_KEYWORD, JetTokens.OVERRIDE_KEYWORD));
|
||||
}
|
||||
|
||||
private void checkOpenMembers(JetClass aClass, MutableClassDescriptor classDescriptor) {
|
||||
@@ -122,7 +121,9 @@ public class DeclarationsChecker {
|
||||
|
||||
JetNamedDeclaration member = (JetNamedDeclaration) context.getTrace().get(BindingContext.DESCRIPTOR_TO_DECLARATION, memberDescriptor);
|
||||
if (member != null && classDescriptor.getModality() == Modality.FINAL && member.hasModifier(JetTokens.OPEN_KEYWORD)) {
|
||||
ASTNode openModifierNode = member.getModifierList().getModifierNode(JetTokens.OPEN_KEYWORD);
|
||||
JetModifierList modifierList = member.getModifierList();
|
||||
assert modifierList != null;
|
||||
ASTNode openModifierNode = modifierList.getModifierNode(JetTokens.OPEN_KEYWORD);
|
||||
context.getTrace().report(NON_FINAL_MEMBER_IN_FINAL_CLASS.on(member, openModifierNode, aClass));
|
||||
}
|
||||
}
|
||||
@@ -136,6 +137,29 @@ public class DeclarationsChecker {
|
||||
checkPropertyAbstractness(property, propertyDescriptor, classDescriptor);
|
||||
checkPropertyInitializer(property, propertyDescriptor, classDescriptor);
|
||||
checkAccessors(property, propertyDescriptor);
|
||||
checkDeclaredTypeInPublicMember(property, propertyDescriptor);
|
||||
}
|
||||
|
||||
private void checkDeclaredTypeInPublicMember(JetNamedDeclaration member, CallableMemberDescriptor memberDescriptor) {
|
||||
PsiElement nameIdentifier = member.getNameIdentifier();
|
||||
boolean hasDeferredType;
|
||||
if (member instanceof JetProperty) {
|
||||
hasDeferredType = ((JetProperty) member).getPropertyTypeRef() == null && ClassDescriptorResolver.hasBody((JetProperty) member);
|
||||
}
|
||||
else {
|
||||
assert member instanceof JetFunction;
|
||||
JetFunction function = (JetFunction) member;
|
||||
hasDeferredType = function.getReturnTypeRef() == null && function.getBodyExpression() != null && !function.hasBlockBody();
|
||||
}
|
||||
if ((memberDescriptor.getVisibility() == Visibility.PUBLIC || memberDescriptor.getVisibility() == Visibility.PROTECTED) &&
|
||||
hasDeferredType && nameIdentifier != null) {
|
||||
|
||||
JetType returnType = memberDescriptor.getReturnType();
|
||||
if (returnType instanceof DeferredType) {
|
||||
returnType = ((DeferredType) returnType).getActualType();
|
||||
}
|
||||
context.getTrace().report(PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE.on(member, nameIdentifier, returnType));
|
||||
}
|
||||
}
|
||||
|
||||
private void checkPropertyAbstractness(JetProperty property, PropertyDescriptor propertyDescriptor, ClassDescriptor classDescriptor) {
|
||||
@@ -225,24 +249,13 @@ public class DeclarationsChecker {
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkFunction(JetDeclarationWithBody function, FunctionDescriptor functionDescriptor) {
|
||||
protected void checkFunction(JetNamedFunction function, FunctionDescriptor functionDescriptor) {
|
||||
DeclarationDescriptor containingDescriptor = functionDescriptor.getContainingDeclaration();
|
||||
PsiElement nameIdentifier;
|
||||
boolean isPropertyAccessor = false;
|
||||
if (function instanceof JetNamedFunction) {
|
||||
nameIdentifier = ((JetNamedFunction) function).getNameIdentifier();
|
||||
}
|
||||
else if (function instanceof JetPropertyAccessor) {
|
||||
isPropertyAccessor = true;
|
||||
nameIdentifier = ((JetPropertyAccessor) function).getNamePlaceholder();
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
JetFunctionOrPropertyAccessor functionOrPropertyAccessor = (JetFunctionOrPropertyAccessor) function;
|
||||
JetModifierList modifierList = functionOrPropertyAccessor.getModifierList();
|
||||
PsiElement nameIdentifier = function.getNameIdentifier();
|
||||
JetModifierList modifierList = function.getModifierList();
|
||||
ASTNode abstractNode = modifierList != null ? modifierList.getModifierNode(JetTokens.ABSTRACT_KEYWORD) : null;
|
||||
boolean hasAbstractModifier = abstractNode != null;
|
||||
checkDeclaredTypeInPublicMember(function, functionDescriptor);
|
||||
if (containingDescriptor instanceof ClassDescriptor) {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) containingDescriptor;
|
||||
boolean inTrait = classDescriptor.getKind() == ClassKind.TRAIT;
|
||||
@@ -251,46 +264,45 @@ public class DeclarationsChecker {
|
||||
if (hasAbstractModifier && !inAbstractClass && !inTrait && !inEnum) {
|
||||
PsiElement classElement = context.getTrace().get(BindingContext.DESCRIPTOR_TO_DECLARATION, classDescriptor);
|
||||
assert classElement instanceof JetClass;
|
||||
context.getTrace().report(ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS.on(functionOrPropertyAccessor, abstractNode, functionDescriptor.getName(), classDescriptor, (JetClass) classElement));
|
||||
context.getTrace().report(ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS.on(function, abstractNode, functionDescriptor.getName(), classDescriptor, (JetClass) classElement));
|
||||
}
|
||||
if (hasAbstractModifier && inTrait && !isPropertyAccessor) {
|
||||
if (hasAbstractModifier && inTrait) {
|
||||
context.getTrace().report(REDUNDANT_MODIFIER_IN_TRAIT.on(modifierList, abstractNode, JetTokens.ABSTRACT_KEYWORD));
|
||||
}
|
||||
if (function.getBodyExpression() != null && hasAbstractModifier) {
|
||||
context.getTrace().report(ABSTRACT_FUNCTION_WITH_BODY.on(functionOrPropertyAccessor, abstractNode, functionDescriptor));
|
||||
context.getTrace().report(ABSTRACT_FUNCTION_WITH_BODY.on(function, abstractNode, functionDescriptor));
|
||||
}
|
||||
if (function.getBodyExpression() == null && !hasAbstractModifier && !inTrait && nameIdentifier != null && !isPropertyAccessor) {
|
||||
context.getTrace().report(NON_ABSTRACT_FUNCTION_WITH_NO_BODY.on(functionOrPropertyAccessor, nameIdentifier, functionDescriptor));
|
||||
if (function.getBodyExpression() == null && !hasAbstractModifier && !inTrait && nameIdentifier != null) {
|
||||
context.getTrace().report(NON_ABSTRACT_FUNCTION_WITH_NO_BODY.on(function, nameIdentifier, functionDescriptor));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (hasAbstractModifier) {
|
||||
if (!isPropertyAccessor) {
|
||||
context.getTrace().report(NON_MEMBER_ABSTRACT_FUNCTION.on(functionOrPropertyAccessor, abstractNode, functionDescriptor));
|
||||
}
|
||||
else {
|
||||
context.getTrace().report(NON_MEMBER_ABSTRACT_ACCESSOR.on(functionOrPropertyAccessor, abstractNode));
|
||||
}
|
||||
context.getTrace().report(NON_MEMBER_ABSTRACT_FUNCTION.on(function, abstractNode, functionDescriptor));
|
||||
}
|
||||
if (function.getBodyExpression() == null && !hasAbstractModifier && nameIdentifier != null && !isPropertyAccessor) {
|
||||
context.getTrace().report(NON_MEMBER_FUNCTION_NO_BODY.on(functionOrPropertyAccessor, nameIdentifier, functionDescriptor));
|
||||
if (function.getBodyExpression() == null && !hasAbstractModifier && nameIdentifier != null) {
|
||||
context.getTrace().report(NON_MEMBER_FUNCTION_NO_BODY.on(function, nameIdentifier, functionDescriptor));
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAccessors(JetProperty property, PropertyDescriptor propertyDescriptor) {
|
||||
for (JetPropertyAccessor accessor : property.getAccessors()) {
|
||||
PropertyAccessorDescriptor accessorDescriptor = accessor.isGetter()
|
||||
? propertyDescriptor.getGetter()
|
||||
: propertyDescriptor.getSetter();
|
||||
checkFunction(accessor, accessorDescriptor);
|
||||
checkModifiers(accessor.getModifierList());
|
||||
if (propertyDescriptor.getModality() == Modality.FINAL && accessor.hasModifier(JetTokens.OPEN_KEYWORD)) {
|
||||
ASTNode openModifierNode = accessor.getModifierList().getModifierNode(JetTokens.OPEN_KEYWORD);
|
||||
context.getTrace().report(NON_FINAL_ACCESSOR_OF_FINAL_PROPERTY.on(accessor, openModifierNode, property));
|
||||
checkIllegalInThisContextModifiers(accessor.getModifierList(), Sets.newHashSet(JetTokens.ABSTRACT_KEYWORD, JetTokens.OPEN_KEYWORD, JetTokens.FINAL_KEYWORD, JetTokens.OVERRIDE_KEYWORD));
|
||||
}
|
||||
JetPropertyAccessor getter = property.getGetter();
|
||||
PropertyGetterDescriptor getterDescriptor = propertyDescriptor.getGetter();
|
||||
JetModifierList getterModifierList = getter != null ? getter.getModifierList() : null;
|
||||
if (getterModifierList != null && getterDescriptor != null) {
|
||||
Map<JetKeywordToken, ASTNode> nodes = getNodesCorrespondingToModifiers(getterModifierList, Sets.newHashSet(JetTokens.PUBLIC_KEYWORD, JetTokens.PROTECTED_KEYWORD, JetTokens.PRIVATE_KEYWORD, JetTokens.INTERNAL_KEYWORD));
|
||||
if (getterDescriptor.getVisibility() != propertyDescriptor.getVisibility()) {
|
||||
for (Map.Entry<JetKeywordToken, ASTNode> entry : nodes.entrySet()) {
|
||||
context.getTrace().report(Errors.GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY.on(getterModifierList, entry.getValue(), entry.getKey()));
|
||||
}
|
||||
}
|
||||
if (propertyDescriptor.getModality() != Modality.ABSTRACT && accessor.hasModifier(JetTokens.ABSTRACT_KEYWORD)) {
|
||||
ASTNode abstractModifierNode = accessor.getModifierList().getModifierNode(JetTokens.ABSTRACT_KEYWORD);
|
||||
context.getTrace().report(ABSTRACT_ACCESSOR_OF_NON_ABSTRACT_PROPERTY.on(accessor, abstractModifierNode, property));
|
||||
else {
|
||||
for (Map.Entry<JetKeywordToken, ASTNode> entry : nodes.entrySet()) {
|
||||
context.getTrace().report(Errors.REDUNDANT_MODIFIER_IN_GETTER.on(getterModifierList, entry.getValue(), entry.getKey()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -346,12 +358,23 @@ public class DeclarationsChecker {
|
||||
}
|
||||
}
|
||||
|
||||
private void checkIllegalInThisContextModifiers(@Nullable JetModifierList modifierList, JetKeywordToken... illegalModifiers) {
|
||||
private void checkIllegalInThisContextModifiers(@Nullable JetModifierList modifierList, Collection<JetKeywordToken> illegalModifiers) {
|
||||
if (modifierList == null) return;
|
||||
for (JetKeywordToken modifier : illegalModifiers) {
|
||||
if (modifierList.hasModifier(modifier)) {
|
||||
context.getTrace().report(Errors.ILLEGAL_MODIFIER.on(modifierList.getModifierNode(modifier), modifier));
|
||||
context.getTrace().report(Errors.ILLEGAL_MODIFIER.on(modifierList, modifierList.getModifierNode(modifier), modifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Map<JetKeywordToken, ASTNode> getNodesCorrespondingToModifiers(@NotNull JetModifierList modifierList, Collection<JetKeywordToken> possibleModifiers) {
|
||||
Map<JetKeywordToken, ASTNode> nodes = Maps.newHashMap();
|
||||
for (JetKeywordToken modifier : possibleModifiers) {
|
||||
if (modifierList.hasModifier(modifier)) {
|
||||
nodes.put(modifier, modifierList.getModifierNode(modifier));
|
||||
}
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,14 @@ import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
@@ -22,7 +25,7 @@ public class DescriptorUtils {
|
||||
|
||||
@Override
|
||||
public Boolean visitFunctionDescriptor(FunctionDescriptor descriptor, Void data) {
|
||||
return descriptor.getReceiver().exists();
|
||||
return descriptor.getReceiverParameter().exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -32,7 +35,7 @@ public class DescriptorUtils {
|
||||
|
||||
@Override
|
||||
public Boolean visitPropertyDescriptor(PropertyDescriptor descriptor, Void data) {
|
||||
return descriptor.getReceiver().exists();
|
||||
return descriptor.getReceiverParameter().exists();
|
||||
}
|
||||
}, null);
|
||||
}
|
||||
@@ -111,4 +114,13 @@ public class DescriptorUtils {
|
||||
if (makeNonAbstract && modality == Modality.ABSTRACT) return Modality.OPEN;
|
||||
return modality;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ReceiverDescriptor getExpectedThisObjectIfNeeded(@NotNull DeclarationDescriptor containingDeclaration) {
|
||||
if (containingDeclaration instanceof ClassDescriptor) {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
|
||||
return classDescriptor.getImplicitReceiver();
|
||||
}
|
||||
return NO_RECEIVER;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,7 +253,7 @@ public class OverrideResolver {
|
||||
}
|
||||
if (hasOverrideModifier && declared.getOverriddenDescriptors().size() == 0) {
|
||||
// context.getTrace().getErrorHandler().genericError(overrideNode, "Method " + declared.getName() + " overrides nothing");
|
||||
context.getTrace().report(NOTHING_TO_OVERRIDE.on(member, overrideNode, declared));
|
||||
context.getTrace().report(NOTHING_TO_OVERRIDE.on(modifierList, overrideNode, declared));
|
||||
}
|
||||
PsiElement nameIdentifier = member.getNameIdentifier();
|
||||
if (!hasOverrideModifier && declared.getOverriddenDescriptors().size() > 0 && nameIdentifier != null) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
@@ -37,24 +38,31 @@ public class OverridingUtil {
|
||||
}
|
||||
|
||||
public static <D extends CallableDescriptor> Set<D> filterOverrides(Set<D> candidateSet) {
|
||||
return filterOverrides(candidateSet, Function.ID);
|
||||
}
|
||||
|
||||
public static <D> Set<D> filterOverrides(Set<D> candidateSet, Function<? super D, ? extends CallableDescriptor> transform) {
|
||||
Set<D> candidates = Sets.newLinkedHashSet();
|
||||
outerLoop:
|
||||
for (D me : candidateSet) {
|
||||
for (D other : candidateSet) {
|
||||
for (D meD : candidateSet) {
|
||||
CallableDescriptor me = transform.fun(meD);
|
||||
for (D otherD : candidateSet) {
|
||||
CallableDescriptor other = transform.fun(otherD);
|
||||
if (me == other) continue;
|
||||
if (overrides(other, me)) {
|
||||
continue outerLoop;
|
||||
}
|
||||
}
|
||||
for (D other : candidates) {
|
||||
for (D otherD : candidates) {
|
||||
CallableDescriptor other = transform.fun(otherD);
|
||||
if (me.getOriginal() == other.getOriginal()
|
||||
&& isOverridableBy(other, me).isSuccess()
|
||||
&& isOverridableBy(me, other).isSuccess()) {
|
||||
&& isOverridableBy(other, me).isSuccess()
|
||||
&& isOverridableBy(me, other).isSuccess()) {
|
||||
continue outerLoop;
|
||||
}
|
||||
}
|
||||
// System.out.println(me);
|
||||
candidates.add(me);
|
||||
candidates.add(meD);
|
||||
}
|
||||
// Set<D> candidates = Sets.newLinkedHashSet(candidateSet);
|
||||
// for (D descriptor : candidateSet) {
|
||||
|
||||
@@ -69,6 +69,7 @@ public class TopDownAnalyzer {
|
||||
new OverrideResolver(context).process();
|
||||
new BodyResolver(context).resolveBehaviorDeclarationBodies();
|
||||
new DeclarationsChecker(context).process();
|
||||
new ControlFlowAnalyzer(context).process();
|
||||
}
|
||||
|
||||
public static void processStandardLibraryNamespace(
|
||||
|
||||
@@ -218,7 +218,7 @@ public class TypeHierarchyResolver {
|
||||
if (importDirective.isAllUnder()) {
|
||||
JetExpression importedReference = importDirective.getImportedReference();
|
||||
if (importedReference != null) {
|
||||
JetTypeInferrer.Services typeInferrerServices = context.getSemanticServices().getTypeInferrerServices(context.getTrace(), JetFlowInformationProvider.THROW_EXCEPTION);
|
||||
JetTypeInferrer.Services typeInferrerServices = context.getSemanticServices().getTypeInferrerServices(context.getTrace());
|
||||
JetType type = typeInferrerServices.getTypeWithNamespaces(namespaceScope, importedReference);
|
||||
if (type != null) {
|
||||
namespaceScope.importScope(type.getMemberScope());
|
||||
@@ -227,18 +227,20 @@ public class TypeHierarchyResolver {
|
||||
}
|
||||
else {
|
||||
ClassifierDescriptor classifierDescriptor = null;
|
||||
NamespaceDescriptor namespaceDescriptor = null;
|
||||
JetSimpleNameExpression referenceExpression = null;
|
||||
|
||||
JetExpression importedReference = importDirective.getImportedReference();
|
||||
if (importedReference instanceof JetDotQualifiedExpression) {
|
||||
JetDotQualifiedExpression reference = (JetDotQualifiedExpression) importedReference;
|
||||
JetType type = context.getSemanticServices().getTypeInferrerServices(context.getTrace(), JetFlowInformationProvider.THROW_EXCEPTION).getTypeWithNamespaces(namespaceScope, reference.getReceiverExpression());
|
||||
JetType type = context.getSemanticServices().getTypeInferrerServices(context.getTrace()).getTypeWithNamespaces(namespaceScope, reference.getReceiverExpression());
|
||||
JetExpression selectorExpression = reference.getSelectorExpression();
|
||||
if (selectorExpression != null) {
|
||||
referenceExpression = (JetSimpleNameExpression) selectorExpression;
|
||||
String referencedName = referenceExpression.getReferencedName();
|
||||
if (type != null && referencedName != null) {
|
||||
classifierDescriptor = type.getMemberScope().getClassifier(referencedName);
|
||||
namespaceDescriptor = type.getMemberScope().getNamespace(referencedName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -249,15 +251,28 @@ public class TypeHierarchyResolver {
|
||||
String referencedName = referenceExpression.getReferencedName();
|
||||
if (referencedName != null) {
|
||||
classifierDescriptor = outerScope.getClassifier(referencedName);
|
||||
namespaceDescriptor = outerScope.getNamespace(referencedName);
|
||||
}
|
||||
}
|
||||
|
||||
String aliasName = importDirective.getAliasName();
|
||||
if (aliasName == null) {
|
||||
aliasName = referenceExpression != null ? referenceExpression.getReferencedName() : null;
|
||||
}
|
||||
if (classifierDescriptor != null) {
|
||||
context.getTrace().record(BindingContext.REFERENCE_TARGET, referenceExpression, classifierDescriptor);
|
||||
|
||||
String aliasName = importDirective.getAliasName();
|
||||
String importedClassifierName = aliasName != null ? aliasName : classifierDescriptor.getName();
|
||||
namespaceScope.importClassifierAlias(importedClassifierName, classifierDescriptor);
|
||||
if (aliasName != null) {
|
||||
namespaceScope.importClassifierAlias(aliasName, classifierDescriptor);
|
||||
}
|
||||
}
|
||||
if (namespaceDescriptor != null) {
|
||||
if (classifierDescriptor == null) {
|
||||
context.getTrace().record(BindingContext.REFERENCE_TARGET, referenceExpression, namespaceDescriptor);
|
||||
}
|
||||
if (aliasName != null) {
|
||||
namespaceScope.importNamespaceAlias(aliasName, namespaceDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.jetbrains.jet.lang.resolve.calls;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.AbstractReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptorVisitor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class AutoCastReceiver extends AbstractReceiverDescriptor {
|
||||
private final ReceiverDescriptor original;
|
||||
private final boolean canCast;
|
||||
|
||||
public AutoCastReceiver(@NotNull ReceiverDescriptor original, @NotNull JetType castTo, boolean canCast) {
|
||||
super(castTo);
|
||||
this.original = original;
|
||||
this.canCast = canCast;
|
||||
}
|
||||
|
||||
public boolean canCast() {
|
||||
return canCast;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ReceiverDescriptor getOriginal() {
|
||||
return original;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, D> R accept(@NotNull ReceiverDescriptorVisitor<R, D> visitor, D data) {
|
||||
return original.accept(visitor, data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.jetbrains.jet.lang.resolve.calls;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.DataFlowInfo;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public interface AutoCastService {
|
||||
AutoCastService NO_AUTO_CASTS = new AutoCastService() {
|
||||
@Override
|
||||
public DataFlowInfo getDataFlowInfo() {
|
||||
return DataFlowInfo.getEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNotNull(@NotNull ReceiverDescriptor receiver) {
|
||||
return !receiver.getType().isNullable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReceiverDescriptor> getVariantsForReceiver(ReceiverDescriptor receiverDescriptor) {
|
||||
return Collections.singletonList(receiverDescriptor);
|
||||
}
|
||||
};
|
||||
|
||||
List<ReceiverDescriptor> getVariantsForReceiver(ReceiverDescriptor receiverDescriptor);
|
||||
DataFlowInfo getDataFlowInfo();
|
||||
|
||||
boolean isNotNull(@NotNull ReceiverDescriptor receiver);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.jetbrains.jet.lang.resolve.calls;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.DataFlowInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class AutoCastServiceImpl implements AutoCastService {
|
||||
private final DataFlowInfo dataFlowInfo;
|
||||
private final BindingContext bindingContext;
|
||||
|
||||
public AutoCastServiceImpl(DataFlowInfo dataFlowInfo, BindingContext bindingContext) {
|
||||
this.dataFlowInfo = dataFlowInfo;
|
||||
this.bindingContext = bindingContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReceiverDescriptor> getVariantsForReceiver(ReceiverDescriptor receiverDescriptor) {
|
||||
return AutoCastUtils.getAutoCastVariants(bindingContext, dataFlowInfo, receiverDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataFlowInfo getDataFlowInfo() {
|
||||
return dataFlowInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNotNull(@NotNull ReceiverDescriptor receiver) {
|
||||
if (!receiver.getType().isNullable()) return true;
|
||||
|
||||
List<ReceiverDescriptor> autoCastVariants = AutoCastUtils.getAutoCastVariants(bindingContext, dataFlowInfo, receiver);
|
||||
for (ReceiverDescriptor autoCastVariant : autoCastVariants) {
|
||||
if (!autoCastVariant.getType().isNullable()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package org.jetbrains.jet.lang.resolve.calls;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetThisExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.*;
|
||||
import org.jetbrains.jet.lang.types.DataFlowInfo;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.JetTypeChecker;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.AUTOCAST_IMPOSSIBLE;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.AUTOCAST;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class AutoCastUtils {
|
||||
|
||||
private AutoCastUtils() {}
|
||||
|
||||
public static List<ReceiverDescriptor> getAutoCastVariants(@NotNull final BindingContext bindingContext, @NotNull final DataFlowInfo dataFlowInfo, @NotNull ReceiverDescriptor receiverToCast) {
|
||||
return receiverToCast.accept(new ReceiverDescriptorVisitor<List<ReceiverDescriptor>, Object>() {
|
||||
@Override
|
||||
public List<ReceiverDescriptor> visitNoReceiver(ReceiverDescriptor noReceiver, Object data) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReceiverDescriptor> visitTransientReceiver(TransientReceiver receiver, Object data) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReceiverDescriptor> visitExtensionReceiver(ExtensionReceiver receiver, Object data) {
|
||||
return castThis(dataFlowInfo, receiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReceiverDescriptor> visitClassReceiver(ClassReceiver receiver, Object data) {
|
||||
return castThis(dataFlowInfo, receiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReceiverDescriptor> visitExpressionReceiver(ExpressionReceiver receiver, Object data) {
|
||||
JetExpression expression = receiver.getExpression();
|
||||
VariableDescriptor variableDescriptor = getVariableDescriptorFromSimpleName(bindingContext, expression);
|
||||
if (variableDescriptor != null) {
|
||||
List<ReceiverDescriptor> result = Lists.newArrayList();
|
||||
for (JetType possibleType : dataFlowInfo.getPossibleTypesForVariable(variableDescriptor)) {
|
||||
result.add(new AutoCastReceiver(receiver, possibleType, isAutoCastable(variableDescriptor)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else if (expression instanceof JetThisExpression) {
|
||||
return castThis(dataFlowInfo, receiver);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}, null);
|
||||
}
|
||||
|
||||
private static List<ReceiverDescriptor> castThis(@NotNull DataFlowInfo dataFlowInfo, @NotNull ReceiverDescriptor receiver) {
|
||||
assert receiver.exists();
|
||||
List<ReceiverDescriptor> result = Lists.newArrayList();
|
||||
for (JetType possibleType : dataFlowInfo.getPossibleTypesForReceiver(receiver)) {
|
||||
result.add(new AutoCastReceiver(receiver, possibleType, true));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static JetType castExpression(@NotNull JetExpression expression, @NotNull JetType expectedType, @NotNull DataFlowInfo dataFlowInfo, @NotNull BindingTrace trace) {
|
||||
JetTypeChecker typeChecker = JetTypeChecker.INSTANCE;
|
||||
VariableDescriptor variableDescriptor = getVariableDescriptorFromSimpleName(trace.getBindingContext(), expression);
|
||||
// boolean appropriateTypeFound = false;
|
||||
if (variableDescriptor != null) {
|
||||
List<JetType> possibleTypes = Lists.newArrayList(dataFlowInfo.getPossibleTypesForVariable(variableDescriptor));
|
||||
Collections.reverse(possibleTypes);
|
||||
for (JetType possibleType : possibleTypes) {
|
||||
if (typeChecker.isSubtypeOf(possibleType, expectedType)) {
|
||||
if (isAutoCastable(variableDescriptor)) {
|
||||
trace.record(AUTOCAST, expression, possibleType);
|
||||
}
|
||||
else {
|
||||
trace.report(AUTOCAST_IMPOSSIBLE.on(expression, possibleType, expression.getText()));
|
||||
}
|
||||
return possibleType;
|
||||
}
|
||||
}
|
||||
// if (!appropriateTypeFound) {
|
||||
// JetType notnullType = dataFlowInfo.getOutType(variableDescriptor);
|
||||
// if (notnullType != null && typeChecker.isSubtypeOf(notnullType, expectedType)) {
|
||||
// appropriateTypeFound = true;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static VariableDescriptor getVariableDescriptorFromSimpleName(@NotNull BindingContext bindingContext, @NotNull JetExpression expression) {
|
||||
// if (expression instanceof JetBinaryExpressionWithTypeRHS) {
|
||||
// JetBinaryExpressionWithTypeRHS expression = (JetBinaryExpressionWithTypeRHS) expression;
|
||||
// if (expression.getOperationSign().getReferencedNameElementType() == JetTokens.COLON) {
|
||||
// return getVariableDescriptorFromSimpleName(bindingContext, expression.getLeft());
|
||||
// }
|
||||
// }
|
||||
JetExpression receiver = JetPsiUtil.deparenthesize(expression);
|
||||
VariableDescriptor variableDescriptor = null;
|
||||
if (receiver instanceof JetSimpleNameExpression) {
|
||||
JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) receiver;
|
||||
DeclarationDescriptor declarationDescriptor = bindingContext.get(REFERENCE_TARGET, nameExpression);
|
||||
if (declarationDescriptor instanceof VariableDescriptor) {
|
||||
variableDescriptor = (VariableDescriptor) declarationDescriptor;
|
||||
}
|
||||
}
|
||||
return variableDescriptor;
|
||||
}
|
||||
|
||||
public static boolean isAutoCastable(@NotNull VariableDescriptor variableDescriptor) {
|
||||
if (variableDescriptor.isVar()) return false;
|
||||
if (variableDescriptor instanceof PropertyDescriptor) {
|
||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) variableDescriptor;
|
||||
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
|
||||
if (containingDeclaration instanceof ClassDescriptor) {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
|
||||
if (classDescriptor.getModality().isOverridable() && propertyDescriptor.getModality().isOverridable()) return false;
|
||||
}
|
||||
else {
|
||||
assert !propertyDescriptor.getModality().isOverridable() : "Property outside a class must not be overridable";
|
||||
}
|
||||
PropertyGetterDescriptor getter = propertyDescriptor.getGetter();
|
||||
if (getter == null || !getter.isDefault()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,22 @@
|
||||
package org.jetbrains.jet.lang.resolve.calls;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class DefaultValueArgument implements ResolvedValueArgument {
|
||||
public static final DefaultValueArgument DEFAULT = new DefaultValueArgument();
|
||||
|
||||
private DefaultValueArgument() {}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JetExpression> getArgumentExpressions() {
|
||||
return Collections.emptyList(); //throw new UnsupportedOperationException("Look into the default value of the parameter");
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package org.jetbrains.jet.lang.resolve.calls;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class ExpressionValueArgument implements ResolvedValueArgument {
|
||||
private final JetExpression expression;
|
||||
|
||||
public ExpressionValueArgument(@Nullable JetExpression expression) {
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
// Nullable when something like f(a, , b) was in the source code
|
||||
@Nullable
|
||||
public JetExpression getExpression() {
|
||||
return expression;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JetExpression> getArgumentExpressions() {
|
||||
if (expression == null) return Collections.emptyList();
|
||||
return Collections.singletonList(expression);
|
||||
}
|
||||
}
|
||||
-96
@@ -1,96 +0,0 @@
|
||||
package org.jetbrains.jet.lang.resolve.calls;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class OverloadResolutionResult<D> {
|
||||
public enum Code {
|
||||
SUCCESS(true),
|
||||
NAME_NOT_FOUND(false),
|
||||
SINGLE_CANDIDATE_ARGUMENT_MISMATCH(false),
|
||||
AMBIGUITY(false),
|
||||
MANY_FAILED_CANDIDATES(false);
|
||||
|
||||
private final boolean success;
|
||||
|
||||
Code(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static <D> OverloadResolutionResult<D> success(@NotNull D descriptor) {
|
||||
return new OverloadResolutionResult<D>(Code.SUCCESS, Collections.singleton(descriptor));
|
||||
}
|
||||
|
||||
public static <D> OverloadResolutionResult<D> nameNotFound() {
|
||||
return new OverloadResolutionResult<D>(Code.NAME_NOT_FOUND, Collections.<D>emptyList());
|
||||
}
|
||||
|
||||
public static <D> OverloadResolutionResult<D> singleFailedCandidate(D candidate) {
|
||||
return new OverloadResolutionResult<D>(Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH, Collections.singleton(candidate));
|
||||
}
|
||||
public static <D> OverloadResolutionResult<D> manyFailedCandidates(Set<D> failedCandidates) {
|
||||
return new OverloadResolutionResult<D>(Code.MANY_FAILED_CANDIDATES, failedCandidates);
|
||||
}
|
||||
|
||||
public static <D> OverloadResolutionResult<D> ambiguity(Collection<D> descriptors) {
|
||||
return new OverloadResolutionResult<D>(Code.AMBIGUITY, descriptors);
|
||||
}
|
||||
|
||||
private final Collection<D> descriptors;
|
||||
|
||||
private final Code resultCode;
|
||||
|
||||
public OverloadResolutionResult(@NotNull Code resultCode, @NotNull Collection<D> descriptors) {
|
||||
this.descriptors = descriptors;
|
||||
this.resultCode = resultCode;
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<D> getDescriptors() {
|
||||
return descriptors;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public D getDescriptor() {
|
||||
assert singleDescriptor();
|
||||
return descriptors.iterator().next();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Code getResultCode() {
|
||||
return resultCode;
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return resultCode.isSuccess();
|
||||
}
|
||||
|
||||
public boolean singleDescriptor() {
|
||||
return isSuccess() || resultCode == Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH;
|
||||
}
|
||||
|
||||
public boolean isNothing() {
|
||||
return resultCode == Code.NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
public boolean isAmbiguity() {
|
||||
return resultCode == Code.AMBIGUITY;
|
||||
}
|
||||
|
||||
public OverloadResolutionResult<D> newContents(@NotNull Collection<D> functionDescriptors) {
|
||||
return new OverloadResolutionResult<D>(resultCode, functionDescriptors);
|
||||
}
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
package org.jetbrains.jet.lang.resolve.calls;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class OverloadResolutionResults<D extends CallableDescriptor> {
|
||||
public enum Code {
|
||||
SUCCESS(true),
|
||||
NAME_NOT_FOUND(false),
|
||||
SINGLE_CANDIDATE_ARGUMENT_MISMATCH(false),
|
||||
AMBIGUITY(false),
|
||||
MANY_FAILED_CANDIDATES(false);
|
||||
|
||||
private final boolean success;
|
||||
|
||||
Code(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static <D extends CallableDescriptor> OverloadResolutionResults<D> success(@NotNull ResolvedCall<D> descriptor) {
|
||||
return new OverloadResolutionResults<D>(Code.SUCCESS, Collections.singleton(descriptor));
|
||||
}
|
||||
|
||||
public static <D extends CallableDescriptor> OverloadResolutionResults<D> nameNotFound() {
|
||||
return new OverloadResolutionResults<D>(Code.NAME_NOT_FOUND, Collections.<ResolvedCall<D>>emptyList());
|
||||
}
|
||||
|
||||
public static <D extends CallableDescriptor> OverloadResolutionResults<D> singleFailedCandidate(ResolvedCall<D> candidate) {
|
||||
return new OverloadResolutionResults<D>(Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH, Collections.singleton(candidate));
|
||||
}
|
||||
public static <D extends CallableDescriptor> OverloadResolutionResults<D> manyFailedCandidates(Collection<ResolvedCall<D>> failedCandidates) {
|
||||
return new OverloadResolutionResults<D>(Code.MANY_FAILED_CANDIDATES, failedCandidates);
|
||||
}
|
||||
|
||||
public static <D extends CallableDescriptor> OverloadResolutionResults<D> ambiguity(Collection<ResolvedCall<D>> descriptors) {
|
||||
return new OverloadResolutionResults<D>(Code.AMBIGUITY, descriptors);
|
||||
}
|
||||
|
||||
private final Collection<ResolvedCall<D>> results;
|
||||
private final Code resultCode;
|
||||
|
||||
private OverloadResolutionResults(@NotNull Code resultCode, @NotNull Collection<ResolvedCall<D>> results) {
|
||||
this.results = results;
|
||||
this.resultCode = resultCode;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<ResolvedCall<D>> getResults() {
|
||||
return results;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ResolvedCall<D> getResult() {
|
||||
assert singleDescriptor();
|
||||
return results.iterator().next();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Code getResultCode() {
|
||||
return resultCode;
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return resultCode.isSuccess();
|
||||
}
|
||||
|
||||
public boolean singleDescriptor() {
|
||||
return isSuccess() || resultCode == Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH;
|
||||
}
|
||||
|
||||
public boolean isNothing() {
|
||||
return resultCode == Code.NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
public boolean isAmbiguity() {
|
||||
return resultCode == Code.AMBIGUITY;
|
||||
}
|
||||
//
|
||||
// public OverloadResolutionResults<D> newContents(@NotNull Collection<D> functionDescriptors) {
|
||||
// return new OverloadResolutionResults<D>(resultCode, functionDescriptors);
|
||||
// }
|
||||
}
|
||||
+30
-17
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jet.lang.resolve.calls;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import gnu.trove.THashSet;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||
@@ -8,13 +9,12 @@ import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.OverridingUtil;
|
||||
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
@@ -28,22 +28,35 @@ public class OverloadingConflictResolver {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <Descriptor extends CallableDescriptor> Descriptor findMaximallySpecific(Map<Descriptor, Descriptor> candidates, Map<Descriptor, TemporaryBindingTrace> traces, boolean discriminateGenericDescriptors) {
|
||||
Map<Descriptor, TemporaryBindingTrace> maximallySpecific = Maps.newHashMap();
|
||||
public <D extends CallableDescriptor> ResolvedCall<D> findMaximallySpecific(Set<ResolvedCall<D>> candidates, boolean discriminateGenericDescriptors) {
|
||||
// Different autocasts may lead to the same candidate descriptor wrapped into different ResolvedCall objects
|
||||
Set<ResolvedCall<D>> maximallySpecific = new THashSet<ResolvedCall<D>>(new TObjectHashingStrategy<ResolvedCall<D>>() {
|
||||
@Override
|
||||
public boolean equals(ResolvedCall<D> o1, ResolvedCall<D> o2) {
|
||||
return o1 == null ? o2 == null : o1.getResultingDescriptor().equals(o2.getResultingDescriptor());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int computeHashCode(ResolvedCall<D> object) {
|
||||
return object == null ? 0 : object.getResultingDescriptor().hashCode();
|
||||
}
|
||||
});
|
||||
meLoop:
|
||||
for (Map.Entry<Descriptor, Descriptor> myEntry : candidates.entrySet()) {
|
||||
Descriptor me = myEntry.getValue();
|
||||
TemporaryBindingTrace myTrace = traces.get(myEntry.getKey());
|
||||
for (Descriptor other : candidates.values()) {
|
||||
for (ResolvedCall<D> candidateCall : candidates) {
|
||||
D me = candidateCall.getResultingDescriptor();
|
||||
for (ResolvedCall<D> otherCall : candidates) {
|
||||
D other = otherCall.getResultingDescriptor();
|
||||
if (other == me) continue;
|
||||
if (!moreSpecific(me, other, discriminateGenericDescriptors) || moreSpecific(other, me, discriminateGenericDescriptors)) continue meLoop;
|
||||
if (!moreSpecific(me, other, discriminateGenericDescriptors) || moreSpecific(other, me, discriminateGenericDescriptors)) {
|
||||
continue meLoop;
|
||||
}
|
||||
}
|
||||
maximallySpecific.put(me, myTrace);
|
||||
maximallySpecific.add(candidateCall);
|
||||
}
|
||||
if (maximallySpecific.size() == 1) {
|
||||
Map.Entry<Descriptor, TemporaryBindingTrace> result = maximallySpecific.entrySet().iterator().next();
|
||||
result.getValue().commit();
|
||||
return result.getKey();
|
||||
ResolvedCall<D> result = maximallySpecific.iterator().next();
|
||||
result.getTrace().commit();
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -59,9 +72,9 @@ public class OverloadingConflictResolver {
|
||||
if (OverridingUtil.overrides(f, g)) return true;
|
||||
if (OverridingUtil.overrides(g, f)) return false;
|
||||
|
||||
ReceiverDescriptor receiverOfF = f.getReceiver();
|
||||
ReceiverDescriptor receiverOfG = g.getReceiver();
|
||||
if (f.getReceiver().exists() && g.getReceiver().exists()) {
|
||||
ReceiverDescriptor receiverOfF = f.getReceiverParameter();
|
||||
ReceiverDescriptor receiverOfG = g.getReceiverParameter();
|
||||
if (f.getReceiverParameter().exists() && g.getReceiverParameter().exists()) {
|
||||
if (!typeMoreSpecific(receiverOfF.getType(), receiverOfG.getType())) return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.jetbrains.jet.lang.resolve.calls;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public enum ResolutionStatus {
|
||||
UNKNOWN_STATUS,
|
||||
UNSAFE_CALL_ERROR,
|
||||
OTHER_ERROR,
|
||||
SUCCESS(true);
|
||||
|
||||
private final boolean success;
|
||||
|
||||
private ResolutionStatus(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
private ResolutionStatus() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public ResolutionStatus combine(ResolutionStatus other) {
|
||||
if (this.isSuccess()) return other;
|
||||
if (this.isWeakError() && !other.isSuccess()) return other;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isWeakError() {
|
||||
return this == UNSAFE_CALL_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -1,81 +1,53 @@
|
||||
package org.jetbrains.jet.lang.resolve.calls;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.Call;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetTypeProjection;
|
||||
import org.jetbrains.jet.lang.psi.ValueArgument;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.DataFlowInfo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
/*package*/ class ResolutionTask<Descriptor extends CallableDescriptor> {
|
||||
private final Collection<Descriptor> candidates;
|
||||
private final ReceiverDescriptor receiver;
|
||||
private final List<JetTypeProjection> typeArguments;
|
||||
private final List<? extends ValueArgument> valueArguments;
|
||||
private final List<JetExpression> functionLiteralArguments;
|
||||
/*package*/ class ResolutionTask<D extends CallableDescriptor> {
|
||||
private final Call call;
|
||||
private final Collection<ResolvedCall<D>> candidates;
|
||||
private final DataFlowInfo dataFlowInfo;
|
||||
private DescriptorCheckStrategy checkingStrategy;
|
||||
|
||||
public ResolutionTask(
|
||||
@NotNull Collection<Descriptor> candidates,
|
||||
@NotNull ReceiverDescriptor receiver,
|
||||
@NotNull List<JetTypeProjection> typeArguments,
|
||||
@NotNull List<? extends ValueArgument> valueArguments,
|
||||
@NotNull List<JetExpression> functionLiteralArguments) {
|
||||
this.candidates = candidates;
|
||||
this.receiver = receiver;
|
||||
this.typeArguments = typeArguments;
|
||||
this.valueArguments = valueArguments;
|
||||
this.functionLiteralArguments = functionLiteralArguments;
|
||||
}
|
||||
|
||||
public ResolutionTask(
|
||||
@NotNull Collection<Descriptor> candidates,
|
||||
@NotNull ReceiverDescriptor receiver,
|
||||
@NotNull Call call
|
||||
@NotNull Collection<ResolvedCall<D>> candidates,
|
||||
@NotNull Call call,
|
||||
@NotNull DataFlowInfo dataFlowInfo
|
||||
) {
|
||||
this(candidates, receiver, call.getTypeArguments(), call.getValueArguments(), call.getFunctionLiteralArguments());
|
||||
this.candidates = candidates;
|
||||
this.call = call;
|
||||
this.dataFlowInfo = dataFlowInfo;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<Descriptor> getCandidates() {
|
||||
public DataFlowInfo getDataFlowInfo() {
|
||||
return dataFlowInfo;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<ResolvedCall<D>> getCandidates() {
|
||||
return candidates;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ReceiverDescriptor getReceiver() {
|
||||
return receiver;
|
||||
public Call getCall() {
|
||||
return call;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<JetTypeProjection> getTypeArguments() {
|
||||
return typeArguments;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<? extends ValueArgument> getValueArguments() {
|
||||
return valueArguments;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<JetExpression> getFunctionLiteralArguments() {
|
||||
return functionLiteralArguments;
|
||||
}
|
||||
|
||||
public void setCheckingStrategy(DescriptorCheckStrategy strategy) {
|
||||
checkingStrategy = strategy;
|
||||
}
|
||||
|
||||
public boolean performAdvancedChecks(Descriptor descriptor, BindingTrace trace, TracingStrategy tracing) {
|
||||
public boolean performAdvancedChecks(D descriptor, BindingTrace trace, TracingStrategy tracing) {
|
||||
if (checkingStrategy != null && !checkingStrategy.performAdvancedChecks(descriptor, trace, tracing)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
package org.jetbrains.jet.lang.resolve.calls;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.calls.ResolutionStatus.UNKNOWN_STATUS;
|
||||
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class ResolvedCall<D extends CallableDescriptor> {
|
||||
|
||||
public static final Function<ResolvedCall<? extends CallableDescriptor>, CallableDescriptor> MAP_TO_CANDIDATE = new Function<ResolvedCall<? extends CallableDescriptor>, CallableDescriptor>() {
|
||||
@Override
|
||||
public CallableDescriptor fun(ResolvedCall<? extends CallableDescriptor> resolvedCall) {
|
||||
return resolvedCall.getCandidateDescriptor();
|
||||
}
|
||||
};
|
||||
|
||||
public static final Function<ResolvedCall<? extends CallableDescriptor>, CallableDescriptor> MAP_TO_RESULT = new Function<ResolvedCall<? extends CallableDescriptor>, CallableDescriptor>() {
|
||||
@Override
|
||||
public CallableDescriptor fun(ResolvedCall<? extends CallableDescriptor> resolvedCall) {
|
||||
return resolvedCall.getResultingDescriptor();
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
public static <D extends CallableDescriptor> ResolvedCall<D> create(@NotNull D descriptor) {
|
||||
return new ResolvedCall<D>(descriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <D extends CallableDescriptor> List<ResolvedCall<D>> convertCollection(@NotNull Collection<D> descriptors) {
|
||||
List<ResolvedCall<D>> result = Lists.newArrayList();
|
||||
for (D descriptor : descriptors) {
|
||||
result.add(create(descriptor));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private final D candidateDescriptor;
|
||||
private D resultingDescriptor; // Probably substituted
|
||||
private ReceiverDescriptor thisObject = NO_RECEIVER; // receiver object of a method
|
||||
private ReceiverDescriptor receiverArgument = NO_RECEIVER; // receiver of an extension function
|
||||
private final Map<TypeParameterDescriptor, JetType> typeArguments = Maps.newLinkedHashMap();
|
||||
private final Map<ValueParameterDescriptor, JetType> autoCasts = Maps.newHashMap();
|
||||
private final Map<ValueParameterDescriptor, ResolvedValueArgument> valueArguments = Maps.newHashMap();
|
||||
private boolean someArgumentHasNoType = false;
|
||||
private TemporaryBindingTrace trace;
|
||||
private ResolutionStatus status = UNKNOWN_STATUS;
|
||||
|
||||
private ResolvedCall(@NotNull D candidateDescriptor) {
|
||||
this.candidateDescriptor = candidateDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ResolutionStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(@NotNull ResolutionStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TemporaryBindingTrace getTrace() {
|
||||
return trace;
|
||||
}
|
||||
|
||||
public void setTrace(@NotNull TemporaryBindingTrace trace) {
|
||||
this.trace = trace;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public D getCandidateDescriptor() {
|
||||
return candidateDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public D getResultingDescriptor() {
|
||||
return resultingDescriptor == null ? candidateDescriptor : resultingDescriptor;
|
||||
}
|
||||
|
||||
public ResolvedCall<D> setResultingDescriptor(@NotNull D resultingDescriptor) {
|
||||
this.resultingDescriptor = resultingDescriptor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void recordTypeArgument(@NotNull TypeParameterDescriptor typeParameter, @NotNull JetType typeArgument) {
|
||||
assert !typeArguments.containsKey(typeParameter);
|
||||
typeArguments.put(typeParameter, typeArgument);
|
||||
}
|
||||
|
||||
public void recordValueArgument(@NotNull ValueParameterDescriptor valueParameter, @NotNull ResolvedValueArgument valueArgument) {
|
||||
assert !valueArguments.containsKey(valueParameter);
|
||||
valueArguments.put(valueParameter, valueArgument);
|
||||
}
|
||||
|
||||
public void autoCastValueArgument(@NotNull ValueParameterDescriptor parameter, @NotNull JetType target) {
|
||||
assert !autoCasts.containsKey(parameter);
|
||||
autoCasts.put(parameter, target);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ReceiverDescriptor getReceiverArgument() {
|
||||
return receiverArgument;
|
||||
}
|
||||
|
||||
public void setReceiverArgument(@NotNull ReceiverDescriptor receiverParameter) {
|
||||
this.receiverArgument = receiverParameter;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ReceiverDescriptor getThisObject() {
|
||||
return thisObject;
|
||||
}
|
||||
|
||||
public void setThisObject(@NotNull ReceiverDescriptor thisObject) {
|
||||
this.thisObject = thisObject;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Map<ValueParameterDescriptor, ResolvedValueArgument> getValueArguments() {
|
||||
return valueArguments;
|
||||
}
|
||||
|
||||
public void argumentHasNoType() {
|
||||
this.someArgumentHasNoType = true;
|
||||
}
|
||||
|
||||
public boolean isDirty() {
|
||||
return someArgumentHasNoType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.jetbrains.jet.lang.resolve.calls;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public interface ResolvedValueArgument {
|
||||
@NotNull
|
||||
List<JetExpression> getArgumentExpressions();
|
||||
|
||||
}
|
||||
@@ -2,31 +2,39 @@ package org.jetbrains.jet.lang.resolve.calls;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.Call;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.DataFlowInfo;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.JetTypeChecker;
|
||||
import org.jetbrains.jet.lang.types.NamespaceType;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
/*package*/ abstract class TaskPrioritizer<D extends CallableDescriptor> {
|
||||
|
||||
public static <T extends DeclarationDescriptor> void splitLexicallyLocalDescriptors(
|
||||
Collection<? extends T> allDescriptors, DeclarationDescriptor containerOfTheCurrentLocality, List<? super T> local, List<? super T> nonlocal) {
|
||||
public static <D extends CallableDescriptor> void splitLexicallyLocalDescriptors(
|
||||
Collection<ResolvedCall<D>> allDescriptors, DeclarationDescriptor containerOfTheCurrentLocality, Collection<ResolvedCall<D>> local, Collection<ResolvedCall<D>> nonlocal) {
|
||||
|
||||
for (T descriptor : allDescriptors) {
|
||||
if (isLocal(containerOfTheCurrentLocality, descriptor)) {
|
||||
local.add(descriptor);
|
||||
for (ResolvedCall<D> resolvedCall : allDescriptors) {
|
||||
if (isLocal(containerOfTheCurrentLocality, resolvedCall.getCandidateDescriptor())) {
|
||||
local.add(resolvedCall);
|
||||
}
|
||||
else {
|
||||
nonlocal.add(descriptor);
|
||||
nonlocal.add(resolvedCall);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,7 +51,7 @@ import java.util.List;
|
||||
*
|
||||
* local extension prevail over members (and members prevail over all non-local extensions)
|
||||
*/
|
||||
public static boolean isLocal(DeclarationDescriptor containerOfTheCurrentLocality, DeclarationDescriptor candidate) {
|
||||
private static boolean isLocal(DeclarationDescriptor containerOfTheCurrentLocality, DeclarationDescriptor candidate) {
|
||||
if (candidate instanceof ValueParameterDescriptor) {
|
||||
return true;
|
||||
}
|
||||
@@ -62,67 +70,132 @@ import java.util.List;
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<ResolutionTask<D>> computePrioritizedTasks(@NotNull JetScope scope, @NotNull ReceiverDescriptor receiver, @NotNull Call call, @NotNull String name) {
|
||||
public List<ResolutionTask<D>> computePrioritizedTasks(@NotNull JetScope scope, @NotNull Call call, @NotNull String name, @NotNull BindingContext bindingContext, @NotNull DataFlowInfo dataFlowInfo) {
|
||||
List<ResolutionTask<D>> result = Lists.newArrayList();
|
||||
doComputeTasks(scope, receiver, call, name, result);
|
||||
|
||||
ReceiverDescriptor explicitReceiver = call.getExplicitReceiver();
|
||||
if (explicitReceiver.exists() && explicitReceiver.getType() instanceof NamespaceType) {
|
||||
scope = explicitReceiver.getType().getMemberScope();
|
||||
explicitReceiver = NO_RECEIVER;
|
||||
}
|
||||
doComputeTasks(scope, explicitReceiver, call, name, result, AutoCastService.NO_AUTO_CASTS);
|
||||
|
||||
ReceiverDescriptor receiverToCast = explicitReceiver.exists() ? explicitReceiver : scope.getImplicitReceiver();
|
||||
if (receiverToCast.exists()) {
|
||||
doComputeTasks(scope, receiverToCast, call, name, result, new AutoCastServiceImpl(dataFlowInfo, bindingContext));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void doComputeTasks(JetScope scope, ReceiverDescriptor receiver, Call call, String name, List<ResolutionTask<D>> result) {
|
||||
private void doComputeTasks(JetScope scope, ReceiverDescriptor receiver, Call call, String name, List<ResolutionTask<D>> result, @NotNull AutoCastService autoCastService) {
|
||||
DataFlowInfo dataFlowInfo = autoCastService.getDataFlowInfo();
|
||||
List<ReceiverDescriptor> implicitReceivers = Lists.newArrayList();
|
||||
scope.getImplicitReceiversHierarchy(implicitReceivers);
|
||||
if (receiver != ReceiverDescriptor.NO_RECEIVER) {
|
||||
Collection<D> extensionFunctions = getExtensionsByName(scope, name);
|
||||
List<D> nonlocals = Lists.newArrayList();
|
||||
List<D> locals = Lists.newArrayList();
|
||||
if (receiver.exists()) {
|
||||
List<ReceiverDescriptor> variantsForExplicitReceiver = autoCastService.getVariantsForReceiver(receiver);
|
||||
|
||||
Collection<ResolvedCall<D>> extensionFunctions = convertWithImpliedThis(scope, variantsForExplicitReceiver, getExtensionsByName(scope, name));
|
||||
List<ResolvedCall<D>> nonlocals = Lists.newArrayList();
|
||||
List<ResolvedCall<D>> locals = Lists.newArrayList();
|
||||
//noinspection unchecked,RedundantTypeArguments
|
||||
TaskPrioritizer.<D>splitLexicallyLocalDescriptors(extensionFunctions, scope.getContainingDeclaration(), locals, nonlocals);
|
||||
|
||||
Collection<D> members = getMembersByName(receiver, name);
|
||||
Collection<ResolvedCall<D>> members = Lists.newArrayList();
|
||||
for (ReceiverDescriptor variant : variantsForExplicitReceiver) {
|
||||
Collection<D> membersForThisVariant = getMembersByName(variant.getType(), name);
|
||||
convertWithReceivers(membersForThisVariant, Collections.singletonList(variant), Collections.singletonList(NO_RECEIVER), members);
|
||||
}
|
||||
|
||||
addTask(result, receiver, call, locals);
|
||||
addTask(result, ReceiverDescriptor.NO_RECEIVER, call, members);
|
||||
addTask(result, call, locals, dataFlowInfo);
|
||||
addTask(result, call, members, dataFlowInfo);
|
||||
|
||||
for (ReceiverDescriptor implicitReceiver : implicitReceivers) {
|
||||
Collection<D> memberExtensions = getExtensionsByName(implicitReceiver.getType().getMemberScope(), name);
|
||||
addTask(result, receiver, call, memberExtensions);
|
||||
List<ReceiverDescriptor> variantsForImplicitReceiver = autoCastService.getVariantsForReceiver(implicitReceiver);
|
||||
addTask(result, call, convertWithReceivers(memberExtensions, variantsForImplicitReceiver, variantsForExplicitReceiver), dataFlowInfo);
|
||||
}
|
||||
|
||||
addTask(result, receiver, call, nonlocals);
|
||||
addTask(result, call, nonlocals, dataFlowInfo);
|
||||
}
|
||||
else {
|
||||
Collection<D> functions = getNonExtensionsByName(scope, name);
|
||||
Collection<ResolvedCall<D>> functions = convertWithImpliedThis(scope, Collections.singletonList(receiver), getNonExtensionsByName(scope, name));
|
||||
|
||||
List<D> nonlocals = Lists.newArrayList();
|
||||
List<D> locals = Lists.newArrayList();
|
||||
List<ResolvedCall<D>> nonlocals = Lists.newArrayList();
|
||||
List<ResolvedCall<D>> locals = Lists.newArrayList();
|
||||
//noinspection unchecked,RedundantTypeArguments
|
||||
TaskPrioritizer.<D>splitLexicallyLocalDescriptors(functions, scope.getContainingDeclaration(), locals, nonlocals);
|
||||
|
||||
addTask(result, receiver, call, locals);
|
||||
addTask(result, call, locals, dataFlowInfo);
|
||||
|
||||
for (ReceiverDescriptor implicitReceiver : implicitReceivers) {
|
||||
doComputeTasks(scope, implicitReceiver, call, name, result);
|
||||
doComputeTasks(scope, implicitReceiver, call, name, result, autoCastService);
|
||||
}
|
||||
|
||||
addTask(result, receiver, call, nonlocals);
|
||||
addTask(result, call, nonlocals, dataFlowInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<ResolvedCall<D>> convertWithReceivers(Collection<D> descriptors, Iterable<ReceiverDescriptor> thisObjects, Iterable<ReceiverDescriptor> receiverParameters) {
|
||||
Collection<ResolvedCall<D>> result = Lists.newArrayList();
|
||||
convertWithReceivers(descriptors, thisObjects, receiverParameters, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void convertWithReceivers(Collection<D> descriptors, Iterable<ReceiverDescriptor> thisObjects, Iterable<ReceiverDescriptor> receiverParameters, Collection<ResolvedCall<D>> result) {
|
||||
// Collection<ResolvedCall<D>> result = Lists.newArrayList();
|
||||
for (ReceiverDescriptor thisObject : thisObjects) {
|
||||
for (ReceiverDescriptor receiverParameter : receiverParameters) {
|
||||
for (D extension : descriptors) {
|
||||
ResolvedCall<D> resolvedCall = ResolvedCall.create(extension);
|
||||
resolvedCall.setThisObject(thisObject);
|
||||
resolvedCall.setReceiverArgument(receiverParameter);
|
||||
result.add(resolvedCall);
|
||||
}
|
||||
}
|
||||
}
|
||||
// return result;
|
||||
}
|
||||
|
||||
public static <D extends CallableDescriptor> Collection<ResolvedCall<D>> convertWithImpliedThis(JetScope scope, Iterable<ReceiverDescriptor> receiverParameters, Collection<D> descriptors) {
|
||||
Collection<ResolvedCall<D>> result = Lists.newArrayList();
|
||||
for (ReceiverDescriptor receiverParameter : receiverParameters) {
|
||||
for (D extension : descriptors) {
|
||||
ResolvedCall<D> resolvedCall = ResolvedCall.create(extension);
|
||||
resolvedCall.setReceiverArgument(receiverParameter);
|
||||
if (setImpliedThis(scope, resolvedCall)) {
|
||||
result.add(resolvedCall);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static <D extends CallableDescriptor> boolean setImpliedThis(@NotNull JetScope scope, ResolvedCall<D> resolvedCall) {
|
||||
ReceiverDescriptor expectedThisObject = resolvedCall.getCandidateDescriptor().getExpectedThisObject();
|
||||
if (!expectedThisObject.exists()) return true;
|
||||
List<ReceiverDescriptor> receivers = Lists.newArrayList();
|
||||
scope.getImplicitReceiversHierarchy(receivers);
|
||||
for (ReceiverDescriptor receiver : receivers) {
|
||||
if (JetTypeChecker.INSTANCE.isSubtypeOf(receiver.getType(), expectedThisObject.getType())) {
|
||||
// TODO : Autocasts & nullability
|
||||
resolvedCall.setThisObject(expectedThisObject);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addTask(@NotNull List<ResolutionTask<D>> result, @NotNull Call call, @NotNull Collection<ResolvedCall<D>> candidates, @NotNull DataFlowInfo dataFlowInfo) {
|
||||
if (candidates.isEmpty()) return;
|
||||
result.add(new ResolutionTask<D>(candidates, call, dataFlowInfo));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected abstract Collection<D> getNonExtensionsByName(JetScope scope, String name);
|
||||
|
||||
@NotNull
|
||||
protected abstract Collection<D> getMembersByName(@NotNull ReceiverDescriptor receiver, String name);
|
||||
protected abstract Collection<D> getMembersByName(@NotNull JetType receiver, String name);
|
||||
|
||||
@NotNull
|
||||
protected abstract Collection<D> getExtensionsByName(JetScope scope, String name);
|
||||
|
||||
private void addTask(@NotNull List<ResolutionTask<D>> result, @NotNull ReceiverDescriptor receiver, @NotNull Call call, @NotNull Collection<D> candidates) {
|
||||
if (candidates.isEmpty()) return;
|
||||
result.add(createTask(receiver, call, candidates));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected abstract ResolutionTask<D> createTask(ReceiverDescriptor receiver, Call call, Collection<D> candidates);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
package org.jetbrains.jet.lang.resolve.calls;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class TaskPrioritizers {
|
||||
|
||||
|
||||
/*package*/ static TaskPrioritizer<FunctionDescriptor> FUNCTION_TASK_PRIORITIZER = new TaskPrioritizer<FunctionDescriptor>() {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Collection<FunctionDescriptor> getNonExtensionsByName(JetScope scope, String name) {
|
||||
Set<FunctionDescriptor> functions = Sets.newLinkedHashSet(scope.getFunctions(name));
|
||||
for (Iterator<FunctionDescriptor> iterator = functions.iterator(); iterator.hasNext(); ) {
|
||||
FunctionDescriptor functionDescriptor = iterator.next();
|
||||
if (functionDescriptor.getReceiverParameter().exists()) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
addConstructors(scope, name, functions);
|
||||
|
||||
addVariableAsFunction(scope, name, functions, false);
|
||||
return functions;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Collection<FunctionDescriptor> getMembersByName(@NotNull JetType receiverType, String name) {
|
||||
JetScope receiverScope = receiverType.getMemberScope();
|
||||
Set<FunctionDescriptor> members = Sets.newHashSet(receiverScope.getFunctions(name));
|
||||
addConstructors(receiverScope, name, members);
|
||||
addVariableAsFunction(receiverScope, name, members, false);
|
||||
return members;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Collection<FunctionDescriptor> getExtensionsByName(JetScope scope, String name) {
|
||||
Set<FunctionDescriptor> extensionFunctions = Sets.newHashSet(scope.getFunctions(name));
|
||||
for (Iterator<FunctionDescriptor> iterator = extensionFunctions.iterator(); iterator.hasNext(); ) {
|
||||
FunctionDescriptor descriptor = iterator.next();
|
||||
if (!descriptor.getReceiverParameter().exists()) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
addVariableAsFunction(scope, name, extensionFunctions, true);
|
||||
return extensionFunctions;
|
||||
}
|
||||
|
||||
private void addConstructors(JetScope scope, String name, Collection<FunctionDescriptor> functions) {
|
||||
ClassifierDescriptor classifier = scope.getClassifier(name);
|
||||
if (classifier instanceof ClassDescriptor && !ErrorUtils.isError(classifier.getTypeConstructor())) {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) classifier;
|
||||
functions.addAll(classDescriptor.getConstructors());
|
||||
}
|
||||
}
|
||||
|
||||
private void addVariableAsFunction(JetScope scope, String name, Set<FunctionDescriptor> functions, boolean receiverNeeded) {
|
||||
VariableDescriptor variable = scope.getVariable(name);
|
||||
if (variable != null && !variable.getReceiverParameter().exists()) {
|
||||
JetType outType = variable.getOutType();
|
||||
if (outType != null && JetStandardClasses.isFunctionType(outType)) {
|
||||
VariableAsFunctionDescriptor functionDescriptor = VariableAsFunctionDescriptor.create(variable);
|
||||
if ((functionDescriptor.getReceiverParameter().exists()) == receiverNeeded) {
|
||||
functions.add(functionDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*package*/ static TaskPrioritizer<VariableDescriptor> PROPERTY_TASK_PRIORITIZER = new TaskPrioritizer<VariableDescriptor>() {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Collection<VariableDescriptor> getNonExtensionsByName(JetScope scope, String name) {
|
||||
VariableDescriptor variable = scope.getVariable(name);
|
||||
if (variable != null && !variable.getReceiverParameter().exists()) {
|
||||
return Collections.singleton(variable);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Collection<VariableDescriptor> getMembersByName(@NotNull JetType receiverType, String name) {
|
||||
VariableDescriptor variable = receiverType.getMemberScope().getVariable(name);
|
||||
if (variable != null) {
|
||||
return Collections.singleton(variable);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Collection<VariableDescriptor> getExtensionsByName(JetScope scope, String name) {
|
||||
VariableDescriptor variable = scope.getVariable(name);
|
||||
if (variable != null && variable.getReceiverParameter().exists()) {
|
||||
return Collections.singleton(variable);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
@@ -15,17 +16,20 @@ import java.util.Set;
|
||||
/*package*/ interface TracingStrategy {
|
||||
TracingStrategy EMPTY = new TracingStrategy() {
|
||||
@Override
|
||||
public void bindReference(@NotNull BindingTrace trace, @NotNull ReceiverDescriptor receiver, @NotNull CallableDescriptor descriptor) {}
|
||||
public <D extends CallableDescriptor> void bindReference(@NotNull BindingTrace trace, @NotNull ResolvedCall<D> resolvedCall) {}
|
||||
|
||||
@Override
|
||||
public void unresolvedReference(@NotNull BindingTrace trace) {}
|
||||
|
||||
@Override
|
||||
public <D extends CallableDescriptor> void recordAmbiguity(BindingTrace trace, Collection<D> candidates) {}
|
||||
public <D extends CallableDescriptor> void recordAmbiguity(BindingTrace trace, Collection<ResolvedCall<D>> candidates) {}
|
||||
|
||||
@Override
|
||||
public void missingReceiver(@NotNull BindingTrace trace, @NotNull ReceiverDescriptor expectedReceiver) {}
|
||||
|
||||
@Override
|
||||
public void wrongReceiverType(@NotNull BindingTrace trace, @NotNull ReceiverDescriptor receiverParameter, @NotNull ReceiverDescriptor receiverArgument) {}
|
||||
|
||||
@Override
|
||||
public void noReceiverAllowed(@NotNull BindingTrace trace) {}
|
||||
|
||||
@@ -36,37 +40,49 @@ import java.util.Set;
|
||||
public void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount) {}
|
||||
|
||||
@Override
|
||||
public void ambiguity(@NotNull BindingTrace trace, @NotNull Set<? extends CallableDescriptor> descriptors) {}
|
||||
public <D extends CallableDescriptor> void ambiguity(@NotNull BindingTrace trace, @NotNull Set<ResolvedCall<D>> descriptors) {}
|
||||
|
||||
@Override
|
||||
public void noneApplicable(@NotNull BindingTrace trace, @NotNull Set<? extends CallableDescriptor> descriptors) {}
|
||||
public <D extends CallableDescriptor> void noneApplicable(@NotNull BindingTrace trace, @NotNull Set<ResolvedCall<D>> descriptors) {}
|
||||
|
||||
@Override
|
||||
public void instantiationOfAbstractClass(@NotNull BindingTrace trace) {}
|
||||
|
||||
@Override
|
||||
public void typeInferenceFailed(@NotNull BindingTrace trace) {}
|
||||
|
||||
@Override
|
||||
public void unsafeCall(@NotNull BindingTrace trace, @NotNull JetType type) {}
|
||||
|
||||
@Override
|
||||
public void unnecessarySafeCall(@NotNull BindingTrace trace, @NotNull JetType type) {}
|
||||
};
|
||||
|
||||
void bindReference(@NotNull BindingTrace trace, @NotNull ReceiverDescriptor receiver, @NotNull CallableDescriptor descriptor);
|
||||
<D extends CallableDescriptor> void bindReference(@NotNull BindingTrace trace, @NotNull ResolvedCall<D> resolvedCall);
|
||||
|
||||
void unresolvedReference(@NotNull BindingTrace trace);
|
||||
|
||||
<D extends CallableDescriptor> void recordAmbiguity(BindingTrace trace, Collection<D> candidates);
|
||||
<D extends CallableDescriptor> void recordAmbiguity(BindingTrace trace, Collection<ResolvedCall<D>> candidates);
|
||||
|
||||
void missingReceiver(@NotNull BindingTrace trace, @NotNull ReceiverDescriptor expectedReceiver);
|
||||
|
||||
void wrongReceiverType(@NotNull BindingTrace trace, @NotNull ReceiverDescriptor receiverParameter, @NotNull ReceiverDescriptor receiverArgument);
|
||||
|
||||
void noReceiverAllowed(@NotNull BindingTrace trace);
|
||||
|
||||
void noValueForParameter(@NotNull BindingTrace trace, @NotNull ValueParameterDescriptor valueParameter);
|
||||
|
||||
void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount);
|
||||
|
||||
void ambiguity(@NotNull BindingTrace trace, @NotNull Set<? extends CallableDescriptor> descriptors);
|
||||
<D extends CallableDescriptor> void ambiguity(@NotNull BindingTrace trace, @NotNull Set<ResolvedCall<D>> descriptors);
|
||||
|
||||
void noneApplicable(@NotNull BindingTrace trace, @NotNull Set<? extends CallableDescriptor> descriptors);
|
||||
<D extends CallableDescriptor> void noneApplicable(@NotNull BindingTrace trace, @NotNull Set<ResolvedCall<D>> descriptors);
|
||||
|
||||
void instantiationOfAbstractClass(@NotNull BindingTrace trace);
|
||||
|
||||
void typeInferenceFailed(@NotNull BindingTrace trace);
|
||||
|
||||
void unsafeCall(@NotNull BindingTrace trace, @NotNull JetType type);
|
||||
|
||||
void unnecessarySafeCall(@NotNull BindingTrace trace, @NotNull JetType type);
|
||||
}
|
||||
|
||||
+58
-18
@@ -6,7 +6,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.CallMaker;
|
||||
|
||||
import java.util.List;
|
||||
@@ -20,15 +21,17 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||
* @author abreslav
|
||||
*/
|
||||
/*package*/ class ValueArgumentsToParametersMapper {
|
||||
public static <Descriptor extends CallableDescriptor> boolean mapValueArgumentsToParameters(
|
||||
@NotNull ResolutionTask<Descriptor> task,
|
||||
public static <D extends CallableDescriptor> boolean mapValueArgumentsToParameters(
|
||||
@NotNull ResolutionTask<D> task,
|
||||
@NotNull TracingStrategy tracing,
|
||||
@NotNull Descriptor candidate,
|
||||
@NotNull BindingTrace temporaryTrace,
|
||||
@NotNull Map<ValueArgument, ValueParameterDescriptor> argumentsToParameters
|
||||
@NotNull ResolvedCall<D> candidateCall
|
||||
) {
|
||||
|
||||
TemporaryBindingTrace temporaryTrace = candidateCall.getTrace();
|
||||
Map<ValueParameterDescriptor, VarargValueArgument> varargs = Maps.newHashMap();
|
||||
Set<ValueParameterDescriptor> usedParameters = Sets.newHashSet();
|
||||
|
||||
D candidate = candidateCall.getCandidateDescriptor();
|
||||
List<ValueParameterDescriptor> valueParameters = candidate.getValueParameters();
|
||||
|
||||
Map<String, ValueParameterDescriptor> parameterByName = Maps.newHashMap();
|
||||
@@ -36,7 +39,7 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||
parameterByName.put(valueParameter.getName(), valueParameter);
|
||||
}
|
||||
|
||||
List<? extends ValueArgument> valueArguments = task.getValueArguments();
|
||||
List<? extends ValueArgument> valueArguments = task.getCall().getValueArguments();
|
||||
|
||||
boolean error = false;
|
||||
boolean someNamed = false;
|
||||
@@ -58,7 +61,7 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||
temporaryTrace.report(ARGUMENT_PASSED_TWICE.on(nameReference));
|
||||
}
|
||||
temporaryTrace.record(REFERENCE_TARGET, nameReference, valueParameterDescriptor);
|
||||
argumentsToParameters.put(valueArgument, valueParameterDescriptor);
|
||||
put(candidateCall, valueParameterDescriptor, valueArgument, varargs);
|
||||
}
|
||||
if (somePositioned) {
|
||||
// temporaryTrace.getErrorHandler().genericError(nameNode, "Mixing named and positioned arguments in not allowed");
|
||||
@@ -78,12 +81,12 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||
if (i < parameterCount) {
|
||||
ValueParameterDescriptor valueParameterDescriptor = valueParameters.get(i);
|
||||
usedParameters.add(valueParameterDescriptor);
|
||||
argumentsToParameters.put(valueArgument, valueParameterDescriptor);
|
||||
put(candidateCall, valueParameterDescriptor, valueArgument, varargs);
|
||||
}
|
||||
else if (!valueParameters.isEmpty()) {
|
||||
ValueParameterDescriptor valueParameterDescriptor = valueParameters.get(valueParameters.size() - 1);
|
||||
if (valueParameterDescriptor.isVararg()) {
|
||||
argumentsToParameters.put(valueArgument, valueParameterDescriptor);
|
||||
put(candidateCall, valueParameterDescriptor, valueArgument, varargs);
|
||||
usedParameters.add(valueParameterDescriptor);
|
||||
}
|
||||
else {
|
||||
@@ -101,7 +104,7 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||
}
|
||||
}
|
||||
|
||||
List<JetExpression> functionLiteralArguments = task.getFunctionLiteralArguments();
|
||||
List<JetExpression> functionLiteralArguments = task.getCall().getFunctionLiteralArguments();
|
||||
if (!functionLiteralArguments.isEmpty()) {
|
||||
JetExpression possiblyLabeledFunctionLiteral = functionLiteralArguments.get(0);
|
||||
|
||||
@@ -109,7 +112,8 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||
// temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), getTooManyArgumentsMessage(candidate));
|
||||
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(possiblyLabeledFunctionLiteral, candidate));
|
||||
error = true;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
JetFunctionLiteralExpression functionLiteral;
|
||||
if (possiblyLabeledFunctionLiteral instanceof JetLabelQualifiedExpression) {
|
||||
JetLabelQualifiedExpression labeledFunctionLiteral = (JetLabelQualifiedExpression) possiblyLabeledFunctionLiteral;
|
||||
@@ -119,20 +123,20 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||
functionLiteral = (JetFunctionLiteralExpression) possiblyLabeledFunctionLiteral;
|
||||
}
|
||||
|
||||
ValueParameterDescriptor parameterDescriptor = valueParameters.get(valueParameters.size() - 1);
|
||||
if (parameterDescriptor.isVararg()) {
|
||||
ValueParameterDescriptor valueParameterDescriptor = valueParameters.get(valueParameters.size() - 1);
|
||||
if (valueParameterDescriptor.isVararg()) {
|
||||
// temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), "Passing value as a vararg is only allowed inside a parenthesized argument list");
|
||||
temporaryTrace.report(VARARG_OUTSIDE_PARENTHESES.on(possiblyLabeledFunctionLiteral));
|
||||
error = true;
|
||||
}
|
||||
else {
|
||||
if (!usedParameters.add(parameterDescriptor)) {
|
||||
if (!usedParameters.add(valueParameterDescriptor)) {
|
||||
// temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), getTooManyArgumentsMessage(candidate));
|
||||
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(possiblyLabeledFunctionLiteral, candidate));
|
||||
error = true;
|
||||
}
|
||||
else {
|
||||
argumentsToParameters.put(CallMaker.makeValueArgument(functionLiteral), parameterDescriptor);
|
||||
put(candidateCall, valueParameterDescriptor, CallMaker.makeValueArgument(functionLiteral), varargs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -148,16 +152,52 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||
|
||||
for (ValueParameterDescriptor valueParameter : valueParameters) {
|
||||
if (!usedParameters.contains(valueParameter)) {
|
||||
if (!valueParameter.hasDefaultValue() && !valueParameter.isVararg()) {
|
||||
// tracing.reportWrongValueArguments(temporaryTrace, "No value passed for parameter " + valueParameter.getName());
|
||||
if (valueParameter.hasDefaultValue()) {
|
||||
candidateCall.recordValueArgument(valueParameter, DefaultValueArgument.DEFAULT);
|
||||
}
|
||||
else if (valueParameter.isVararg()) {
|
||||
candidateCall.recordValueArgument(valueParameter, new VarargValueArgument());
|
||||
}
|
||||
else {
|
||||
// tracing.reportWrongValueArguments(temporaryTrace, "No value passed for parameter " + valueParameter.getName());
|
||||
tracing.noValueForParameter(temporaryTrace, valueParameter);
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReceiverDescriptor receiverParameter = candidate.getReceiverParameter();
|
||||
ReceiverDescriptor receiverArgument = candidateCall.getReceiverArgument();
|
||||
if (receiverParameter.exists() &&!receiverArgument.exists()) {
|
||||
tracing.missingReceiver(temporaryTrace, receiverParameter);
|
||||
error = true;
|
||||
}
|
||||
if (!receiverParameter.exists() && receiverArgument.exists()) {
|
||||
tracing.noReceiverAllowed(temporaryTrace);
|
||||
error = true;
|
||||
}
|
||||
|
||||
assert candidateCall.getThisObject().exists() == candidateCall.getResultingDescriptor().getExpectedThisObject().exists() : "Shouldn't happen because of TaskPrioritizer: " + candidateCall.getCandidateDescriptor();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
private static <D extends CallableDescriptor> void put(ResolvedCall<D> candidateCall, ValueParameterDescriptor valueParameterDescriptor, ValueArgument valueArgument, Map<ValueParameterDescriptor, VarargValueArgument> varargs) {
|
||||
if (valueParameterDescriptor.isVararg()) {
|
||||
VarargValueArgument vararg = varargs.get(valueParameterDescriptor);
|
||||
if (vararg == null) {
|
||||
vararg = new VarargValueArgument();
|
||||
varargs.put(valueParameterDescriptor, vararg);
|
||||
candidateCall.recordValueArgument(valueParameterDescriptor, vararg);
|
||||
}
|
||||
vararg.getArgumentExpressions().add(valueArgument.getArgumentExpression());
|
||||
}
|
||||
else {
|
||||
ResolvedValueArgument argument = new ExpressionValueArgument(valueArgument.getArgumentExpression());
|
||||
candidateCall.recordValueArgument(valueParameterDescriptor, argument);
|
||||
}
|
||||
}
|
||||
|
||||
// private static <Descriptor extends CallableDescriptor> String getTooManyArgumentsMessage(Descriptor candidate) {
|
||||
// return "Too many arguments for " + DescriptorRenderer.TEXT.render(candidate);
|
||||
// }
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.jetbrains.jet.lang.resolve.calls;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class VarargValueArgument implements ResolvedValueArgument {
|
||||
private final List<JetExpression> values = Lists.newArrayList();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JetExpression> getArgumentExpressions() {
|
||||
return values;
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,8 @@ public interface WritableScope extends JetScope {
|
||||
|
||||
void addClassifierAlias(@NotNull String name, @NotNull ClassifierDescriptor classifierDescriptor);
|
||||
|
||||
void addNamespaceAlias(@NotNull String name, @NotNull NamespaceDescriptor namespaceDescriptor);
|
||||
|
||||
void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor);
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -27,9 +27,13 @@ public class WritableScopeImpl extends WritableScopeWithImports {
|
||||
|
||||
@Nullable
|
||||
private SetMultimap<String, FunctionDescriptor> functionGroups;
|
||||
|
||||
@Nullable
|
||||
private Map<String, DeclarationDescriptor> variableClassOrNamespaceDescriptors;
|
||||
|
||||
@Nullable
|
||||
private Map<String, NamespaceDescriptor> namespaceAliases;
|
||||
|
||||
@Nullable
|
||||
private Map<String, List<DeclarationDescriptor>> labelsToDescriptors;
|
||||
|
||||
@@ -66,6 +70,12 @@ public class WritableScopeImpl extends WritableScopeWithImports {
|
||||
super.importClassifierAlias(importedClassifierName, classifierDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void importNamespaceAlias(String aliasName, NamespaceDescriptor namespaceDescriptor) {
|
||||
allDescriptors.add(namespaceDescriptor);
|
||||
super.importNamespaceAlias(aliasName, namespaceDescriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<DeclarationDescriptor> getAllDescriptors() {
|
||||
@@ -123,6 +133,14 @@ public class WritableScopeImpl extends WritableScopeWithImports {
|
||||
return variableClassOrNamespaceDescriptors;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Map<String, NamespaceDescriptor> getNamespaceAliases() {
|
||||
if (namespaceAliases == null) {
|
||||
namespaceAliases = Maps.newHashMap();
|
||||
}
|
||||
return namespaceAliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addVariableDescriptor(@NotNull VariableDescriptor variableDescriptor) {
|
||||
Map<String, DeclarationDescriptor> variableClassOrNamespaceDescriptors = getVariableClassOrNamespaceDescriptors();
|
||||
@@ -189,13 +207,23 @@ public class WritableScopeImpl extends WritableScopeWithImports {
|
||||
|
||||
@Override
|
||||
public void addClassifierAlias(@NotNull String name, @NotNull ClassifierDescriptor classifierDescriptor) {
|
||||
Map<String, DeclarationDescriptor> variableClassOrNamespaceDescriptors = getVariableClassOrNamespaceDescriptors();
|
||||
DeclarationDescriptor originalDescriptor = variableClassOrNamespaceDescriptors.get(name);
|
||||
checkForRedeclaration(name, classifierDescriptor);
|
||||
getVariableClassOrNamespaceDescriptors().put(name, classifierDescriptor);
|
||||
allDescriptors.add(classifierDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNamespaceAlias(@NotNull String name, @NotNull NamespaceDescriptor namespaceDescriptor) {
|
||||
checkForRedeclaration(name, namespaceDescriptor);
|
||||
getNamespaceAliases().put(name, namespaceDescriptor);
|
||||
allDescriptors.add(namespaceDescriptor);
|
||||
}
|
||||
|
||||
private void checkForRedeclaration(String name, DeclarationDescriptor classifierDescriptor) {
|
||||
DeclarationDescriptor originalDescriptor = getVariableClassOrNamespaceDescriptors().get(name);
|
||||
if (originalDescriptor != null) {
|
||||
redeclarationHandler.handleRedeclaration(originalDescriptor, classifierDescriptor);
|
||||
}
|
||||
variableClassOrNamespaceDescriptors.put(name, classifierDescriptor);
|
||||
allDescriptors.add(classifierDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -242,6 +270,9 @@ public class WritableScopeImpl extends WritableScopeWithImports {
|
||||
NamespaceDescriptor declaredNamespace = getDeclaredNamespace(name);
|
||||
if (declaredNamespace != null) return declaredNamespace;
|
||||
|
||||
NamespaceDescriptor aliased = getNamespaceAliases().get(name);
|
||||
if (aliased != null) return aliased;
|
||||
|
||||
NamespaceDescriptor namespace = getWorkerScope().getNamespace(name);
|
||||
if (namespace != null) return namespace;
|
||||
return super.getNamespace(name);
|
||||
|
||||
+11
-2
@@ -97,15 +97,24 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement
|
||||
return null;
|
||||
}
|
||||
|
||||
public void importClassifierAlias(@NotNull String importedClassifierName, @NotNull ClassifierDescriptor classifierDescriptor) {
|
||||
private WritableScope getCurrentIndividualImportScope() {
|
||||
if (currentIndividualImportScope == null) {
|
||||
WritableScopeImpl writableScope = new WritableScopeImpl(EMPTY, getContainingDeclaration(), RedeclarationHandler.DO_NOTHING).setDebugName("Individual import scope");
|
||||
importScope(writableScope);
|
||||
currentIndividualImportScope = writableScope;
|
||||
}
|
||||
currentIndividualImportScope.addClassifierAlias(importedClassifierName, classifierDescriptor);
|
||||
return currentIndividualImportScope;
|
||||
}
|
||||
|
||||
public void importClassifierAlias(@NotNull String importedClassifierName, @NotNull ClassifierDescriptor classifierDescriptor) {
|
||||
getCurrentIndividualImportScope().addClassifierAlias(importedClassifierName, classifierDescriptor);
|
||||
}
|
||||
|
||||
|
||||
public void importNamespaceAlias(String aliasName, NamespaceDescriptor namespaceDescriptor) {
|
||||
getCurrentIndividualImportScope().addNamespaceAlias(aliasName, namespaceDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + "@" + Integer.toHexString(System.identityHashCode(this)) + " " + debugName + " for " + getContainingDeclaration();
|
||||
|
||||
@@ -126,6 +126,11 @@ public class WriteThroughScope extends WritableScopeWithImports {
|
||||
writableWorker.addClassifierAlias(name, classifierDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNamespaceAlias(@NotNull String name, @NotNull NamespaceDescriptor namespaceDescriptor) {
|
||||
writableWorker.addNamespaceAlias(name, namespaceDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) {
|
||||
writableWorker.addNamespace(namespaceDescriptor);
|
||||
|
||||
+17
-3
@@ -2,14 +2,28 @@ package org.jetbrains.jet.lang.resolve.scopes.receivers;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class ClassReceiver extends ImplicitReceiverDescriptor {
|
||||
public class ClassReceiver implements ReceiverDescriptor {
|
||||
|
||||
public ClassReceiver(ClassDescriptor classDescriptor) {
|
||||
super(classDescriptor, classDescriptor.getDefaultType());
|
||||
private final ClassDescriptor classDescriptor;
|
||||
|
||||
public ClassReceiver(@NotNull ClassDescriptor classDescriptor) {
|
||||
this.classDescriptor = classDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetType getType() {
|
||||
return classDescriptor.getDefaultType();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ public class ReceiverDescriptorVisitor<R, D> {
|
||||
return null;
|
||||
}
|
||||
|
||||
public R visitClassReceiver(ClassReceiver classReceiver, D data) {
|
||||
public R visitClassReceiver(ClassReceiver receiver, D data) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package org.jetbrains.jet.lang.types;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -17,8 +19,8 @@ public class CallMaker {
|
||||
private static class ExpressionValueArgument implements ValueArgument {
|
||||
|
||||
private final JetExpression expression;
|
||||
private final PsiElement reportErrorsOn;
|
||||
|
||||
private final PsiElement reportErrorsOn;
|
||||
private ExpressionValueArgument(@NotNull JetExpression expression) {
|
||||
this(expression, expression);
|
||||
}
|
||||
@@ -60,18 +62,72 @@ public class CallMaker {
|
||||
}
|
||||
|
||||
}
|
||||
private static abstract class CallStub implements Call {
|
||||
|
||||
private static class CallImpl implements Call {
|
||||
|
||||
private final ASTNode callNode;
|
||||
private final PsiElement callElement;
|
||||
private final ReceiverDescriptor explicitReceiver;
|
||||
private ASTNode callOperationNode;
|
||||
private final JetExpression calleeExpression;
|
||||
private final List<? extends ValueArgument> valueArguments;
|
||||
|
||||
protected CallImpl(@NotNull ASTNode callNode, @Nullable PsiElement callElement, @NotNull ReceiverDescriptor explicitReceiver, @Nullable ASTNode callOperationNode, @NotNull JetExpression calleeExpression, @NotNull List<? extends ValueArgument> valueArguments) {
|
||||
this.callNode = callNode;
|
||||
this.callElement = callElement;
|
||||
this.explicitReceiver = explicitReceiver;
|
||||
this.callOperationNode = callOperationNode;
|
||||
this.calleeExpression = calleeExpression;
|
||||
this.valueArguments = valueArguments;
|
||||
}
|
||||
|
||||
protected CallImpl(@NotNull PsiElement callElement, @NotNull ReceiverDescriptor explicitReceiver, @Nullable ASTNode callOperationNode, @NotNull JetExpression calleeExpression, @NotNull List<? extends ValueArgument> valueArguments) {
|
||||
this(callElement.getNode(), callElement, explicitReceiver, callOperationNode, calleeExpression, valueArguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ASTNode getCallOperationNode() {
|
||||
return callOperationNode;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ReceiverDescriptor getExplicitReceiver() {
|
||||
return explicitReceiver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetExpression getCalleeExpression() {
|
||||
return calleeExpression;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<? extends ValueArgument> getValueArguments() {
|
||||
return valueArguments;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ASTNode getCallNode() {
|
||||
return callNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getCallElement() {
|
||||
return callElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetValueArgumentList getValueArgumentList() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JetExpression> getFunctionLiteralArguments() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JetTypeProjection> getTypeArguments() {
|
||||
@@ -83,42 +139,36 @@ public class CallMaker {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
public static Call makeCallWithArguments(final JetExpression calleeExpression, final List<? extends ValueArgument> valueArguments) {
|
||||
return new CallStub() {
|
||||
@Override
|
||||
public JetExpression getCalleeExpression() {
|
||||
return calleeExpression;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<? extends ValueArgument> getValueArguments() {
|
||||
return valueArguments;
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public String toString() {
|
||||
return getCallNode().getText();
|
||||
}
|
||||
}
|
||||
|
||||
public static Call makeCall(final JetExpression calleeExpression, final List<JetExpression> argumentExpressions) {
|
||||
public static Call makeCallWithExpressions(@NotNull JetElement callElement, @NotNull ReceiverDescriptor explicitReceiver, @Nullable ASTNode callOperationNode, @NotNull JetExpression calleeExpression, @NotNull List<JetExpression> argumentExpressions) {
|
||||
List<ValueArgument> arguments = Lists.newArrayList();
|
||||
for (JetExpression argumentExpression : argumentExpressions) {
|
||||
arguments.add(makeValueArgument(argumentExpression, calleeExpression));
|
||||
}
|
||||
return makeCallWithArguments(calleeExpression, arguments);
|
||||
return makeCall(callElement, explicitReceiver, callOperationNode, calleeExpression, arguments);
|
||||
}
|
||||
|
||||
public static Call makeCall(final JetBinaryExpression expression) {
|
||||
return makeCall(expression.getOperationReference(), Collections.singletonList(expression.getRight()));
|
||||
public static Call makeCall(JetElement callElement, ReceiverDescriptor explicitReceiver, @Nullable ASTNode callOperationNode, JetExpression calleeExpression, List<? extends ValueArgument> arguments) {
|
||||
return new CallImpl(callElement, explicitReceiver, callOperationNode, calleeExpression, arguments);
|
||||
}
|
||||
|
||||
public static Call makeCall(final JetUnaryExpression expression) {
|
||||
return makeCallWithArguments(expression.getOperationSign(), Collections.<ValueArgument>emptyList());
|
||||
public static Call makeCall(@NotNull ReceiverDescriptor leftAsReceiver, JetBinaryExpression expression) {
|
||||
return makeCallWithExpressions(expression, leftAsReceiver, null, expression.getOperationReference(), Collections.singletonList(expression.getRight()));
|
||||
}
|
||||
|
||||
public static Call makeCall(final JetArrayAccessExpression arrayAccessExpression, final JetExpression rightHandSide) {
|
||||
public static Call makeCall(@NotNull ReceiverDescriptor baseAsReceiver, JetUnaryExpression expression) {
|
||||
return makeCall(expression, baseAsReceiver, null, expression.getOperationSign(), Collections.<ValueArgument>emptyList());
|
||||
}
|
||||
|
||||
public static Call makeCall(@NotNull ReceiverDescriptor arrayAsReceiver,JetArrayAccessExpression arrayAccessExpression, JetExpression rightHandSide) {
|
||||
List<JetExpression> arguments = Lists.newArrayList(arrayAccessExpression.getIndexExpressions());
|
||||
arguments.add(rightHandSide);
|
||||
return makeCall(arrayAccessExpression, arguments);
|
||||
return makeCallWithExpressions(arrayAccessExpression, arrayAsReceiver, null, arrayAccessExpression, arguments);
|
||||
}
|
||||
|
||||
public static ValueArgument makeValueArgument(@NotNull JetExpression expression) {
|
||||
@@ -129,7 +179,68 @@ public class CallMaker {
|
||||
return new ExpressionValueArgument(expression, reportErrorsOn);
|
||||
}
|
||||
|
||||
public static Call makePropertyCall(@NotNull JetSimpleNameExpression nameExpression) {
|
||||
return makeCall(nameExpression, Collections.<JetExpression>emptyList());
|
||||
public static Call makePropertyCall(@NotNull ReceiverDescriptor explicitReceiver, @Nullable ASTNode callOperationNode, @NotNull JetSimpleNameExpression nameExpression) {
|
||||
return makeCallWithExpressions(nameExpression, explicitReceiver, callOperationNode, nameExpression, Collections.<JetExpression>emptyList());
|
||||
}
|
||||
|
||||
public static Call makeCall(@NotNull final ReceiverDescriptor explicitReceiver, @Nullable final ASTNode callOperationNode, @NotNull final JetCallElement callElement) {
|
||||
return new Call() {
|
||||
@Override
|
||||
public ASTNode getCallOperationNode() {
|
||||
return callOperationNode;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ReceiverDescriptor getExplicitReceiver() {
|
||||
return explicitReceiver;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JetExpression getCalleeExpression() {
|
||||
return callElement.getCalleeExpression();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JetValueArgumentList getValueArgumentList() {
|
||||
return callElement.getValueArgumentList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<? extends ValueArgument> getValueArguments() {
|
||||
return callElement.getValueArguments();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<JetExpression> getFunctionLiteralArguments() {
|
||||
return callElement.getFunctionLiteralArguments();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<JetTypeProjection> getTypeArguments() {
|
||||
return callElement.getTypeArguments();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JetTypeArgumentList getTypeArgumentList() {
|
||||
return callElement.getTypeArgumentList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ASTNode getCallNode() {
|
||||
return callElement.getNode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getCallElement() {
|
||||
return callElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return callElement.toString();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.google.common.collect.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.util.CommonSuppliers;
|
||||
|
||||
import java.util.*;
|
||||
@@ -14,9 +15,9 @@ import java.util.*;
|
||||
public class DataFlowInfo {
|
||||
|
||||
public static abstract class CompositionOperator {
|
||||
|
||||
public abstract DataFlowInfo compose(DataFlowInfo a, DataFlowInfo b);
|
||||
}
|
||||
|
||||
public static final CompositionOperator AND = new CompositionOperator() {
|
||||
@Override
|
||||
public DataFlowInfo compose(DataFlowInfo a, DataFlowInfo b) {
|
||||
@@ -31,7 +32,7 @@ public class DataFlowInfo {
|
||||
}
|
||||
};
|
||||
|
||||
private static DataFlowInfo EMPTY = new DataFlowInfo(ImmutableMap.<VariableDescriptor, NullabilityFlags>of(), Multimaps.newListMultimap(Collections.<VariableDescriptor, Collection<JetType>>emptyMap(), CommonSuppliers.<JetType>getArrayListSupplier()));
|
||||
private static DataFlowInfo EMPTY = new DataFlowInfo(ImmutableMap.<Object, NullabilityFlags>of(), Multimaps.newListMultimap(Collections.<Object, Collection<JetType>>emptyMap(), CommonSuppliers.<JetType>getArrayListSupplier()));
|
||||
|
||||
public static DataFlowInfo getEmpty() {
|
||||
return EMPTY;
|
||||
@@ -39,10 +40,11 @@ public class DataFlowInfo {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private final ImmutableMap<VariableDescriptor, NullabilityFlags> nullabilityInfo;
|
||||
private final ListMultimap<VariableDescriptor, JetType> typeInfo;
|
||||
private final ImmutableMap<Object, NullabilityFlags> nullabilityInfo;
|
||||
|
||||
private DataFlowInfo(ImmutableMap<VariableDescriptor, NullabilityFlags> nullabilityInfo, ListMultimap<VariableDescriptor, JetType> typeInfo) {
|
||||
private final ListMultimap<Object, JetType> typeInfo;
|
||||
|
||||
private DataFlowInfo(ImmutableMap<Object, NullabilityFlags> nullabilityInfo, ListMultimap<Object, JetType> typeInfo) {
|
||||
this.nullabilityInfo = nullabilityInfo;
|
||||
this.typeInfo = typeInfo;
|
||||
}
|
||||
@@ -60,13 +62,16 @@ public class DataFlowInfo {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<JetType> getPossibleTypes(VariableDescriptor variableDescriptor) {
|
||||
List<JetType> types = typeInfo.get(variableDescriptor);
|
||||
NullabilityFlags nullabilityFlags = nullabilityInfo.get(variableDescriptor);
|
||||
private List<JetType> getPossibleTypes(Object key, @NotNull JetType originalType) {
|
||||
List<JetType> types = typeInfo.get(key);
|
||||
NullabilityFlags nullabilityFlags = nullabilityInfo.get(key);
|
||||
if (nullabilityFlags == null || nullabilityFlags.canBeNull()) {
|
||||
return types;
|
||||
}
|
||||
List<JetType> enrichedTypes = Lists.newArrayListWithCapacity(types.size());
|
||||
if (originalType.isNullable()) {
|
||||
enrichedTypes.add(TypeUtils.makeNotNullable(originalType));
|
||||
}
|
||||
for (JetType type: types) {
|
||||
if (type.isNullable()) {
|
||||
enrichedTypes.add(TypeUtils.makeNotNullable(type));
|
||||
@@ -78,21 +83,30 @@ public class DataFlowInfo {
|
||||
return enrichedTypes;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<JetType> getPossibleTypesForVariable(@NotNull VariableDescriptor variableDescriptor) {
|
||||
return getPossibleTypes(variableDescriptor, variableDescriptor.getOutType());
|
||||
}
|
||||
|
||||
public List<JetType> getPossibleTypesForReceiver(@NotNull ReceiverDescriptor receiver) {
|
||||
return getPossibleTypes(receiver, receiver.getType());
|
||||
}
|
||||
|
||||
public DataFlowInfo equalsToNull(@NotNull VariableDescriptor variableDescriptor, boolean notNull) {
|
||||
return new DataFlowInfo(getEqualsToNullMap(variableDescriptor, notNull), typeInfo);
|
||||
}
|
||||
|
||||
private ImmutableMap<VariableDescriptor, NullabilityFlags> getEqualsToNullMap(VariableDescriptor variableDescriptor, boolean notNull) {
|
||||
Map<VariableDescriptor, NullabilityFlags> builder = Maps.newHashMap(nullabilityInfo);
|
||||
private ImmutableMap<Object, NullabilityFlags> getEqualsToNullMap(VariableDescriptor variableDescriptor, boolean notNull) {
|
||||
Map<Object, NullabilityFlags> builder = Maps.newHashMap(nullabilityInfo);
|
||||
NullabilityFlags nullabilityFlags = nullabilityInfo.get(variableDescriptor);
|
||||
boolean varNotNull = notNull || (nullabilityFlags != null && !nullabilityFlags.canBeNull);
|
||||
builder.put(variableDescriptor, new NullabilityFlags(!varNotNull, varNotNull));
|
||||
return ImmutableMap.copyOf(builder);
|
||||
}
|
||||
|
||||
private ImmutableMap<VariableDescriptor, NullabilityFlags> getEqualsToNullMap(VariableDescriptor[] variableDescriptors, boolean notNull) {
|
||||
private ImmutableMap<Object, NullabilityFlags> getEqualsToNullMap(VariableDescriptor[] variableDescriptors, boolean notNull) {
|
||||
if (variableDescriptors.length == 0) return nullabilityInfo;
|
||||
Map<VariableDescriptor, NullabilityFlags> builder = Maps.newHashMap(nullabilityInfo);
|
||||
Map<Object, NullabilityFlags> builder = Maps.newHashMap(nullabilityInfo);
|
||||
for (VariableDescriptor variableDescriptor : variableDescriptors) {
|
||||
if (variableDescriptor != null) {
|
||||
NullabilityFlags nullabilityFlags = nullabilityInfo.get(variableDescriptor);
|
||||
@@ -104,14 +118,14 @@ public class DataFlowInfo {
|
||||
}
|
||||
|
||||
public DataFlowInfo isInstanceOf(@NotNull VariableDescriptor variableDescriptor, @NotNull JetType type) {
|
||||
ListMultimap<VariableDescriptor, JetType> newTypeInfo = copyTypeInfo();
|
||||
ListMultimap<Object, JetType> newTypeInfo = copyTypeInfo();
|
||||
newTypeInfo.put(variableDescriptor, type);
|
||||
return new DataFlowInfo(getEqualsToNullMap(variableDescriptor, !type.isNullable()), newTypeInfo);
|
||||
}
|
||||
|
||||
public DataFlowInfo isInstanceOf(@NotNull VariableDescriptor[] variableDescriptors, @NotNull JetType type) {
|
||||
if (variableDescriptors.length == 0) return this;
|
||||
ListMultimap<VariableDescriptor, JetType> newTypeInfo = copyTypeInfo();
|
||||
ListMultimap<Object, JetType> newTypeInfo = copyTypeInfo();
|
||||
for (VariableDescriptor variableDescriptor : variableDescriptors) {
|
||||
if (variableDescriptor != null) {
|
||||
newTypeInfo.put(variableDescriptor, type);
|
||||
@@ -121,59 +135,63 @@ public class DataFlowInfo {
|
||||
}
|
||||
|
||||
public DataFlowInfo and(DataFlowInfo other) {
|
||||
Map<VariableDescriptor, NullabilityFlags> nullabilityMapBuilder = Maps.newHashMap();
|
||||
Map<Object, NullabilityFlags> nullabilityMapBuilder = Maps.newHashMap();
|
||||
nullabilityMapBuilder.putAll(nullabilityInfo);
|
||||
for (Map.Entry<VariableDescriptor, NullabilityFlags> entry : other.nullabilityInfo.entrySet()) {
|
||||
VariableDescriptor variableDescriptor = entry.getKey();
|
||||
for (Map.Entry<Object, NullabilityFlags> entry : other.nullabilityInfo.entrySet()) {
|
||||
Object key = entry.getKey();
|
||||
NullabilityFlags otherFlags = entry.getValue();
|
||||
NullabilityFlags thisFlags = nullabilityInfo.get(variableDescriptor);
|
||||
NullabilityFlags thisFlags = nullabilityInfo.get(key);
|
||||
if (thisFlags != null) {
|
||||
nullabilityMapBuilder.put(variableDescriptor, thisFlags.and(otherFlags));
|
||||
nullabilityMapBuilder.put(key, thisFlags.and(otherFlags));
|
||||
}
|
||||
else {
|
||||
nullabilityMapBuilder.put(variableDescriptor, otherFlags);
|
||||
nullabilityMapBuilder.put(key, otherFlags);
|
||||
}
|
||||
}
|
||||
|
||||
ListMultimap<VariableDescriptor, JetType> newTypeInfo = copyTypeInfo();
|
||||
ListMultimap<Object, JetType> newTypeInfo = copyTypeInfo();
|
||||
newTypeInfo.putAll(other.typeInfo);
|
||||
return new DataFlowInfo(ImmutableMap.copyOf(nullabilityMapBuilder), newTypeInfo);
|
||||
}
|
||||
|
||||
private ListMultimap<VariableDescriptor, JetType> copyTypeInfo() {
|
||||
ListMultimap<VariableDescriptor, JetType> newTypeInfo = Multimaps.newListMultimap(Maps.<VariableDescriptor, Collection<JetType>>newHashMap(), CommonSuppliers.<JetType>getArrayListSupplier());
|
||||
private ListMultimap<Object, JetType> copyTypeInfo() {
|
||||
ListMultimap<Object, JetType> newTypeInfo = Multimaps.newListMultimap(Maps.<Object, Collection<JetType>>newHashMap(), CommonSuppliers.<JetType>getArrayListSupplier());
|
||||
newTypeInfo.putAll(typeInfo);
|
||||
return newTypeInfo;
|
||||
}
|
||||
|
||||
public DataFlowInfo or(DataFlowInfo other) {
|
||||
Map<VariableDescriptor, NullabilityFlags> builder = Maps.newHashMap(nullabilityInfo);
|
||||
Map<Object, NullabilityFlags> builder = Maps.newHashMap(nullabilityInfo);
|
||||
builder.keySet().retainAll(other.nullabilityInfo.keySet());
|
||||
for (Map.Entry<VariableDescriptor, NullabilityFlags> entry : builder.entrySet()) {
|
||||
VariableDescriptor variableDescriptor = entry.getKey();
|
||||
for (Map.Entry<Object, NullabilityFlags> entry : builder.entrySet()) {
|
||||
Object key = entry.getKey();
|
||||
NullabilityFlags thisFlags = entry.getValue();
|
||||
NullabilityFlags otherFlags = other.nullabilityInfo.get(variableDescriptor);
|
||||
NullabilityFlags otherFlags = other.nullabilityInfo.get(key);
|
||||
assert (otherFlags != null);
|
||||
builder.put(variableDescriptor, thisFlags.or(otherFlags));
|
||||
builder.put(key, thisFlags.or(otherFlags));
|
||||
}
|
||||
|
||||
ListMultimap<VariableDescriptor, JetType> newTypeInfo = Multimaps.newListMultimap(Maps.<VariableDescriptor, Collection<JetType>>newHashMap(), CommonSuppliers.<JetType>getArrayListSupplier());
|
||||
ListMultimap<Object, JetType> newTypeInfo = Multimaps.newListMultimap(Maps.<Object, Collection<JetType>>newHashMap(), CommonSuppliers.<JetType>getArrayListSupplier());
|
||||
|
||||
Set<VariableDescriptor> keys = newTypeInfo.keySet();
|
||||
Set<Object> keys = newTypeInfo.keySet();
|
||||
keys.retainAll(other.typeInfo.keySet());
|
||||
|
||||
for (VariableDescriptor variableDescriptor : keys) {
|
||||
Collection<JetType> thisTypes = typeInfo.get(variableDescriptor);
|
||||
Collection<JetType> otherTypes = other.typeInfo.get(variableDescriptor);
|
||||
for (Object key : keys) {
|
||||
Collection<JetType> thisTypes = typeInfo.get(key);
|
||||
Collection<JetType> otherTypes = other.typeInfo.get(key);
|
||||
|
||||
Collection<JetType> newTypes = Sets.newHashSet(thisTypes);
|
||||
newTypes.retainAll(otherTypes);
|
||||
|
||||
newTypeInfo.putAll(variableDescriptor, newTypes);
|
||||
newTypeInfo.putAll(key, newTypes);
|
||||
}
|
||||
|
||||
return new DataFlowInfo(ImmutableMap.copyOf(builder), newTypeInfo);
|
||||
}
|
||||
|
||||
public DataFlowInfo nullabilityOnly() {
|
||||
return new DataFlowInfo(nullabilityInfo, EMPTY.copyTypeInfo());
|
||||
}
|
||||
|
||||
private static class NullabilityFlags {
|
||||
private final boolean canBeNull;
|
||||
|
||||
@@ -105,6 +105,7 @@ public class ErrorUtils {
|
||||
Visibility.INTERNAL,
|
||||
true,
|
||||
null,
|
||||
ReceiverDescriptor.NO_RECEIVER,
|
||||
"<ERROR PROPERTY>",
|
||||
ERROR_PROPERTY_TYPE, ERROR_PROPERTY_TYPE);
|
||||
|
||||
@@ -112,6 +113,7 @@ public class ErrorUtils {
|
||||
FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(ERROR_CLASS, Collections.<AnnotationDescriptor>emptyList(), "<ERROR FUNCTION>");
|
||||
return functionDescriptor.initialize(
|
||||
null,
|
||||
ReceiverDescriptor.NO_RECEIVER,
|
||||
typeParameters,
|
||||
getValueParameters(functionDescriptor, positionedValueArgumentTypes),
|
||||
createErrorType("<ERROR FUNCTION RETURN>"),
|
||||
@@ -123,6 +125,7 @@ public class ErrorUtils {
|
||||
public static FunctionDescriptor createErrorFunction(int typeParameterCount, List<JetType> positionedValueParameterTypes) {
|
||||
return new FunctionDescriptorImpl(ERROR_CLASS, Collections.<AnnotationDescriptor>emptyList(), "<ERROR FUNCTION>").initialize(
|
||||
null,
|
||||
ReceiverDescriptor.NO_RECEIVER,
|
||||
Collections.<TypeParameterDescriptor>emptyList(), // TODO
|
||||
Collections.<ValueParameterDescriptor>emptyList(), // TODO
|
||||
createErrorType("<ERROR FUNCTION RETURN TYPE>"),
|
||||
|
||||
@@ -312,8 +312,7 @@ public class JetStandardLibrary {
|
||||
|
||||
@NotNull
|
||||
public JetType getArrayType(@NotNull JetType argument) {
|
||||
Variance variance = Variance.INVARIANT;
|
||||
return getArrayType(variance, argument);
|
||||
return getArrayType(Variance.INVARIANT, argument);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -136,6 +136,7 @@ public interface JetTokens {
|
||||
JetKeywordToken CATCH_KEYWORD = JetKeywordToken.softKeyword("catch");
|
||||
JetKeywordToken OUT_KEYWORD = JetKeywordToken.softKeyword("out");
|
||||
JetKeywordToken VARARG_KEYWORD = JetKeywordToken.softKeyword("vararg");
|
||||
JetKeywordToken INLINE_KEYWORD = JetKeywordToken.softKeyword("inline");
|
||||
|
||||
JetKeywordToken FINALLY_KEYWORD = JetKeywordToken.softKeyword("finally");
|
||||
JetKeywordToken FINAL_KEYWORD = JetKeywordToken.softKeyword("final");
|
||||
@@ -155,12 +156,12 @@ public interface JetTokens {
|
||||
TokenSet SOFT_KEYWORDS = TokenSet.create(IMPORT_KEYWORD, WHERE_KEYWORD, BY_KEYWORD, GET_KEYWORD,
|
||||
SET_KEYWORD, ABSTRACT_KEYWORD, ENUM_KEYWORD, OPEN_KEYWORD, ANNOTATION_KEYWORD,
|
||||
OVERRIDE_KEYWORD, PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD, PROTECTED_KEYWORD,
|
||||
CATCH_KEYWORD, FINALLY_KEYWORD, REF_KEYWORD, OUT_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD
|
||||
CATCH_KEYWORD, FINALLY_KEYWORD, REF_KEYWORD, OUT_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD, INLINE_KEYWORD
|
||||
);
|
||||
|
||||
TokenSet MODIFIER_KEYWORDS = TokenSet.create(ABSTRACT_KEYWORD, ENUM_KEYWORD,
|
||||
OPEN_KEYWORD, ANNOTATION_KEYWORD, OVERRIDE_KEYWORD, PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD,
|
||||
PROTECTED_KEYWORD, REF_KEYWORD, OUT_KEYWORD, IN_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD
|
||||
PROTECTED_KEYWORD, REF_KEYWORD, OUT_KEYWORD, IN_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD, INLINE_KEYWORD
|
||||
);
|
||||
TokenSet WHITE_SPACE_OR_COMMENT_BIT_SET = TokenSet.create(WHITE_SPACE, BLOCK_COMMENT, EOL_COMMENT, DOC_COMMENT);
|
||||
TokenSet WHITESPACES = TokenSet.create(TokenType.WHITE_SPACE);
|
||||
|
||||
@@ -186,7 +186,7 @@ public class DescriptorRenderer implements Renderer {
|
||||
renderModality(descriptor.getModality(), builder);
|
||||
String typeString = renderPropertyPrefixAndComputeTypeString(
|
||||
builder, descriptor.getTypeParameters(),
|
||||
descriptor.getReceiver(),
|
||||
descriptor.getReceiverParameter(),
|
||||
descriptor.getOutType(),
|
||||
descriptor.getInType());
|
||||
renderName(descriptor, builder);
|
||||
@@ -215,7 +215,7 @@ public class DescriptorRenderer implements Renderer {
|
||||
builder.append(renderKeyword("fun")).append(" ");
|
||||
renderTypeParameters(descriptor.getTypeParameters(), builder);
|
||||
|
||||
ReceiverDescriptor receiver = descriptor.getReceiver();
|
||||
ReceiverDescriptor receiver = descriptor.getReceiverParameter();
|
||||
if (receiver.exists()) {
|
||||
builder.append(escape(renderType(receiver.getType()))).append(".");
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -97,6 +97,15 @@ public class JetHighlighter extends SyntaxHighlighterBase {
|
||||
JET_AUTO_CAST_EXPRESSION = TextAttributesKey.createTextAttributesKey("JET.AUTO.CAST.EXPRESSION", clone);
|
||||
}
|
||||
|
||||
public static final TextAttributesKey JET_WRAPPED_INTO_REF;
|
||||
|
||||
static {
|
||||
TextAttributes attributes = new TextAttributes();
|
||||
attributes.setEffectType(EffectType.LINE_UNDERSCORE);
|
||||
attributes.setEffectColor(Color.BLACK);
|
||||
JET_WRAPPED_INTO_REF = TextAttributesKey.createTextAttributesKey("JET.WRAPPED.INTO.REF", attributes);
|
||||
}
|
||||
|
||||
public static final TextAttributesKey JET_AUTOCREATED_IT;
|
||||
|
||||
static {
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||
import org.jetbrains.jet.lang.diagnostics.UnresolvedReferenceDiagnostic;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.plugin.AnalyzerFacade;
|
||||
@@ -91,7 +92,7 @@ public class DebugInfoAnnotator implements Annotator {
|
||||
target = labelTarget.getText();
|
||||
}
|
||||
else {
|
||||
Collection<? extends DeclarationDescriptor> declarationDescriptors = bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, expression);
|
||||
Collection<? extends ResolvedCall<? extends DeclarationDescriptor>> declarationDescriptors = bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, expression);
|
||||
if (declarationDescriptors != null) {
|
||||
target = "[" + declarationDescriptors.size() + " descriptors]";
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.jetbrains.jet.plugin.annotations;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.annotation.Annotation;
|
||||
import com.intellij.lang.annotation.AnnotationHolder;
|
||||
import com.intellij.lang.annotation.Annotator;
|
||||
@@ -117,9 +118,28 @@ public class JetPsiChecker implements Annotator {
|
||||
holder.createInfoAnnotation(expression, "Automatically declared based on the expected type").setTextAttributes(JetHighlighter.JET_AUTOCREATED_IT);
|
||||
}
|
||||
}
|
||||
|
||||
markVariableAsWrappedIfNeeded(expression.getNode(), target);
|
||||
super.visitSimpleNameExpression(expression);
|
||||
}
|
||||
|
||||
private void markVariableAsWrappedIfNeeded(ASTNode node, DeclarationDescriptor target) {
|
||||
if (target instanceof VariableDescriptor) {
|
||||
VariableDescriptor variableDescriptor = (VariableDescriptor) target;
|
||||
if (bindingContext.get(MUST_BE_WRAPPED_IN_A_REF, variableDescriptor)) {
|
||||
holder.createInfoAnnotation(node, "Wrapped into a ref-object to be modifier when captured in a closure").setTextAttributes(JetHighlighter.JET_WRAPPED_INTO_REF);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitProperty(JetProperty property) {
|
||||
DeclarationDescriptor declarationDescriptor = bindingContext.get(DECLARATION_TO_DESCRIPTOR, property);
|
||||
markVariableAsWrappedIfNeeded(property.getNameIdentifier().getNode(), declarationDescriptor);
|
||||
super.visitProperty(property);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitExpression(JetExpression expression) {
|
||||
JetType autoCast = bindingContext.get(AUTOCAST, expression);
|
||||
|
||||
@@ -12,8 +12,8 @@ import org.jetbrains.jet.lang.psi.*;
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class AddFunctionBodyFix extends JetIntentionAction<JetFunctionOrPropertyAccessor> {
|
||||
public AddFunctionBodyFix(@NotNull JetFunctionOrPropertyAccessor element) {
|
||||
public class AddFunctionBodyFix extends JetIntentionAction<JetFunction> {
|
||||
public AddFunctionBodyFix(@NotNull JetFunction element) {
|
||||
super(element);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class AddFunctionBodyFix extends JetIntentionAction<JetFunctionOrProperty
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
JetFunctionOrPropertyAccessor newElement = (JetFunctionOrPropertyAccessor) element.copy();
|
||||
JetFunction newElement = (JetFunction) element.copy();
|
||||
JetExpression bodyExpression = newElement.getBodyExpression();
|
||||
if (!(newElement.getLastChild() instanceof PsiWhiteSpace)) {
|
||||
newElement.add(JetPsiFactory.createWhiteSpace(project));
|
||||
@@ -48,12 +48,12 @@ public class AddFunctionBodyFix extends JetIntentionAction<JetFunctionOrProperty
|
||||
element.replace(newElement);
|
||||
}
|
||||
|
||||
public static JetIntentionActionFactory<JetFunctionOrPropertyAccessor> createFactory() {
|
||||
return new JetIntentionActionFactory<JetFunctionOrPropertyAccessor>() {
|
||||
public static JetIntentionActionFactory<JetFunction> createFactory() {
|
||||
return new JetIntentionActionFactory<JetFunction>() {
|
||||
@Override
|
||||
public JetIntentionAction<JetFunctionOrPropertyAccessor> createAction(DiagnosticWithPsiElement diagnostic) {
|
||||
assert diagnostic.getPsiElement() instanceof JetFunctionOrPropertyAccessor;
|
||||
return new AddFunctionBodyFix((JetFunctionOrPropertyAccessor) diagnostic.getPsiElement());
|
||||
public JetIntentionAction<JetFunction> createAction(DiagnosticWithPsiElement diagnostic) {
|
||||
assert diagnostic.getPsiElement() instanceof JetFunction;
|
||||
return new AddFunctionBodyFix((JetFunction) diagnostic.getPsiElement());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,11 +4,13 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiNameIdentifierOwner;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
|
||||
import org.jetbrains.jet.lang.psi.JetModifierList;
|
||||
import org.jetbrains.jet.lang.psi.JetModifierListOwner;
|
||||
import org.jetbrains.jet.lang.psi.JetPropertyAccessor;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiFactory;
|
||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
||||
import org.jetbrains.jet.lexer.JetToken;
|
||||
@@ -17,19 +19,39 @@ import org.jetbrains.jet.lexer.JetTokens;
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class AddModifierFix extends ModifierFix {
|
||||
public class AddModifierFix extends JetIntentionAction<JetModifierListOwner> {
|
||||
private final JetKeywordToken modifier;
|
||||
private final JetToken[] modifiersThanCanBeReplaced;
|
||||
|
||||
private AddModifierFix(@NotNull JetModifierListOwner element, JetKeywordToken modifier, JetToken[] modifiersThanCanBeReplaced) {
|
||||
super(element, modifier);
|
||||
super(element);
|
||||
this.modifier = modifier;
|
||||
this.modifiersThanCanBeReplaced = modifiersThanCanBeReplaced;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
/*package*/ static String getElementName(JetModifierListOwner modifierListOwner) {
|
||||
String name = null;
|
||||
if (modifierListOwner instanceof PsiNameIdentifierOwner) {
|
||||
PsiElement nameIdentifier = ((PsiNameIdentifierOwner) modifierListOwner).getNameIdentifier();
|
||||
if (nameIdentifier != null) {
|
||||
name = nameIdentifier.getText();
|
||||
}
|
||||
}
|
||||
else if (modifierListOwner instanceof JetPropertyAccessor) {
|
||||
name = ((JetPropertyAccessor) modifierListOwner).getNamePlaceholder().getText();
|
||||
}
|
||||
if (name == null) {
|
||||
name = modifierListOwner.getText();
|
||||
}
|
||||
return "'" + name + "'";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
if (modifier == JetTokens.ABSTRACT_KEYWORD || modifier == JetTokens.OPEN_KEYWORD) {
|
||||
return "Make " + getElementName() + " " + modifier.getValue();
|
||||
return "Make " + getElementName(element) + " " + modifier.getValue();
|
||||
}
|
||||
return "Add '" + modifier.getValue() + "' modifier";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticParameters;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class AddReturnTypeFix extends JetIntentionAction<JetNamedDeclaration> {
|
||||
private JetType type;
|
||||
|
||||
public AddReturnTypeFix(@NotNull JetNamedDeclaration element, JetType type) {
|
||||
super(element);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Add return type declaration";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Add return type declaration";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
PsiElement newElement;
|
||||
if (element instanceof JetProperty) {
|
||||
newElement = addPropertyType(project, (JetProperty) element, type);
|
||||
}
|
||||
else {
|
||||
assert element instanceof JetFunction;
|
||||
newElement = addFunctionType(project, (JetFunction) element, type);
|
||||
}
|
||||
ImportClassHelper.perform(type, element, newElement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static JetProperty addPropertyType(Project project, JetProperty property, JetType type) {
|
||||
JetProperty newProperty = (JetProperty) property.copy();
|
||||
JetTypeReference typeReference = JetPsiFactory.createType(project, type.toString());
|
||||
Pair<PsiElement, PsiElement> colon = JetPsiFactory.createColon(project);
|
||||
PsiElement nameIdentifier = newProperty.getNameIdentifier();
|
||||
addTypeReference(newProperty, typeReference, colon, nameIdentifier);
|
||||
return newProperty;
|
||||
}
|
||||
|
||||
public static JetFunction addFunctionType(Project project, JetFunction function, JetType type) {
|
||||
JetFunction newFunction = (JetFunction) function.copy();
|
||||
JetTypeReference typeReference = JetPsiFactory.createType(project, type.toString());
|
||||
Pair<PsiElement, PsiElement> colon = JetPsiFactory.createColon(project);
|
||||
JetParameterList valueParameterList = newFunction.getValueParameterList();
|
||||
addTypeReference(newFunction, typeReference, colon, valueParameterList);
|
||||
return newFunction;
|
||||
}
|
||||
|
||||
private static void addTypeReference(JetNamedDeclaration element, JetTypeReference typeReference, Pair<PsiElement, PsiElement> colon, PsiElement anchor) {
|
||||
assert anchor != null;
|
||||
element.addAfter(typeReference, anchor);
|
||||
element.addRangeAfter(colon.getFirst(), colon.getSecond(), anchor);
|
||||
}
|
||||
|
||||
public static JetIntentionActionFactory<JetNamedDeclaration> createFactory() {
|
||||
return new JetIntentionActionFactory<JetNamedDeclaration>() {
|
||||
@Override
|
||||
public JetIntentionAction<JetNamedDeclaration> createAction(DiagnosticWithPsiElement diagnostic) {
|
||||
assert diagnostic.getPsiElement() instanceof JetNamedDeclaration;
|
||||
DiagnosticWithParameters<PsiElement> diagnosticWithParameters = assertAndCastToDiagnosticWithParameters(diagnostic, DiagnosticParameters.TYPE);
|
||||
JetType type = diagnosticWithParameters.getParameter(DiagnosticParameters.TYPE);
|
||||
return new AddReturnTypeFix((JetNamedDeclaration) diagnostic.getPsiElement(), type);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiNameIdentifierOwner;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.JetModifierListOwner;
|
||||
import org.jetbrains.jet.lang.psi.JetPropertyAccessor;
|
||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public abstract class ModifierFix extends JetIntentionAction<JetModifierListOwner> {
|
||||
protected final JetKeywordToken modifier;
|
||||
|
||||
protected ModifierFix(@NotNull JetModifierListOwner element, JetKeywordToken modifier) {
|
||||
super(element);
|
||||
this.modifier = modifier;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected String getElementName() {
|
||||
String name = null;
|
||||
if (element instanceof PsiNameIdentifierOwner) {
|
||||
PsiElement nameIdentifier = ((PsiNameIdentifierOwner) element).getNameIdentifier();
|
||||
if (nameIdentifier != null) {
|
||||
name = nameIdentifier.getText();
|
||||
}
|
||||
}
|
||||
else if (element instanceof JetPropertyAccessor) {
|
||||
name = ((JetPropertyAccessor) element).getNamePlaceholder().getText();
|
||||
}
|
||||
if (name == null) {
|
||||
name = element.getText();
|
||||
}
|
||||
return "'" + name + "'";
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.extapi.psi.ASTDelegatePsiElement;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticParameter;
|
||||
@@ -69,4 +71,12 @@ public class QuickFixUtil {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static boolean removePossiblyWhiteSpace(ASTDelegatePsiElement element, PsiElement possiblyWhiteSpace) {
|
||||
if (possiblyWhiteSpace instanceof PsiWhiteSpace) {
|
||||
element.deleteChildInternal(possiblyWhiteSpace.getNode());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ public class QuickFixes {
|
||||
}
|
||||
|
||||
static {
|
||||
JetIntentionActionFactory<JetModifierListOwner> removeAbstractModifierFactory = RemoveModifierFix.createFactory(JetTokens.ABSTRACT_KEYWORD);
|
||||
JetIntentionActionFactory<JetModifierListOwner> removeAbstractModifierFactory = RemoveModifierFix.createRemoveModifierFromListOwnerFactory(JetTokens.ABSTRACT_KEYWORD);
|
||||
JetIntentionActionFactory<JetModifierListOwner> addAbstractModifierFactory = AddModifierFix.createFactory(JetTokens.ABSTRACT_KEYWORD, new JetToken[]{JetTokens.OPEN_KEYWORD, JetTokens.FINAL_KEYWORD});
|
||||
|
||||
add(Errors.ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS, removeAbstractModifierFactory);
|
||||
@@ -53,22 +53,21 @@ public class QuickFixes {
|
||||
add(Errors.ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS, removeAbstractModifierFactory);
|
||||
add(Errors.ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS, addAbstractToClassFactory);
|
||||
|
||||
JetIntentionActionFactory<JetFunctionOrPropertyAccessor> removeFunctionBodyFactory = RemoveFunctionBodyFix.createFactory();
|
||||
JetIntentionActionFactory<JetFunction> removeFunctionBodyFactory = RemoveFunctionBodyFix.createFactory();
|
||||
add(Errors.ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS, removeAbstractModifierFactory);
|
||||
add(Errors.ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS, addAbstractToClassFactory);
|
||||
|
||||
add(Errors.ABSTRACT_FUNCTION_WITH_BODY, removeAbstractModifierFactory);
|
||||
add(Errors.ABSTRACT_FUNCTION_WITH_BODY, removeFunctionBodyFactory);
|
||||
|
||||
JetIntentionActionFactory<JetFunctionOrPropertyAccessor> addFunctionBodyFactory = AddFunctionBodyFix.createFactory();
|
||||
JetIntentionActionFactory<JetFunction> addFunctionBodyFactory = AddFunctionBodyFix.createFactory();
|
||||
add(Errors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY, addAbstractModifierFactory);
|
||||
add(Errors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY, addFunctionBodyFactory);
|
||||
|
||||
add(Errors.NON_MEMBER_ABSTRACT_FUNCTION, removeAbstractModifierFactory);
|
||||
add(Errors.NON_MEMBER_ABSTRACT_ACCESSOR, removeAbstractModifierFactory);
|
||||
add(Errors.NON_MEMBER_FUNCTION_NO_BODY, addFunctionBodyFactory);
|
||||
|
||||
add(Errors.NOTHING_TO_OVERRIDE, RemoveModifierFix.createFactory(JetTokens.OVERRIDE_KEYWORD));
|
||||
add(Errors.NOTHING_TO_OVERRIDE, RemoveModifierFix.createRemoveModifierFromListFactory(JetTokens.OVERRIDE_KEYWORD));
|
||||
add(Errors.VIRTUAL_MEMBER_HIDDEN, AddModifierFix.createFactory(JetTokens.OVERRIDE_KEYWORD, new JetToken[] {JetTokens.OPEN_KEYWORD}));
|
||||
|
||||
add(Errors.VAL_WITH_SETTER, ChangeVariableMutabilityFix.createFactory());
|
||||
@@ -84,10 +83,10 @@ public class QuickFixes {
|
||||
|
||||
add(Errors.UNNECESSARY_SAFE_CALL, ReplaceSafeCallToDotCall.createFactory());
|
||||
|
||||
JetIntentionActionFactory<JetModifierList> removeRedundantModifierFactory = RemoveRedundantModifierFix.createFactory();
|
||||
JetIntentionActionFactory<JetModifierList> removeRedundantModifierFactory = RemoveModifierFix.createRemoveModifierFromListFactory(true);
|
||||
add(Errors.REDUNDANT_MODIFIER, removeRedundantModifierFactory);
|
||||
add(Errors.REDUNDANT_MODIFIER_IN_TRAIT, removeRedundantModifierFactory);
|
||||
add(Errors.TRAIT_CAN_NOT_BE_FINAL, RemoveModifierFix.createFactory(JetTokens.FINAL_KEYWORD));
|
||||
add(Errors.TRAIT_CAN_NOT_BE_FINAL, RemoveModifierFix.createRemoveModifierFromListOwnerFactory(JetTokens.FINAL_KEYWORD));
|
||||
|
||||
add(Errors.PROPERTY_INITIALIZER_NO_PRIMARY_CONSTRUCTOR, RemovePartsFromPropertyFix.createRemoveInitializerFactory());
|
||||
|
||||
@@ -96,14 +95,15 @@ public class QuickFixes {
|
||||
add(Errors.PRIMARY_CONSTRUCTOR_MISSING_STATEFUL_PROPERTY, addPrimaryConstructorFactory);
|
||||
|
||||
JetIntentionActionFactory<JetModifierListOwner> addOpenModifierFactory = AddModifierFix.createFactory(JetTokens.OPEN_KEYWORD, new JetToken[]{JetTokens.FINAL_KEYWORD});
|
||||
JetIntentionActionFactory<JetModifierListOwner> removeOpenModifierFactory = RemoveModifierFix.createFactory(JetTokens.OPEN_KEYWORD);
|
||||
JetIntentionActionFactory<JetModifierListOwner> removeOpenModifierFactory = RemoveModifierFix.createRemoveModifierFromListOwnerFactory(JetTokens.OPEN_KEYWORD);
|
||||
add(Errors.NON_FINAL_MEMBER_IN_FINAL_CLASS, QuickFixUtil.createFactoryRedirectingAdditionalInfoToAnotherFactory(addOpenModifierFactory, DiagnosticParameters.CLASS));
|
||||
add(Errors.NON_FINAL_MEMBER_IN_FINAL_CLASS, removeOpenModifierFactory);
|
||||
add(Errors.NON_FINAL_ACCESSOR_OF_FINAL_PROPERTY, QuickFixUtil.createFactoryRedirectingAdditionalInfoToAnotherFactory(addOpenModifierFactory, DiagnosticParameters.PROPERTY));
|
||||
add(Errors.NON_FINAL_ACCESSOR_OF_FINAL_PROPERTY, removeOpenModifierFactory);
|
||||
|
||||
add(Errors.ABSTRACT_ACCESSOR_OF_NON_ABSTRACT_PROPERTY, QuickFixUtil.createFactoryRedirectingAdditionalInfoToAnotherFactory(addAbstractModifierFactory, DiagnosticParameters.PROPERTY));
|
||||
add(Errors.ABSTRACT_ACCESSOR_OF_NON_ABSTRACT_PROPERTY, removeAbstractModifierFactory);
|
||||
JetIntentionActionFactory<JetModifierList> removeModifierFactory = RemoveModifierFix.createRemoveModifierFromListFactory();
|
||||
add(Errors.GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY, removeModifierFactory);
|
||||
add(Errors.REDUNDANT_MODIFIER_IN_GETTER, removeRedundantModifierFactory);
|
||||
add(Errors.ILLEGAL_MODIFIER, removeModifierFactory);
|
||||
|
||||
add(Errors.PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE, AddReturnTypeFix.createFactory());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,18 +4,22 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetFunction;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class RemoveFunctionBodyFix extends JetIntentionAction<JetFunctionOrPropertyAccessor> {
|
||||
public class RemoveFunctionBodyFix extends JetIntentionAction<JetFunction> {
|
||||
|
||||
public RemoveFunctionBodyFix(@NotNull JetFunctionOrPropertyAccessor element) {
|
||||
public RemoveFunctionBodyFix(@NotNull JetFunction element) {
|
||||
super(element);
|
||||
}
|
||||
|
||||
@@ -39,25 +43,41 @@ public class RemoveFunctionBodyFix extends JetIntentionAction<JetFunctionOrPrope
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
JetFunctionOrPropertyAccessor newElement = (JetFunctionOrPropertyAccessor) element.copy();
|
||||
JetExpression bodyExpression = newElement.getBodyExpression();
|
||||
if (bodyExpression != null) {
|
||||
PsiElement prevSibling = bodyExpression.getPrevSibling();
|
||||
if (prevSibling instanceof PsiWhiteSpace) {
|
||||
((JetElement)newElement).deleteChildInternal(prevSibling.getNode());
|
||||
}
|
||||
((JetElement)newElement).deleteChildInternal(bodyExpression.getNode());
|
||||
JetFunction function = (JetFunction) element.copy();
|
||||
JetExpression bodyExpression = function.getBodyExpression();
|
||||
assert bodyExpression != null;
|
||||
if (function.hasBlockBody()) {
|
||||
PsiElement prevElement = bodyExpression.getPrevSibling();
|
||||
QuickFixUtil.removePossiblyWhiteSpace(function, prevElement);
|
||||
function.deleteChildInternal(bodyExpression.getNode());
|
||||
}
|
||||
element.replace(newElement);
|
||||
else {
|
||||
PsiElement prevElement = bodyExpression.getPrevSibling();
|
||||
PsiElement prevPrevElement = prevElement.getPrevSibling();
|
||||
QuickFixUtil.removePossiblyWhiteSpace(function, prevElement);
|
||||
removePossiblyEquationSign(function, prevElement);
|
||||
removePossiblyEquationSign(function, prevPrevElement);
|
||||
function.deleteChildInternal(bodyExpression.getNode());
|
||||
}
|
||||
element.replace(function);
|
||||
}
|
||||
|
||||
public static JetIntentionActionFactory<JetFunctionOrPropertyAccessor> createFactory() {
|
||||
return new JetIntentionActionFactory<JetFunctionOrPropertyAccessor>() {
|
||||
private static boolean removePossiblyEquationSign(@NotNull JetElement element, @Nullable PsiElement possiblyEq) {
|
||||
if (possiblyEq instanceof LeafPsiElement && ((LeafPsiElement)possiblyEq).getElementType() == JetTokens.EQ) {
|
||||
QuickFixUtil.removePossiblyWhiteSpace(element, possiblyEq.getNextSibling());
|
||||
element.deleteChildInternal(possiblyEq.getNode());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static JetIntentionActionFactory<JetFunction> createFactory() {
|
||||
return new JetIntentionActionFactory<JetFunction>() {
|
||||
@Override
|
||||
public JetIntentionAction<JetFunctionOrPropertyAccessor> createAction(DiagnosticWithPsiElement diagnostic) {
|
||||
assert diagnostic.getPsiElement() instanceof JetFunctionOrPropertyAccessor;
|
||||
return new RemoveFunctionBodyFix((JetFunctionOrPropertyAccessor) diagnostic.getPsiElement());
|
||||
public JetIntentionAction<JetFunction> createAction(DiagnosticWithPsiElement diagnostic) {
|
||||
assert diagnostic.getPsiElement() instanceof JetFunction;
|
||||
return new RemoveFunctionBodyFix((JetFunction) diagnostic.getPsiElement());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,15 @@
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.extapi.psi.ASTDelegatePsiElement;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticParameters;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
import org.jetbrains.jet.lang.psi.JetModifierList;
|
||||
@@ -20,35 +21,31 @@ import org.jetbrains.jet.lexer.JetTokens;
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class RemoveModifierFix extends ModifierFix {
|
||||
public class RemoveModifierFix {
|
||||
private final JetKeywordToken modifier;
|
||||
private final boolean isRedundant;
|
||||
|
||||
public RemoveModifierFix(@NotNull JetModifierListOwner element, JetKeywordToken modifier) {
|
||||
super(element, modifier);
|
||||
public RemoveModifierFix(JetKeywordToken modifier, boolean isRedundant) {
|
||||
this.modifier = modifier;
|
||||
this.isRedundant = isRedundant;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
if (modifier == JetTokens.ABSTRACT_KEYWORD || modifier == JetTokens.OPEN_KEYWORD) {
|
||||
return "Make " + getElementName() + " not " + modifier.getValue();
|
||||
private static String makeText(@Nullable JetModifierListOwner element, JetKeywordToken modifier, boolean isRedundant) {
|
||||
if (isRedundant) {
|
||||
return "Remove redundant '" + modifier.getValue() + "' modifier";
|
||||
}
|
||||
if (element != null && modifier == JetTokens.ABSTRACT_KEYWORD || modifier == JetTokens.OPEN_KEYWORD) {
|
||||
return "Make " + AddModifierFix.getElementName(element) + " not " + modifier.getValue();
|
||||
}
|
||||
return "Remove '" + modifier.getValue() + "' modifier";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Remove modifier";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
JetModifierListOwner newElement = (JetModifierListOwner) element.copy();
|
||||
element.replace(removeModifier(newElement, modifier));
|
||||
|
||||
private static String getFamilyName() {
|
||||
return "Remove modifier fix";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
/*package*/ static <T extends JetModifierListOwner> T removeModifier(T element, JetToken modifier) {
|
||||
private static <T extends JetModifierListOwner> T removeModifier(T element, JetToken modifier) {
|
||||
JetModifierList modifierList = element.getModifierList();
|
||||
assert modifierList != null;
|
||||
removeModifierFromList(modifierList, modifier);
|
||||
@@ -56,38 +53,128 @@ public class RemoveModifierFix extends ModifierFix {
|
||||
PsiElement whiteSpace = modifierList.getNextSibling();
|
||||
assert element instanceof JetElement;
|
||||
((JetElement) element).deleteChildInternal(modifierList.getNode());
|
||||
removeWhiteSpace((JetElement) element, whiteSpace);
|
||||
QuickFixUtil.removePossiblyWhiteSpace((JetElement) element, whiteSpace);
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
/*package*/ static JetModifierList removeModifierFromList(@NotNull JetModifierList modifierList, JetToken modifier) {
|
||||
@NotNull
|
||||
private static JetModifierList removeModifierFromList(@NotNull JetModifierList modifierList, JetToken modifier) {
|
||||
assert modifierList.hasModifier(modifier);
|
||||
ASTNode modifierNode = modifierList.getModifierNode(modifier);
|
||||
PsiElement whiteSpace = modifierNode.getPsi().getNextSibling();
|
||||
boolean wsRemoved = removeWhiteSpace(modifierList, whiteSpace);
|
||||
boolean wsRemoved = QuickFixUtil.removePossiblyWhiteSpace(modifierList, whiteSpace);
|
||||
modifierList.deleteChildInternal(modifierNode);
|
||||
if (!wsRemoved) {
|
||||
removeWhiteSpace(modifierList, modifierList.getLastChild());
|
||||
QuickFixUtil.removePossiblyWhiteSpace(modifierList, modifierList.getLastChild());
|
||||
}
|
||||
return modifierList;
|
||||
}
|
||||
|
||||
private static boolean removeWhiteSpace(ASTDelegatePsiElement element, PsiElement subElement) {
|
||||
if (subElement instanceof PsiWhiteSpace) {
|
||||
element.deleteChildInternal(subElement.getNode());
|
||||
return true;
|
||||
|
||||
private class RemoveModifierFromListOwner extends JetIntentionAction<JetModifierListOwner> {
|
||||
public RemoveModifierFromListOwner(@NotNull JetModifierListOwner element) {
|
||||
super(element);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return makeText(element, modifier, isRedundant);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return RemoveModifierFix.getFamilyName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
JetModifierListOwner newElement = (JetModifierListOwner) element.copy();
|
||||
element.replace(removeModifier(newElement, modifier));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static JetIntentionActionFactory<JetModifierListOwner> createFactory(final JetKeywordToken modifier) {
|
||||
private class RemoveModifierFromList extends JetIntentionAction<JetModifierList> {
|
||||
public RemoveModifierFromList(@NotNull JetModifierList element) {
|
||||
super(element);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return makeText(null, modifier, isRedundant);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return RemoveModifierFix.getFamilyName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
JetModifierList newElement = (JetModifierList) element.copy();
|
||||
element.replace(RemoveModifierFix.removeModifierFromList(newElement, modifier));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static JetIntentionActionFactory<JetModifierListOwner> createRemoveModifierFromListOwnerFactory(final JetKeywordToken modifier, final boolean isRedundant) {
|
||||
return new JetIntentionActionFactory<JetModifierListOwner>() {
|
||||
@Override
|
||||
public JetIntentionAction<JetModifierListOwner> createAction(DiagnosticWithPsiElement diagnostic) {
|
||||
assert diagnostic.getPsiElement() instanceof JetModifierListOwner;
|
||||
return new RemoveModifierFix((JetModifierListOwner) diagnostic.getPsiElement(), modifier);
|
||||
return new RemoveModifierFix(modifier, isRedundant).new RemoveModifierFromListOwner((JetModifierListOwner) diagnostic.getPsiElement());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static RemoveModifierFix createRemoveModifierFixFromDiagnostic(DiagnosticWithPsiElement diagnostic, boolean isRedundant) {
|
||||
DiagnosticWithParameters<PsiElement> diagnosticWithParameters = JetIntentionAction.assertAndCastToDiagnosticWithParameters(diagnostic, DiagnosticParameters.MODIFIER);
|
||||
JetKeywordToken modifier = diagnosticWithParameters.getParameter(DiagnosticParameters.MODIFIER);
|
||||
return new RemoveModifierFix(modifier, isRedundant);
|
||||
}
|
||||
|
||||
public static JetIntentionActionFactory<JetModifierListOwner> createRemoveModifierFromListOwnerFactory(final boolean isRedundant) {
|
||||
return new JetIntentionActionFactory<JetModifierListOwner>() {
|
||||
@Override
|
||||
public JetIntentionAction<JetModifierListOwner> createAction(DiagnosticWithPsiElement diagnostic) {
|
||||
assert diagnostic.getPsiElement() instanceof JetModifierListOwner;
|
||||
return createRemoveModifierFixFromDiagnostic(diagnostic, isRedundant).new RemoveModifierFromListOwner((JetModifierListOwner) diagnostic.getPsiElement());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static JetIntentionActionFactory<JetModifierList> createRemoveModifierFromListFactory(final boolean isRedundant) {
|
||||
return new JetIntentionActionFactory<JetModifierList>() {
|
||||
@Override
|
||||
public JetIntentionAction<JetModifierList> createAction(DiagnosticWithPsiElement diagnostic) {
|
||||
assert diagnostic.getPsiElement() instanceof JetModifierList;
|
||||
return createRemoveModifierFixFromDiagnostic(diagnostic, isRedundant).new RemoveModifierFromList((JetModifierList) diagnostic.getPsiElement());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static JetIntentionActionFactory<JetModifierList> createRemoveModifierFromListFactory(final JetKeywordToken modifier, final boolean isRedundant) {
|
||||
return new JetIntentionActionFactory<JetModifierList>() {
|
||||
@Override
|
||||
public JetIntentionAction<JetModifierList> createAction(DiagnosticWithPsiElement diagnostic) {
|
||||
assert diagnostic.getPsiElement() instanceof JetModifierList;
|
||||
return new RemoveModifierFix(modifier, isRedundant).new RemoveModifierFromList((JetModifierList) diagnostic.getPsiElement());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static JetIntentionActionFactory<JetModifierListOwner> createRemoveModifierFromListOwnerFactory(final JetKeywordToken modifier) {
|
||||
return createRemoveModifierFromListOwnerFactory(modifier, false);
|
||||
}
|
||||
|
||||
public static JetIntentionActionFactory<JetModifierList> createRemoveModifierFromListFactory() {
|
||||
return createRemoveModifierFromListFactory(false);
|
||||
}
|
||||
|
||||
public static JetIntentionActionFactory<JetModifierList> createRemoveModifierFromListFactory(final JetKeywordToken modifier) {
|
||||
return createRemoveModifierFromListFactory(modifier, false);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
@@ -97,7 +96,7 @@ public class RemovePartsFromPropertyFix extends JetIntentionAction<JetProperty>
|
||||
newElement.deleteChildRange(nextSibling, initializer);
|
||||
|
||||
if (newElement.getPropertyTypeRef() == null && type != null) {
|
||||
newElement = addPropertyType(project, newElement, type);
|
||||
newElement = AddReturnTypeFix.addPropertyType(project, newElement, type);
|
||||
needImport = true;
|
||||
}
|
||||
}
|
||||
@@ -108,17 +107,6 @@ public class RemovePartsFromPropertyFix extends JetIntentionAction<JetProperty>
|
||||
}
|
||||
}
|
||||
|
||||
public static JetProperty addPropertyType(Project project, JetProperty property, JetType type) {
|
||||
JetProperty newProperty = (JetProperty) property.copy();
|
||||
JetTypeReference typeReference = JetPsiFactory.createType(project, type.toString());
|
||||
Pair<PsiElement, PsiElement> colon = JetPsiFactory.createColon(project);
|
||||
PsiElement nameIdentifier = newProperty.getNameIdentifier();
|
||||
assert nameIdentifier != null;
|
||||
newProperty.addAfter(typeReference, nameIdentifier);
|
||||
newProperty.addRangeAfter(colon.getFirst(), colon.getSecond(), nameIdentifier);
|
||||
return newProperty;
|
||||
}
|
||||
|
||||
public static JetIntentionActionFactory<JetProperty> createFactory() {
|
||||
return new JetIntentionActionFactory<JetProperty>() {
|
||||
@Override
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticParameters;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
|
||||
import org.jetbrains.jet.lang.psi.JetModifierList;
|
||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class RemoveRedundantModifierFix extends JetIntentionAction<JetModifierList> {
|
||||
private JetKeywordToken redundantModifier;
|
||||
public RemoveRedundantModifierFix(@NotNull JetModifierList element, @NotNull JetKeywordToken redundantModifier) {
|
||||
super(element);
|
||||
this.redundantModifier = redundantModifier;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Remove redundant '" + redundantModifier + "' modifier";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Remove redundant modifier";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
JetModifierList newElement = (JetModifierList) element.copy();
|
||||
element.replace(RemoveModifierFix.removeModifierFromList(newElement, redundantModifier));
|
||||
}
|
||||
|
||||
public static JetIntentionActionFactory<JetModifierList> createFactory() {
|
||||
return new JetIntentionActionFactory<JetModifierList>() {
|
||||
@Override
|
||||
public JetIntentionAction<JetModifierList> createAction(DiagnosticWithPsiElement diagnostic) {
|
||||
assert diagnostic.getPsiElement() instanceof JetModifierList;
|
||||
DiagnosticWithParameters<PsiElement> diagnosticWithParameters = assertAndCastToDiagnosticWithParameters(diagnostic, DiagnosticParameters.MODIFIER);
|
||||
JetKeywordToken modifier = diagnosticWithParameters.getParameter(DiagnosticParameters.MODIFIER);
|
||||
return new RemoveRedundantModifierFix((JetModifierList) diagnostic.getPsiElement(), modifier);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||
import org.jetbrains.jet.plugin.AnalyzerFacade;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -80,7 +81,7 @@ public abstract class JetPsiReference implements PsiPolyVariantReference {
|
||||
if (psiElement != null) {
|
||||
return psiElement;
|
||||
}
|
||||
Collection<? extends DeclarationDescriptor> declarationDescriptors = bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, myExpression);
|
||||
Collection<? extends ResolvedCall<? extends DeclarationDescriptor>> declarationDescriptors = bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, myExpression);
|
||||
if (declarationDescriptors != null) return null;
|
||||
return file;
|
||||
}
|
||||
@@ -88,12 +89,12 @@ public abstract class JetPsiReference implements PsiPolyVariantReference {
|
||||
protected ResolveResult[] doMultiResolve() {
|
||||
JetFile file = (JetFile) getElement().getContainingFile();
|
||||
BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(file);
|
||||
Collection<? extends DeclarationDescriptor> declarationDescriptors = bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, myExpression);
|
||||
if (declarationDescriptors == null) return ResolveResult.EMPTY_ARRAY;
|
||||
ResolveResult[] results = new ResolveResult[declarationDescriptors.size()];
|
||||
Collection<? extends ResolvedCall<? extends DeclarationDescriptor>> resolvedCalls = bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, myExpression);
|
||||
if (resolvedCalls == null) return ResolveResult.EMPTY_ARRAY;
|
||||
ResolveResult[] results = new ResolveResult[resolvedCalls.size()];
|
||||
int i = 0;
|
||||
for (DeclarationDescriptor descriptor : declarationDescriptors) {
|
||||
PsiElement element = bindingContext.get(DESCRIPTOR_TO_DECLARATION, descriptor);
|
||||
for (ResolvedCall<? extends DeclarationDescriptor> resolvedCall : resolvedCalls) {
|
||||
PsiElement element = bindingContext.get(DESCRIPTOR_TO_DECLARATION, resolvedCall.getResultingDescriptor());
|
||||
if (element != null) {
|
||||
results[i] = new PsiElementResolveResult(element, true);
|
||||
i++;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user