diff --git a/compiler/frontend/src/jet/Library.jet b/compiler/frontend/src/jet/Library.jet index 580d1dd1a2b..6feeeb7d334 100644 --- a/compiler/frontend/src/jet/Library.jet +++ b/compiler/frontend/src/jet/Library.jet @@ -103,6 +103,38 @@ trait Iterable { fun iterator() : Iterator } +trait ByteIterable : Iterable { + override fun iterator() : ByteIterator +} + +trait ShortIterable : Iterable { + override fun iterator() : ShortIterator +} + +trait IntIterable : Iterable { + override fun iterator() : IntIterator +} + +trait LongIterable : Iterable { + override fun iterator() : LongIterator +} + +trait FloatIterable : Iterable { + override fun iterator() : FloatIterator +} + +trait DoubleIterable : Iterable { + override fun iterator() : DoubleIterator +} + +trait BooleanIterable : Iterable { + override fun iterator() : BooleanIterator +} + +trait CharIterable : Iterable { + override fun iterator() : CharIterator +} + fun Array(val size : Int) : Array class Array(val size : Int, init : fun(Int) : T) { @@ -230,7 +262,7 @@ trait Range> { fun contains(item : T) : Boolean } -class IntRange(val start : Int, size : Int, reversed : Boolean = false) : Range, Iterable { +class IntRange(val start : Int, size : Int, reversed : Boolean = false) : Range, IntIterable { fun iterator () : Iterator fun contains (elem: Int) : Boolean diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java index 4f3446cab05..a23ea8dece9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java @@ -556,10 +556,10 @@ public class JetFlowInformationProvider { JetDeclaration element = ((VariableDeclarationInstruction) instruction).getVariableDeclarationElement(); if (element instanceof JetNamedDeclaration) { PsiElement nameIdentifier = ((JetNamedDeclaration) element).getNameIdentifier(); - PsiElement elementToMark = nameIdentifier != null ? nameIdentifier : element; + if (nameIdentifier == null) return; if (variableStatus == null || variableStatus == VariableStatus.UNUSED) { if (element instanceof JetProperty) { - trace.report(Errors.UNUSED_VARIABLE.on((JetProperty) element, elementToMark, variableDescriptor)); + trace.report(Errors.UNUSED_VARIABLE.on((JetProperty) element, nameIdentifier, variableDescriptor)); } else if (element instanceof JetParameter) { PsiElement psiElement = element.getParent().getParent(); @@ -569,13 +569,13 @@ public class JetFlowInformationProvider { assert descriptor instanceof FunctionDescriptor; FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor; if (!isMain && !functionDescriptor.getModality().isOverridable() && functionDescriptor.getOverriddenDescriptors().isEmpty()) { - trace.report(Errors.UNUSED_PARAMETER.on((JetParameter) element, elementToMark, variableDescriptor)); + trace.report(Errors.UNUSED_PARAMETER.on((JetParameter) element, nameIdentifier, variableDescriptor)); } } } } else if (variableStatus == VariableStatus.ONLY_WRITTEN && element instanceof JetProperty) { - trace.report(Errors.ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE.on((JetNamedDeclaration) element, elementToMark, variableDescriptor)); + trace.report(Errors.ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE.on((JetNamedDeclaration) element, nameIdentifier, variableDescriptor)); } else if (variableStatus == VariableStatus.WRITTEN && element instanceof JetProperty) { JetExpression initializer = ((JetProperty) element).getInitializer(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java index 9254fcdc0de..94ea67e824e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java @@ -221,18 +221,17 @@ public class DeclarationsChecker { boolean backingFieldRequired = context.getTrace().getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor); PsiElement nameIdentifier = property.getNameIdentifier(); - ASTNode nameNode = nameIdentifier == null ? property.getNode() : nameIdentifier.getNode(); - if (inTrait && backingFieldRequired && hasAccessorImplementation) { - context.getTrace().report(BACKING_FIELD_IN_TRAIT.on(nameNode)); + if (inTrait && backingFieldRequired && hasAccessorImplementation && nameIdentifier != null) { + context.getTrace().report(BACKING_FIELD_IN_TRAIT.on(nameIdentifier)); } if (initializer == null) { - if (backingFieldRequired && !inTrait && !context.getTrace().getBindingContext().get(BindingContext.IS_INITIALIZED, propertyDescriptor)) { + if (nameIdentifier != null && backingFieldRequired && !inTrait && !context.getTrace().getBindingContext().get(BindingContext.IS_INITIALIZED, propertyDescriptor)) { if (classDescriptor == null || hasAccessorImplementation) { - context.getTrace().report(MUST_BE_INITIALIZED.on(nameNode)); + context.getTrace().report(MUST_BE_INITIALIZED.on(nameIdentifier)); } else { - context.getTrace().report(MUST_BE_INITIALIZED_OR_BE_ABSTRACT.on(property, nameNode)); + context.getTrace().report(MUST_BE_INITIALIZED_OR_BE_ABSTRACT.on(property, nameIdentifier)); } } return; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java index ccd0c4d9385..2c060f36b97 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java @@ -117,10 +117,10 @@ public class OverrideResolver { else if (klass instanceof JetObjectDeclaration) { nameIdentifier = ((JetObjectDeclaration) klass).getNameIdentifier(); } - PsiElement elementToMark = nameIdentifier != null ? nameIdentifier : klass; + if (nameIdentifier == null) return; for (CallableMemberDescriptor memberDescriptor : manyImpl) { - context.getTrace().report(MANY_IMPL_MEMBER_NOT_IMPLEMENTED.on(elementToMark, klass, memberDescriptor)); + context.getTrace().report(MANY_IMPL_MEMBER_NOT_IMPLEMENTED.on(nameIdentifier, klass, memberDescriptor)); break; } @@ -130,7 +130,7 @@ public class OverrideResolver { } for (CallableMemberDescriptor memberDescriptor : abstractNoImpl) { - context.getTrace().report(ABSTRACT_MEMBER_NOT_IMPLEMENTED.on(elementToMark, klass, memberDescriptor)); + context.getTrace().report(ABSTRACT_MEMBER_NOT_IMPLEMENTED.on(nameIdentifier, klass, memberDescriptor)); break; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index 18524d28943..466b318ed58 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -19,6 +19,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; import org.jetbrains.jet.lang.types.expressions.OperatorConventions; +import org.jetbrains.jet.lexer.JetToken; import org.jetbrains.jet.lexer.JetTokens; import java.util.*; @@ -344,7 +345,7 @@ public class CallResolver { if (callElement instanceof JetBinaryExpression) { JetBinaryExpression binaryExpression = (JetBinaryExpression) callElement; JetSimpleNameExpression operationReference = binaryExpression.getOperationReference(); - String operationString = operationReference.getReferencedNameElementType() == JetTokens.IDENTIFIER ? operationReference.getText() : OperatorConventions.getNameForOperationSymbol(operationReference.getReferencedNameElementType()); + String operationString = operationReference.getReferencedNameElementType() == JetTokens.IDENTIFIER ? operationReference.getText() : OperatorConventions.getNameForOperationSymbol((JetToken) operationReference.getReferencedNameElementType()); JetExpression right = binaryExpression.getRight(); if (right != null) { trace.report(UNSAFE_INFIX_CALL.on(reference, binaryExpression.getLeft().getText(), operationString, right.getText())); @@ -506,15 +507,6 @@ public class CallResolver { } else { tracing.typeInferenceFailed(temporaryTrace, solution.getStatus()); -// // Substitute DONT_CARE types to make further type checking as tolerant as possible -// D candidateWithDontCares = (D) candidate.substitute(TypeSubstitutor.makeConstantSubstitutor(candidate.getTypeParameters(), DONT_CARE)); -// if (candidateWithDontCares == null) { -// candidateWithDontCares = (D) candidate.substitute(TypeSubstitutor.makeConstantSubstitutor(candidate.getTypeParameters(), Variance.INVARIANT, DONT_CARE)); -// } -// if (!ErrorUtils.isErrorType(candidateWithDontCares.getReturnType())) { -// // Returning an error type provokes overload resolution ambiguities that mask errors -// candidateCall.setResultingDescriptor(candidateWithDontCares); -// } candidateCall.setStatus(OTHER_ERROR.combine(checkAllValueArguments(scope, tracing, task, candidateCall))); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/OperatorConventions.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/OperatorConventions.java index 570d75fb38b..2aea399ef4e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/OperatorConventions.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/OperatorConventions.java @@ -1,10 +1,11 @@ package org.jetbrains.jet.lang.types.expressions; +import com.google.common.collect.ImmutableBiMap; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; -import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lexer.JetToken; import org.jetbrains.jet.lexer.JetTokens; /** @@ -12,6 +13,10 @@ import org.jetbrains.jet.lexer.JetTokens; */ public class OperatorConventions { + public static final String EQUALS = "equals"; + public static final String COMPARE_TO = "compareTo"; + public static final String CONTAINS = "contains"; + private OperatorConventions() {} public static final ImmutableSet NUMBER_CONVERSIONS = ImmutableSet.of( @@ -23,7 +28,7 @@ public class OperatorConventions { "int" ); - public static final ImmutableMap UNARY_OPERATION_NAMES = ImmutableMap.builder() + public static final ImmutableBiMap UNARY_OPERATION_NAMES = ImmutableBiMap.builder() .put(JetTokens.PLUSPLUS, "inc") .put(JetTokens.MINUSMINUS, "dec") .put(JetTokens.PLUS, "plus") @@ -31,7 +36,7 @@ public class OperatorConventions { .put(JetTokens.EXCL, "not") .build(); - public static final ImmutableMap BINARY_OPERATION_NAMES = ImmutableMap.builder() + public static final ImmutableBiMap BINARY_OPERATION_NAMES = ImmutableBiMap.builder() .put(JetTokens.MUL, "times") .put(JetTokens.PLUS, "plus") .put(JetTokens.MINUS, "minus") @@ -41,11 +46,22 @@ public class OperatorConventions { .put(JetTokens.RANGE, "rangeTo") .build(); - public static final ImmutableSet COMPARISON_OPERATIONS = ImmutableSet.of(JetTokens.LT, JetTokens.GT, JetTokens.LTEQ, JetTokens.GTEQ); - public static final ImmutableSet EQUALS_OPERATIONS = ImmutableSet.of(JetTokens.EQEQ, JetTokens.EXCLEQ); + public static final ImmutableSet NOT_OVERLOADABLE = + ImmutableSet.of(JetTokens.ANDAND, JetTokens.OROR, JetTokens.ELVIS); + + public static final ImmutableSet INCREMENT_OPERATIONS = + ImmutableSet.of(JetTokens.PLUSPLUS, JetTokens.MINUSMINUS); - public static final ImmutableSet IN_OPERATIONS = ImmutableSet.of(JetTokens.IN_KEYWORD, JetTokens.NOT_IN); - public static final ImmutableMap ASSIGNMENT_OPERATIONS = ImmutableMap.builder() + public static final ImmutableSet COMPARISON_OPERATIONS = + ImmutableSet.of(JetTokens.LT, JetTokens.GT, JetTokens.LTEQ, JetTokens.GTEQ); + + public static final ImmutableSet EQUALS_OPERATIONS = + ImmutableSet.of(JetTokens.EQEQ, JetTokens.EXCLEQ); + + public static final ImmutableSet IN_OPERATIONS = + ImmutableSet.of(JetTokens.IN_KEYWORD, JetTokens.NOT_IN); + + public static final ImmutableBiMap ASSIGNMENT_OPERATIONS = ImmutableBiMap.builder() .put(JetTokens.MULTEQ, "timesAssign") .put(JetTokens.DIVEQ, "divAssign") .put(JetTokens.PERCEQ, "modAssign") @@ -53,7 +69,7 @@ public class OperatorConventions { .put(JetTokens.MINUSEQ, "minusAssign") .build(); - public static final ImmutableMap ASSIGNMENT_OPERATION_COUNTERPARTS = ImmutableMap.builder() + public static final ImmutableMap ASSIGNMENT_OPERATION_COUNTERPARTS = ImmutableMap.builder() .put(JetTokens.MULTEQ, JetTokens.MUL) .put(JetTokens.DIVEQ, JetTokens.DIV) .put(JetTokens.PERCEQ, JetTokens.PERC) @@ -62,17 +78,16 @@ public class OperatorConventions { .build(); @Nullable - public static String getNameForOperationSymbol(@NotNull IElementType token) { + public static String getNameForOperationSymbol(@NotNull JetToken token) { String name = UNARY_OPERATION_NAMES.get(token); if (name != null) return name; name = BINARY_OPERATION_NAMES.get(token); if (name != null) return name; name = ASSIGNMENT_OPERATIONS.get(token); if (name != null) return name; - if (COMPARISON_OPERATIONS.contains(token)) return "compareTo"; - if (EQUALS_OPERATIONS.contains(token)) return "equals"; - if (IN_OPERATIONS.contains(token)) return "contains"; + if (COMPARISON_OPERATIONS.contains(token)) return COMPARE_TO; + if (EQUALS_OPERATIONS.contains(token)) return EQUALS; + if (IN_OPERATIONS.contains(token)) return CONTAINS; return null; - } - + } } diff --git a/compiler/testData/codegen/regressions/kt511.jet b/compiler/testData/codegen/regressions/kt511.jet new file mode 100644 index 00000000000..a9bc915346c --- /dev/null +++ b/compiler/testData/codegen/regressions/kt511.jet @@ -0,0 +1,16 @@ +namespace one_extends_base + +open class Base(name : T?) { + var myName : T? + { + $myName = name + } +} +open class One(name : T?, second : K?) : Base(name) { + var mySecond : K? + { + $mySecond = second + } +} + +fun box() = if(One("ola", 0).myName == "ola") "OK" else "fail" diff --git a/compiler/testData/codegen/regressions/kt779.jet b/compiler/testData/codegen/regressions/kt779.jet new file mode 100644 index 00000000000..12aa290eb67 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt779.jet @@ -0,0 +1,3 @@ +val Array.length : Int get() = this.size + +fun box() = if(Array(10, {1}).length == 10) "OK" else "fail" \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt843.jet b/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt843.jet new file mode 100644 index 00000000000..3e276fe45d3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt843.jet @@ -0,0 +1,8 @@ +//KT-843 Don't highlight incomplete variables as unused + +namespace kt843 + +fun main(args : Array) { + // Integer type + val // this word is grey, which looks strange +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java index 5de65ac38f6..f14c34e279d 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java @@ -12,6 +12,11 @@ public class ArrayGenTest extends CodegenTestCase { // System.out.println(generateToText()); } + public void testKt779 () throws Exception { + blackBoxFile("regressions/kt779.jet"); +// System.out.println(generateToText()); + } + public void testCreateMultiInt () throws Exception { loadText("fun foo() = Array> (5, { Array(it, {239}) })"); Method foo = generateFunction(); diff --git a/compiler/tests/org/jetbrains/jet/codegen/TypeInfoTest.java b/compiler/tests/org/jetbrains/jet/codegen/TypeInfoTest.java index b2396c96af6..3949cf9b8c6 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/TypeInfoTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/TypeInfoTest.java @@ -138,6 +138,11 @@ public class TypeInfoTest extends CodegenTestCase { // System.out.println(generateToText()); } + public void testKt511() throws Exception { + blackBoxFile("regressions/kt511.jet"); +// System.out.println(generateToText()); + } + public void testInner() throws Exception { blackBoxFile("typeInfo/inner.jet"); System.out.println(generateToText()); diff --git a/stdlib/src/jet/BooleanIterable.java b/stdlib/src/jet/BooleanIterable.java new file mode 100644 index 00000000000..76d59748d65 --- /dev/null +++ b/stdlib/src/jet/BooleanIterable.java @@ -0,0 +1,9 @@ +package jet; + +/** + * @author alex.tkachman + */ +public interface BooleanIterable extends Iterable { + @Override + BooleanIterator iterator(); +} diff --git a/stdlib/src/jet/ByteIterable.java b/stdlib/src/jet/ByteIterable.java new file mode 100644 index 00000000000..36e773da574 --- /dev/null +++ b/stdlib/src/jet/ByteIterable.java @@ -0,0 +1,9 @@ +package jet; + +/** + * @author alex.tkachman + */ +public interface ByteIterable extends Iterable { + @Override + ByteIterator iterator(); +} diff --git a/stdlib/src/jet/CharIterable.java b/stdlib/src/jet/CharIterable.java new file mode 100644 index 00000000000..d8646e449f3 --- /dev/null +++ b/stdlib/src/jet/CharIterable.java @@ -0,0 +1,9 @@ +package jet; + +/** + * @author alex.tkachman + */ +public interface CharIterable extends Iterable { + @Override + CharIterator iterator(); +} diff --git a/stdlib/src/jet/DoubleIterable.java b/stdlib/src/jet/DoubleIterable.java new file mode 100644 index 00000000000..ac6336039a2 --- /dev/null +++ b/stdlib/src/jet/DoubleIterable.java @@ -0,0 +1,9 @@ +package jet; + +/** + * @author alex.tkachman + */ +public interface DoubleIterable extends Iterable { + @Override + DoubleIterator iterator(); +} diff --git a/stdlib/src/jet/FloatIterable.java b/stdlib/src/jet/FloatIterable.java new file mode 100644 index 00000000000..5bbd25f3dd9 --- /dev/null +++ b/stdlib/src/jet/FloatIterable.java @@ -0,0 +1,9 @@ +package jet; + +/** + * @author alex.tkachman + */ +public interface FloatIterable extends Iterable { + @Override + FloatIterator iterator(); +} diff --git a/stdlib/src/jet/IntIterable.java b/stdlib/src/jet/IntIterable.java new file mode 100644 index 00000000000..0963ba1f099 --- /dev/null +++ b/stdlib/src/jet/IntIterable.java @@ -0,0 +1,9 @@ +package jet; + +/** + * @author alex.tkachman + */ +public interface IntIterable extends Iterable { + @Override + IntIterator iterator(); +} diff --git a/stdlib/src/jet/IntRange.java b/stdlib/src/jet/IntRange.java index 13811dbba40..7866919f9fe 100644 --- a/stdlib/src/jet/IntRange.java +++ b/stdlib/src/jet/IntRange.java @@ -2,7 +2,7 @@ package jet; import jet.typeinfo.TypeInfo; -public final class IntRange implements Range, Iterable, JetObject { +public final class IntRange implements Range, IntIterable, JetObject { private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(IntRange.class, false); private final int start; @@ -39,7 +39,7 @@ public final class IntRange implements Range, Iterable, JetObj } @Override - public Iterator iterator() { + public IntIterator iterator() { return new MyIterator(start, count); } @@ -66,7 +66,7 @@ public final class IntRange implements Range, Iterable, JetObj } } - private static class MyIterator implements Iterator { + private static class MyIterator extends IntIterator { private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false); private int cur; @@ -86,7 +86,7 @@ public final class IntRange implements Range, Iterable, JetObj } @Override - public Integer next() { + public int nextInt() { count--; if(reversed) { return cur--; diff --git a/stdlib/src/jet/LongIterable.java b/stdlib/src/jet/LongIterable.java new file mode 100644 index 00000000000..79567c0604b --- /dev/null +++ b/stdlib/src/jet/LongIterable.java @@ -0,0 +1,9 @@ +package jet; + +/** + * @author alex.tkachman + */ +public interface LongIterable extends Iterable { + @Override + LongIterator iterator(); +} diff --git a/stdlib/src/jet/LongRange.java b/stdlib/src/jet/LongRange.java index ed94c76cb31..dea5c70402e 100644 --- a/stdlib/src/jet/LongRange.java +++ b/stdlib/src/jet/LongRange.java @@ -2,7 +2,7 @@ package jet; import jet.typeinfo.TypeInfo; -public final class LongRange implements Range, Iterable, JetObject { +public final class LongRange implements Range, LongIterable, JetObject { private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(IntRange.class, false); private final long start; @@ -39,7 +39,7 @@ public final class LongRange implements Range, Iterable, JetObject { } @Override - public Iterator iterator() { + public LongIterator iterator() { return new MyIterator(start, count); } @@ -66,7 +66,7 @@ public final class LongRange implements Range, Iterable, JetObject { } } - private static class MyIterator implements Iterator { + private static class MyIterator extends LongIterator { private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false); private long cur; @@ -86,7 +86,7 @@ public final class LongRange implements Range, Iterable, JetObject { } @Override - public Long next() { + public long nextLong() { count--; if(reversed) { return cur--; diff --git a/stdlib/src/jet/ShortIterable.java b/stdlib/src/jet/ShortIterable.java new file mode 100644 index 00000000000..9da1721794b --- /dev/null +++ b/stdlib/src/jet/ShortIterable.java @@ -0,0 +1,9 @@ +package jet; + +/** + * @author alex.tkachman + */ +public interface ShortIterable extends Iterable { + @Override + ShortIterator iterator(); +}