From be0165f1e5995381f30171803fa7183a1e09c093 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 14 Dec 2011 13:12:36 +0400 Subject: [PATCH 01/33] Constraint priorities integrated --- .../jet/lang/resolve/calls/CallResolver.java | 19 +- .../resolve/calls/ResolutionDebugInfo.java | 13 +- .../lang/resolve/calls/ResolutionTask.java | 2 +- .../ConstraintSystemWithPriorities.java | 167 +++++++++++++----- .../DebugConstraintResolutionListener.java | 26 +-- .../calls/inference/SubtypingConstraint.java | 5 + .../resolve/calls/inference/TypeValue.java | 11 ++ .../jet/lang/types/TypeSubstitutor.java | 2 +- .../tests/FunctionCalleeExpressions.jet | 2 +- .../tests/ResolveOfJavaGenerics.jet | 3 +- .../diagnostics/tests/ResolveToJava.jet | 2 +- .../NoInferenceFromDeclaredBounds.jet | 9 + .../diagnostics/tests/regressions/kt353.jet | 8 +- .../org/jetbrains/jet/runtime/JetNpeTest.java | 2 +- .../resolvewindow/ResolveToolwindow.java | 62 ++++--- idea/testData/checker/ResolveToJava.jet | 2 +- 16 files changed, 237 insertions(+), 98 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/inference/NoInferenceFromDeclaredBounds.jet 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 b5d04a21d8e..176524e2c9a 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 @@ -101,7 +101,7 @@ public class CallResolver { } @Nullable - public FunctionDescriptor resolveSimpleCallToFunctionDescriptor( + private FunctionDescriptor resolveSimpleCallToFunctionDescriptor( @NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull final Call call, @@ -439,7 +439,7 @@ public class CallResolver { ResolutionDebugInfo.Data debugInfo = trace.get(ResolutionDebugInfo.RESOLUTION_DEBUG_INFO, task.getCall().getCallElement()); - ConstraintSystem constraintSystem = new ConstraintSystemImpl(new DebugConstraintResolutionListener(debugInfo)); + ConstraintSystem constraintSystem = new ConstraintSystemWithPriorities(new DebugConstraintResolutionListener(candidateCall, debugInfo)); // If the call is recursive, e.g. // fun foo(t : T) : T = foo(t) @@ -472,7 +472,7 @@ public class CallResolver { TemporaryBindingTrace traceForUnknown = TemporaryBindingTrace.create(temporaryTrace); ExpressionTypingServices temporaryServices = new ExpressionTypingServices(semanticServices, traceForUnknown); JetType type = temporaryServices.getType(scope, expression, substituteDontCare.substitute(valueParameterDescriptor.getOutType(), Variance.INVARIANT)); - if (type != null) { + if (type != null && !ErrorUtils.isErrorType(type)) { constraintSystem.addSubtypingConstraint(VALUE_ARGUMENT.assertSubtyping(type, effectiveExpectedType)); } else { @@ -513,7 +513,16 @@ public class CallResolver { } else { tracing.typeInferenceFailed(temporaryTrace, solution.getStatus()); - candidateCall.setStatus(checkAllValueArguments(scope, tracing, task, candidateCall)); +// // 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))); } } else { @@ -699,7 +708,7 @@ public class CallResolver { for (JetExpression argumentExpression : argumentExpressions) { ExpressionTypingServices temporaryServices = new ExpressionTypingServices(semanticServices, candidateCall.getTrace()); JetType type = temporaryServices.getType(scope, argumentExpression, parameterType, dataFlowInfo); - if (type == null) { + if (type == null || ErrorUtils.isErrorType(type)) { candidateCall.argumentHasNoType(); } else if (!semanticServices.getTypeChecker().isSubtypeOf(type, parameterType)) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionDebugInfo.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionDebugInfo.java index d254ac771e4..91d2e14013b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionDebugInfo.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionDebugInfo.java @@ -20,12 +20,13 @@ import java.util.Map; public class ResolutionDebugInfo { public static final WritableSlice>> TASKS = Slices.createSimpleSlice(); public static final WritableSlice> RESULT = Slices.createSimpleSlice(); - public static final WritableSlice ERRORS = Slices.createSimpleSlice(); - public static final WritableSlice LOG = Slices.createSimpleSlice(); - public static final WritableSlice> BOUNDS_FOR_UNKNOWNS = Slices.createSimpleSlice(); - public static final WritableSlice> BOUNDS_FOR_KNOWNS = Slices.createSimpleSlice(); - public static final WritableSlice SOLUTION = Slices.createSimpleSlice(); - public static final WritableSlice> UNKNOWNS = Slices.createSimpleSlice(); + + public static final WritableSlice, StringBuilder> ERRORS = Slices.createSimpleSlice(); + public static final WritableSlice, StringBuilder> LOG = Slices.createSimpleSlice(); + public static final WritableSlice, Map> BOUNDS_FOR_UNKNOWNS = Slices.createSimpleSlice(); + public static final WritableSlice, Map> BOUNDS_FOR_KNOWNS = Slices.createSimpleSlice(); + public static final WritableSlice, ConstraintSystemSolution> SOLUTION = Slices.createSimpleSlice(); + public static final WritableSlice, Collection> UNKNOWNS = Slices.createSimpleSlice(); static { BasicWritableSlice.initSliceDebugNames(ResolutionDebugInfo.class); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionTask.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionTask.java index dc2f978517c..7057b8d556a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionTask.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionTask.java @@ -13,7 +13,7 @@ import java.util.Collection; * * @author abreslav */ -/*package*/ class ResolutionTask { +public class ResolutionTask { private final Call call; private final Collection> candidates; private final DataFlowInfo dataFlowInfo; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemWithPriorities.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemWithPriorities.java index fd408957971..3da752a9950 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemWithPriorities.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemWithPriorities.java @@ -10,7 +10,10 @@ import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.checker.TypeCheckingProcedure; import org.jetbrains.jet.lang.types.checker.TypingConstraints; -import java.util.*; +import java.util.Comparator; +import java.util.Map; +import java.util.PriorityQueue; +import java.util.Set; import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintType.PARAMETER_BOUND; @@ -200,7 +203,7 @@ public class ConstraintSystemWithPriorities implements ConstraintSystem { else { // One unknown and one known if (upper.isKnown()) { - if (TypeUtils.canHaveSubtypes(typeChecker, upper.getType())) { + if (!TypeUtils.canHaveSubtypes(typeChecker, upper.getType())) { // Upper bound is final -> we have to equate the lower bounds to it return expandEqualityConstraint(lower, upper); } @@ -225,17 +228,8 @@ public class ConstraintSystemWithPriorities implements ConstraintSystem { Solution solution = new Solution(); // At this point we only have type values, no bounds added for them, no values computed for unknown types - // Generate low-priority constraints from bounds - for (Map.Entry entry : Sets.newHashSet(unknownTypes.entrySet())) { - TypeParameterDescriptor typeParameterDescriptor = entry.getKey(); - TypeValue typeValue = entry.getValue(); - for (JetType upperBound : typeParameterDescriptor.getUpperBounds()) { - addSubtypingConstraint(PARAMETER_BOUND.assertSubtyping(typeValue.getOriginalType(), getTypeValueFor(upperBound).getOriginalType())); - } - for (JetType lowerBound : typeParameterDescriptor.getLowerBounds()) { - addSubtypingConstraint(PARAMETER_BOUND.assertSubtyping(getTypeValueFor(lowerBound).getOriginalType(), typeValue.getOriginalType())); - } - } + // After the parameters are inferred we will make sure the initial constraints are satisfied + PriorityQueue constraintsToEnsureAfterInference = new PriorityQueue(constraintQueue); // Expand and solve constraints while (!constraintQueue.isEmpty()) { @@ -247,7 +241,7 @@ public class ConstraintSystemWithPriorities implements ConstraintSystem { boolean success = expandSubtypingConstraint(lower, upper); if (!success) { solution.registerError(constraint.getErrorMessage()); - break; +// break; } // (???) Propagate info @@ -256,25 +250,6 @@ public class ConstraintSystemWithPriorities implements ConstraintSystem { if (unsolvedUnknowns.isEmpty()) break; } - // Now, let's check the rest of the constraints - - // Expand custom bounds, e.g. List <: List -// for (Map.Entry entry : Sets.newHashSet(knownTypes.entrySet())) { -// JetType jetType = entry.getKey(); -// TypeValue typeValue = entry.getValue(); -// -// for (TypeValue upperBound : typeValue.getUpperBounds()) { -// if (upperBound.isKnown()) { -// boolean ok = constraintExpander.isSubtypeOf(jetType, upperBound.getType()); -// if (!ok) { -// listener.error("Error while expanding '" + jetType + " :< " + upperBound.getType() + "'"); -// return new Solution().registerError("Mismatch while expanding constraints"); -// } -// } -// } -// -// // Lower bounds. Probably not needed for known types, as everything is symmetrical anyway -// } // effective bounds for each node // Set visited = Sets.newHashSet(); @@ -282,6 +257,16 @@ public class ConstraintSystemWithPriorities implements ConstraintSystem { // transitiveClosure(unknownType, visited); // } + assert constraintQueue.isEmpty() || unsolvedUnknowns.isEmpty() : constraintQueue + " " + unsolvedUnknowns; + + for (TypeValue unknown : unsolvedUnknowns) { + if (!computeValueFor(unknown)) { + listener.error("Not enough data to compute value for ", unknown); + solution.registerError("Not enough data to compute value for " + unknown + ". Please, specify type arguments explicitly"); + } + } + + // Logging for (TypeValue unknownType : unknownTypes.values()) { listener.constraintsForUnknown(unknownType.getTypeParameterDescriptor(), unknownType); } @@ -289,23 +274,117 @@ public class ConstraintSystemWithPriorities implements ConstraintSystem { listener.constraintsForKnownType(knownType.getType(), knownType); } + // Now, let's check the rest of the constraints and re-check the initial ones + + // Add constraints for the declared bounds for parameters + // Maybe these bounds could reconcile some resolution earlier? Then, move them up + for (Map.Entry entry : Sets.newHashSet(unknownTypes.entrySet())) { + TypeParameterDescriptor typeParameterDescriptor = entry.getKey(); + TypeValue unknown = entry.getValue(); + for (JetType upperBound : typeParameterDescriptor.getUpperBounds()) { + constraintsToEnsureAfterInference.add(PARAMETER_BOUND.assertSubtyping(unknown.getOriginalType(), getTypeValueFor(upperBound).getOriginalType())); +// unknown.addUpperBound(new TypeValue(upperBound)); + } + for (JetType lowerBound : typeParameterDescriptor.getLowerBounds()) { + constraintsToEnsureAfterInference.add(PARAMETER_BOUND.assertSubtyping(getTypeValueFor(lowerBound).getOriginalType(), unknown.getOriginalType())); +// unknown.addLowerBound(new TypeValue(lowerBound)); + } + } + + // Find inconsistencies - // Compute values and check that all bounds are respected by solutions: + // Check that all bounds are respected by solutions: // we have set some of them from equality constraints with known types // and thus the bounds may be violated if some of the constraints conflict - for (TypeValue unknownType : unknownTypes.values()) { - check(unknownType, solution); - } - for (TypeValue knownType : knownTypes.values()) { - check(knownType, solution); + + + for (SubtypingConstraint constraint : constraintsToEnsureAfterInference) { + JetType substitutedSubtype = solution.getSubstitutor().substitute(constraint.getSubtype(), Variance.INVARIANT); // TODO + if (substitutedSubtype == null) continue; + JetType substitutedSupertype = solution.getSubstitutor().substitute(constraint.getSupertype(), Variance.INVARIANT); // TODO + if (substitutedSupertype == null) continue; + + if (!typeChecker.isSubtypeOf(substitutedSubtype, substitutedSupertype)) { + solution.registerError(constraint.getErrorMessage()); + listener.error("Constraint violation: ", substitutedSubtype, " :< ", substitutedSupertype, " message: ", constraint.getErrorMessage()); + } } + +// for (TypeValue unknownType : unknownTypes.values()) { +// check(unknownType, solution); +// } +// +// for (TypeValue knownType : knownTypes.values()) { +// check(knownType, solution); +// } + + listener.done(solution, unknownTypes.keySet()); return solution; } + private final Set beingComputed = Sets.newHashSet(); + + public boolean computeValueFor(TypeValue unknown) { + assert !unknown.isKnown(); + if (beingComputed.contains(unknown)) { + throw new LoopInTypeVariableConstraintsException(); + } + if (!unknown.hasValue()) { + beingComputed.add(unknown); + try { + if (unknown.getPositionVariance() == Variance.IN_VARIANCE) { + // maximal solution + throw new UnsupportedOperationException(); + } + else { + // minimal solution + + Set lowerBounds = unknown.getLowerBounds(); + Set upperBounds = unknown.getUpperBounds(); + if (!lowerBounds.isEmpty()) { + Set types = getTypes(lowerBounds); + + JetType commonSupertype = CommonSupertypes.commonSupertype(types); + for (TypeValue upperBound : upperBounds) { + if (!typeChecker.isSubtypeOf(commonSupertype, upperBound.getType())) { + return false; + } + } + + listener.log("minimal solution from lower bounds for ", this, " is ", commonSupertype); + assignValueTo(unknown, commonSupertype); + } + else if (!upperBounds.isEmpty()) { + Set types = getTypes(upperBounds); + JetType intersect = TypeUtils.intersect(typeChecker, types); + + if (intersect == null) return false; + + assignValueTo(unknown, intersect); + } + else { + return false; // No bounds to compute the value from + } + } + } finally { + beingComputed.remove(unknown); + } + } + return true; + } + + private static Set getTypes(Set lowerBounds) { + Set types = Sets.newHashSet(); + for (TypeValue lowerBound : lowerBounds) { + types.add(lowerBound.getType()); + } + return types; + } + private void transitiveClosure(TypeValue current, Set visited) { if (!visited.add(current)) { return; @@ -324,6 +403,7 @@ public class ConstraintSystemWithPriorities implements ConstraintSystem { } private void check(TypeValue typeValue, Solution solution) { + if (!typeValue.hasValue()) return; try { JetType resultingType = typeValue.getType(); JetType type = solution.getSubstitutor().substitute(resultingType, Variance.INVARIANT); // TODO @@ -377,7 +457,11 @@ public class ConstraintSystemWithPriorities implements ConstraintSystem { if (!unknownTypes.containsKey(descriptor)) return null; - TypeProjection typeProjection = new TypeProjection(getValue(descriptor)); + JetType value = getValue(descriptor); + if (value == null) { + return null; + } + TypeProjection typeProjection = new TypeProjection(value); listener.log(descriptor, " |-> ", typeProjection); @@ -411,7 +495,8 @@ public class ConstraintSystemWithPriorities implements ConstraintSystem { @Override public JetType getValue(TypeParameterDescriptor typeParameterDescriptor) { - return getTypeVariable(typeParameterDescriptor).getType(); + TypeValue typeVariable = getTypeVariable(typeParameterDescriptor); + return typeVariable.hasValue() ? typeVariable.getType() : null; } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/DebugConstraintResolutionListener.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/DebugConstraintResolutionListener.java index 52edf22c3f0..6f3415538a0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/DebugConstraintResolutionListener.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/DebugConstraintResolutionListener.java @@ -2,8 +2,10 @@ package org.jetbrains.jet.lang.resolve.calls.inference; import com.google.common.collect.Maps; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.resolve.calls.ResolutionDebugInfo; +import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.jet.lang.types.JetType; import java.util.Map; @@ -17,18 +19,20 @@ import static org.jetbrains.jet.lang.resolve.calls.ResolutionDebugInfo.*; public class DebugConstraintResolutionListener implements ConstraintResolutionListener { private final ResolutionDebugInfo.Data debugInfo; + private final ResolvedCall candidateCall; - public DebugConstraintResolutionListener(@NotNull ResolutionDebugInfo.Data debugInfo) { + public DebugConstraintResolutionListener(@NotNull ResolvedCall candidateCall, @NotNull ResolutionDebugInfo.Data debugInfo) { this.debugInfo = debugInfo; + this.candidateCall = candidateCall; } @Override public void constraintsForUnknown(TypeParameterDescriptor typeParameterDescriptor, BoundsOwner typeValue) { if (!ResolutionDebugInfo.isResolutionDebugEnabled()) return; - Map map = debugInfo.get(BOUNDS_FOR_UNKNOWNS); + Map map = debugInfo.getByKey(BOUNDS_FOR_UNKNOWNS, candidateCall); if (map == null) { map = Maps.newLinkedHashMap(); - debugInfo.set(BOUNDS_FOR_UNKNOWNS, map); + debugInfo.putByKey(BOUNDS_FOR_UNKNOWNS, candidateCall, map); } map.put(typeParameterDescriptor, typeValue); } @@ -36,10 +40,10 @@ public class DebugConstraintResolutionListener implements ConstraintResolutionLi @Override public void constraintsForKnownType(JetType type, BoundsOwner typeValue) { if (!ResolutionDebugInfo.isResolutionDebugEnabled()) return; - Map map = debugInfo.get(BOUNDS_FOR_KNOWNS); + Map map = debugInfo.getByKey(BOUNDS_FOR_KNOWNS, candidateCall); if (map == null) { map = Maps.newLinkedHashMap(); - debugInfo.set(BOUNDS_FOR_KNOWNS, map); + debugInfo.putByKey(BOUNDS_FOR_KNOWNS, candidateCall, map); } map.put(type, typeValue); } @@ -47,17 +51,17 @@ public class DebugConstraintResolutionListener implements ConstraintResolutionLi @Override public void done(ConstraintSystemSolution solution, Set typeParameterDescriptors) { if (!ResolutionDebugInfo.isResolutionDebugEnabled()) return; - debugInfo.set(SOLUTION, solution); - debugInfo.set(UNKNOWNS, typeParameterDescriptors); + debugInfo.putByKey(SOLUTION, candidateCall, solution); + debugInfo.putByKey(UNKNOWNS, candidateCall, typeParameterDescriptors); } @Override public void log(Object... messageFragments) { if (!ResolutionDebugInfo.isResolutionDebugEnabled()) return; - StringBuilder stringBuilder = debugInfo.get(LOG); + StringBuilder stringBuilder = debugInfo.getByKey(LOG, candidateCall); if (stringBuilder == null) { stringBuilder = new StringBuilder(); - debugInfo.set(LOG, stringBuilder); + debugInfo.putByKey(LOG, candidateCall, stringBuilder); } for (Object m : messageFragments) { stringBuilder.append(m); @@ -68,10 +72,10 @@ public class DebugConstraintResolutionListener implements ConstraintResolutionLi @Override public void error(Object... messageFragments) { if (!ResolutionDebugInfo.isResolutionDebugEnabled()) return; - StringBuilder stringBuilder = debugInfo.get(ERRORS); + StringBuilder stringBuilder = debugInfo.getByKey(ERRORS, candidateCall); if (stringBuilder == null) { stringBuilder = new StringBuilder(); - debugInfo.set(ERRORS, stringBuilder); + debugInfo.putByKey(ERRORS, candidateCall, stringBuilder); } for (Object m : messageFragments) { stringBuilder.append(m); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/SubtypingConstraint.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/SubtypingConstraint.java index 5f62fb11233..77e01ea7303 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/SubtypingConstraint.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/SubtypingConstraint.java @@ -36,4 +36,9 @@ public class SubtypingConstraint { public String getErrorMessage() { return type.makeErrorMessage(this); } + + @Override + public String toString() { + return getSubtype() + " :< " + getSupertype(); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/TypeValue.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/TypeValue.java index 837036e003f..48d6e24c57e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/TypeValue.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/TypeValue.java @@ -32,6 +32,7 @@ public class TypeValue implements BoundsOwner { this.positionVariance = null; this.typeParameterDescriptor = null; this.originalType = knownType; + this.value = knownType; } public boolean isKnown() { @@ -42,6 +43,11 @@ public class TypeValue implements BoundsOwner { return typeParameterDescriptor; } + @NotNull + public Variance getPositionVariance() { + return positionVariance; + } + @Override @NotNull public Set getUpperBounds() { @@ -79,4 +85,9 @@ public class TypeValue implements BoundsOwner { public boolean hasValue() { return value != null; } + + @Override + public String toString() { + return isKnown() ? getType().toString() : (getTypeParameterDescriptor() + (hasValue() ? " |-> " + getType() : "")); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java index 55c861b18c8..d3e77c5b6b1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java @@ -20,7 +20,7 @@ public class TypeSubstitutor { } final TypeProjection projection = new TypeProjection(type); - return create(new TypeSubstitution() { + return TypeSubstitutor.create(new TypeSubstitutor.TypeSubstitution() { @Override public TypeProjection get(TypeConstructor key) { if (constructors.contains(key)) { diff --git a/compiler/testData/diagnostics/tests/FunctionCalleeExpressions.jet b/compiler/testData/diagnostics/tests/FunctionCalleeExpressions.jet index 5e6ef793f1d..7e36dc38033 100644 --- a/compiler/testData/diagnostics/tests/FunctionCalleeExpressions.jet +++ b/compiler/testData/diagnostics/tests/FunctionCalleeExpressions.jet @@ -42,7 +42,7 @@ fun main(args : Array) { val b = fooT2()(1) b : Int - fooT2()(1) // : Any? + fooT2()(1) // : Any? 1() 1{} diff --git a/compiler/testData/diagnostics/tests/ResolveOfJavaGenerics.jet b/compiler/testData/diagnostics/tests/ResolveOfJavaGenerics.jet index ae44ace8caf..44264b416f4 100644 --- a/compiler/testData/diagnostics/tests/ResolveOfJavaGenerics.jet +++ b/compiler/testData/diagnostics/tests/ResolveOfJavaGenerics.jet @@ -6,7 +6,8 @@ fun test(a : annotation.RetentionPolicy) { } fun test() { - java.util.Collections.emptyList() + java.util.Collections.emptyList() + val a : java.util.Collection? = java.util.Collections.emptyList() } fun test(a : java.lang.Comparable) { diff --git a/compiler/testData/diagnostics/tests/ResolveToJava.jet b/compiler/testData/diagnostics/tests/ResolveToJava.jet index ff4d34b1cf7..28d49d5ee3f 100644 --- a/compiler/testData/diagnostics/tests/ResolveToJava.jet +++ b/compiler/testData/diagnostics/tests/ResolveToJava.jet @@ -21,7 +21,7 @@ fun test(l : java.util.List) { Collections.emptyList Collections.emptyList Collections.emptyList() - Collections.emptyList() + Collections.emptyList() Collections.singleton(1) : Set? Collections.singleton(1.0) diff --git a/compiler/testData/diagnostics/tests/inference/NoInferenceFromDeclaredBounds.jet b/compiler/testData/diagnostics/tests/inference/NoInferenceFromDeclaredBounds.jet new file mode 100644 index 00000000000..4436d18abf9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/NoInferenceFromDeclaredBounds.jet @@ -0,0 +1,9 @@ +fun fooT2() : fun(t : T) : T { + return {it} +} + +val n : Nothing = null.sure() + +fun test() { + fooT2()(1) +} diff --git a/compiler/testData/diagnostics/tests/regressions/kt353.jet b/compiler/testData/diagnostics/tests/regressions/kt353.jet index dffdaa68d48..bc2a4f6df2f 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt353.jet +++ b/compiler/testData/diagnostics/tests/regressions/kt353.jet @@ -9,15 +9,15 @@ fun foo(a: A) { a.gen() //it works: Unit is derived } - val u: Unit = a.gen() //type mismatch, but Unit can be derived + val u: Unit = a.gen() // Unit should be inferred if (true) { - a.gen() //it works: Unit is derived + a.gen() // Shouldn't work: no info for inference } val b : fun() : Unit = { if (true) { - a.gen() //type mismatch, but Unit can be derived + a.gen() // unit can be inferred } else { () @@ -28,5 +28,5 @@ fun foo(a: A) { a.gen() //type mismatch, but Int can be derived } - a.gen() //it works: Unit is derived + a.gen() // Shouldn't work: no info for inference } \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/runtime/JetNpeTest.java b/compiler/tests/org/jetbrains/jet/runtime/JetNpeTest.java index a4ad31bfa9b..61e0397f34c 100644 --- a/compiler/tests/org/jetbrains/jet/runtime/JetNpeTest.java +++ b/compiler/tests/org/jetbrains/jet/runtime/JetNpeTest.java @@ -24,7 +24,7 @@ public class JetNpeTest extends CodegenTestCase { } public void testNull () throws Exception { - loadText("fun box() = if(null.sure() == 10) \"OK\" else \"fail\""); + loadText("fun box() = if((null : Int?).sure() == 10) \"OK\" else \"fail\""); // System.out.println(generateToText()); Method box = generateFunction("box"); assertThrows(box, NullPointerException.class, null); diff --git a/idea/src/org/jetbrains/jet/plugin/internal/resolvewindow/ResolveToolwindow.java b/idea/src/org/jetbrains/jet/plugin/internal/resolvewindow/ResolveToolwindow.java index 4b9a6fbc102..8f04d3eb557 100644 --- a/idea/src/org/jetbrains/jet/plugin/internal/resolvewindow/ResolveToolwindow.java +++ b/idea/src/org/jetbrains/jet/plugin/internal/resolvewindow/ResolveToolwindow.java @@ -28,11 +28,8 @@ import org.jetbrains.jet.lang.psi.JetExpression; 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.calls.ResolutionDebugInfo; -import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; -import org.jetbrains.jet.lang.resolve.calls.ResolvedValueArgument; +import org.jetbrains.jet.lang.resolve.calls.*; import org.jetbrains.jet.lang.resolve.calls.inference.BoundsOwner; -import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.plugin.JetFileType; @@ -43,6 +40,7 @@ import org.jetbrains.jet.util.slicedmap.WritableSlice; import javax.swing.*; import java.awt.*; +import java.util.List; import java.util.Map; import static org.jetbrains.jet.lang.resolve.BindingContext.*; @@ -52,6 +50,9 @@ import static org.jetbrains.jet.lang.resolve.calls.ResolutionDebugInfo.*; * @author abreslav */ public class ResolveToolwindow extends JPanel { + + public static final String BAR = "\n\n===\n\n"; + public static class Factory implements ToolWindowFactory { @Override public void createToolWindowContent(Project project, ToolWindow toolWindow) { @@ -176,36 +177,49 @@ public class ResolveToolwindow extends JPanel { } private String renderDebugInfo(PsiElement currentElement, @Nullable ResolutionDebugInfo.Data debugInfo, @Nullable ResolvedCall call) { - final String bar = "\n\n===\n\n"; - StringBuilder result = new StringBuilder(); - + if (debugInfo != null) { - StringBuilder errors = debugInfo.get(ERRORS); - if (errors != null) { - result.append("Errors: \n").append(errors).append(bar); + List> resolutionTasks = debugInfo.get(TASKS); + for (ResolutionTask resolutionTask : resolutionTasks) { + for (ResolvedCallImpl resolvedCall : resolutionTask.getCandidates()) { + renderResolutionLogForCall(debugInfo, resolvedCall, result); + } } - StringBuilder log = debugInfo.get(LOG); - if (log != null) { - result.append("Log: \n").append(log).append(bar); - } - - Map knowns = debugInfo.get(BOUNDS_FOR_KNOWNS); - renderMap(knowns, result); - Map unknowns = debugInfo.get(BOUNDS_FOR_UNKNOWNS); - renderMap(unknowns, result); - - result.append(bar); - call = debugInfo.get(RESULT); } - renderCall(result, call); + if (call != null) { + renderCall(result, call); + } + else { + result.append("Resolved call is null\n"); + } result.append(currentElement + ": " + currentElement.getText()); return result.toString(); } - + + private void renderResolutionLogForCall(Data debugInfo, ResolvedCallImpl resolvedCall, StringBuilder result) { + result.append("Trying to call ").append(resolvedCall.getCandidateDescriptor()).append("\n"); + StringBuilder errors = debugInfo.getByKey(ERRORS, resolvedCall); + if (errors != null) { + result.append("Errors: \n").append(errors).append(BAR); + } + + StringBuilder log = debugInfo.getByKey(LOG, resolvedCall); + if (log != null) { + result.append("Log: \n").append(log).append(BAR); + } + + Map knowns = debugInfo.getByKey(BOUNDS_FOR_KNOWNS, resolvedCall); + renderMap(knowns, result); + Map unknowns = debugInfo.getByKey(BOUNDS_FOR_UNKNOWNS, resolvedCall); + renderMap(unknowns, result); + + result.append(BAR); + } + private void renderMap(Map map, StringBuilder builder) { if (map == null) return; diff --git a/idea/testData/checker/ResolveToJava.jet b/idea/testData/checker/ResolveToJava.jet index e8cb67fceb3..6dfda6ac032 100644 --- a/idea/testData/checker/ResolveToJava.jet +++ b/idea/testData/checker/ResolveToJava.jet @@ -19,7 +19,7 @@ fun test(l : java.util.List) { Collections.emptyList Collections.emptyList Collections.emptyList() - Collections.emptyList() + Collections.emptyList() Collections.singleton(1) : Set? Collections.singleton(1.0) From 7d3d5b4c883f41dd2869d03917892a596c436320 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 14 Dec 2011 14:06:44 +0400 Subject: [PATCH 02/33] Read only interface extracted from OverloadResolutionResult --- .../jet/lang/resolve/calls/CallResolver.java | 36 ++++---- .../calls/OverloadResolutionResults.java | 70 +++------------- .../calls/OverloadResolutionResultsImpl.java | 83 +++++++++++++++++++ .../BasicExpressionTypingVisitor.java | 4 +- .../ControlStructureTypingVisitor.java | 10 +-- .../expressions/ExpressionTypingContext.java | 4 +- .../jetbrains/jet/resolve/JetResolveTest.java | 4 +- 7 files changed, 122 insertions(+), 89 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResultsImpl.java 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 176524e2c9a..4f753b068a0 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 @@ -372,10 +372,10 @@ public class CallResolver { }; TemporaryBindingTrace traceForFirstNonemptyCandidateSet = null; - OverloadResolutionResults resultsForFirstNonemptyCandidateSet = null; + OverloadResolutionResultsImpl resultsForFirstNonemptyCandidateSet = null; for (ResolutionTask task : prioritizedTasks) { TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace); - OverloadResolutionResults results = performResolution(temporaryTrace, scope, expectedType, task, tracing); + OverloadResolutionResultsImpl results = performResolution(temporaryTrace, scope, expectedType, task, tracing); if (results.isSuccess()) { temporaryTrace.commit(); @@ -407,7 +407,7 @@ public class CallResolver { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @NotNull - private OverloadResolutionResults performResolution( + private OverloadResolutionResultsImpl performResolution( @NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull JetType expectedType, @NotNull ResolutionTask task, @NotNull TracingStrategy tracing @@ -593,7 +593,7 @@ public class CallResolver { } } - OverloadResolutionResults results = computeResultAndReportErrors(trace, tracing, successfulCandidates, failedCandidates); + OverloadResolutionResultsImpl results = computeResultAndReportErrors(trace, tracing, successfulCandidates, failedCandidates); if (!results.singleDescriptor()) { checkTypesWithNoCallee(trace, scope, task.getCall()); } @@ -740,7 +740,7 @@ public class CallResolver { } @NotNull - private OverloadResolutionResults computeResultAndReportErrors( + private OverloadResolutionResultsImpl computeResultAndReportErrors( BindingTrace trace, TracingStrategy tracing, Set> successfulCandidates, @@ -748,7 +748,7 @@ public class CallResolver { // TODO : maybe it's better to filter overrides out first, and only then look for the maximally specific if (successfulCandidates.size() > 0) { - OverloadResolutionResults results = chooseAndReportMaximallySpecific(successfulCandidates, true); + OverloadResolutionResultsImpl results = chooseAndReportMaximallySpecific(successfulCandidates, true); if (results.isAmbiguity()) { // This check is needed for the following case: // x.foo(unresolved) -- if there are multiple foo's, we'd report an ambiguity, and it does not make sense here @@ -772,15 +772,15 @@ public class CallResolver { } } if (!thisLevel.isEmpty()) { - OverloadResolutionResults results = chooseAndReportMaximallySpecific(thisLevel, false); + OverloadResolutionResultsImpl results = chooseAndReportMaximallySpecific(thisLevel, false); if (results.isSuccess()) { results.getResult().getTrace().commit(); - return OverloadResolutionResults.singleFailedCandidate(results.getResult()); + return OverloadResolutionResultsImpl.singleFailedCandidate(results.getResult()); } tracing.noneApplicable(trace, results.getResults()); tracing.recordAmbiguity(trace, results.getResults()); - return OverloadResolutionResults.manyFailedCandidates(results.getResults()); + return OverloadResolutionResultsImpl.manyFailedCandidates(results.getResults()); } } assert false : "Should not be reachable, cause every status must belong to some level"; @@ -789,17 +789,17 @@ public class CallResolver { if (noOverrides.size() != 1) { tracing.noneApplicable(trace, noOverrides); tracing.recordAmbiguity(trace, noOverrides); - return OverloadResolutionResults.manyFailedCandidates(noOverrides); + return OverloadResolutionResultsImpl.manyFailedCandidates(noOverrides); } failedCandidates = noOverrides; } ResolvedCallImpl failed = failedCandidates.iterator().next(); failed.getTrace().commit(); - return OverloadResolutionResults.singleFailedCandidate(failed); + return OverloadResolutionResultsImpl.singleFailedCandidate(failed); } else { tracing.unresolvedReference(trace); - return OverloadResolutionResults.nameNotFound(); + return OverloadResolutionResultsImpl.nameNotFound(); } } @@ -810,7 +810,7 @@ public class CallResolver { return true; } - private OverloadResolutionResults chooseAndReportMaximallySpecific(Set> candidates, boolean discriminateGenerics) { + private OverloadResolutionResultsImpl chooseAndReportMaximallySpecific(Set> candidates, boolean discriminateGenerics) { if (candidates.size() != 1) { Set> cleanCandidates = Sets.newLinkedHashSet(candidates); for (Iterator> iterator = cleanCandidates.iterator(); iterator.hasNext(); ) { @@ -825,26 +825,26 @@ public class CallResolver { } ResolvedCallImpl maximallySpecific = overloadingConflictResolver.findMaximallySpecific(cleanCandidates, false); if (maximallySpecific != null) { - return OverloadResolutionResults.success(maximallySpecific); + return OverloadResolutionResultsImpl.success(maximallySpecific); } if (discriminateGenerics) { ResolvedCallImpl maximallySpecificGenericsDiscriminated = overloadingConflictResolver.findMaximallySpecific(cleanCandidates, true); if (maximallySpecificGenericsDiscriminated != null) { - return OverloadResolutionResults.success(maximallySpecificGenericsDiscriminated); + return OverloadResolutionResultsImpl.success(maximallySpecificGenericsDiscriminated); } } Set> noOverrides = OverridingUtil.filterOverrides(candidates, MAP_TO_RESULT); - return OverloadResolutionResults.ambiguity(noOverrides); + return OverloadResolutionResultsImpl.ambiguity(noOverrides); } else { ResolvedCallImpl result = candidates.iterator().next(); TemporaryBindingTrace temporaryTrace = result.getTrace(); temporaryTrace.commit(); - return OverloadResolutionResults.success(result); + return OverloadResolutionResultsImpl.success(result); } } @@ -868,7 +868,7 @@ public class CallResolver { } @NotNull - public OverloadResolutionResults resolveExactSignature(@NotNull JetScope scope, @NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List parameterTypes) { + public OverloadResolutionResultsImpl resolveExactSignature(@NotNull JetScope scope, @NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List parameterTypes) { List> result = findCandidatesByExactSignature(scope, receiver, name, parameterTypes); BindingTraceContext trace = new BindingTraceContext(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResults.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResults.java index dfe84f5f26c..9525accd886 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResults.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResults.java @@ -4,13 +4,12 @@ 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 { - public enum Code { + * @author abreslav + */ +public interface OverloadResolutionResults { + enum Code { SUCCESS(true), NAME_NOT_FOUND(false), SINGLE_CANDIDATE_ARGUMENT_MISMATCH(false), @@ -26,69 +25,22 @@ public class OverloadResolutionResults { boolean isSuccess() { return success; } - - } - - public static OverloadResolutionResults success(@NotNull ResolvedCallImpl descriptor) { - return new OverloadResolutionResults(Code.SUCCESS, Collections.singleton(descriptor)); - } - - public static OverloadResolutionResults nameNotFound() { - return new OverloadResolutionResults(Code.NAME_NOT_FOUND, Collections.>emptyList()); - } - - public static OverloadResolutionResults singleFailedCandidate(ResolvedCallImpl candidate) { - return new OverloadResolutionResults(Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH, Collections.singleton(candidate)); - } - public static OverloadResolutionResults manyFailedCandidates(Collection> failedCandidates) { - return new OverloadResolutionResults(Code.MANY_FAILED_CANDIDATES, failedCandidates); - } - - public static OverloadResolutionResults ambiguity(Collection> descriptors) { - return new OverloadResolutionResults(Code.AMBIGUITY, descriptors); - } - - private final Collection> results; - private final Code resultCode; - - private OverloadResolutionResults(@NotNull Code resultCode, @NotNull Collection> results) { - this.results = results; - this.resultCode = resultCode; } @NotNull - public Collection> getResults() { - return results; - } + Collection> getResults(); @NotNull - public ResolvedCallImpl getResult() { - assert singleDescriptor(); - return results.iterator().next(); - } + ResolvedCall getResult(); @NotNull - public Code getResultCode() { - return resultCode; - } + Code getResultCode(); - public boolean isSuccess() { - return resultCode.isSuccess(); - } + boolean isSuccess(); - public boolean singleDescriptor() { - return isSuccess() || resultCode == Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH; - } + boolean singleDescriptor(); - public boolean isNothing() { - return resultCode == Code.NAME_NOT_FOUND; - } + boolean isNothing(); - public boolean isAmbiguity() { - return resultCode == Code.AMBIGUITY; - } -// -// public OverloadResolutionResults newContents(@NotNull Collection functionDescriptors) { -// return new OverloadResolutionResults(resultCode, functionDescriptors); -// } + boolean isAmbiguity(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResultsImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResultsImpl.java new file mode 100644 index 00000000000..577c365b694 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResultsImpl.java @@ -0,0 +1,83 @@ +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 OverloadResolutionResultsImpl implements OverloadResolutionResults { + + public static OverloadResolutionResultsImpl success(@NotNull ResolvedCallImpl descriptor) { + return new OverloadResolutionResultsImpl(Code.SUCCESS, Collections.singleton(descriptor)); + } + + public static OverloadResolutionResultsImpl nameNotFound() { + return new OverloadResolutionResultsImpl(Code.NAME_NOT_FOUND, Collections.>emptyList()); + } + + public static OverloadResolutionResultsImpl singleFailedCandidate(ResolvedCallImpl candidate) { + return new OverloadResolutionResultsImpl(Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH, Collections.singleton(candidate)); + } + public static OverloadResolutionResultsImpl manyFailedCandidates(Collection> failedCandidates) { + return new OverloadResolutionResultsImpl(Code.MANY_FAILED_CANDIDATES, failedCandidates); + } + + public static OverloadResolutionResultsImpl ambiguity(Collection> descriptors) { + return new OverloadResolutionResultsImpl(Code.AMBIGUITY, descriptors); + } + + private final Collection> results; + private final Code resultCode; + + private OverloadResolutionResultsImpl(@NotNull Code resultCode, @NotNull Collection> results) { + this.results = results; + this.resultCode = resultCode; + } + + @Override + @NotNull + public Collection> getResults() { + return results; + } + + @Override + @NotNull + public ResolvedCallImpl getResult() { + assert singleDescriptor(); + return results.iterator().next(); + } + + @Override + @NotNull + public Code getResultCode() { + return resultCode; + } + + @Override + public boolean isSuccess() { + return resultCode.isSuccess(); + } + + @Override + public boolean singleDescriptor() { + return isSuccess() || resultCode == Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH; + } + + @Override + public boolean isNothing() { + return resultCode == Code.NAME_NOT_FOUND; + } + + @Override + public boolean isAmbiguity() { + return resultCode == Code.AMBIGUITY; + } +// +// public OverloadResolutionResultsImpl newContents(@NotNull Collection functionDescriptors) { +// return new OverloadResolutionResultsImpl(resultCode, functionDescriptors); +// } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java index a2898afa2dd..8b58250041f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -15,7 +15,7 @@ import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.calls.CallMaker; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; -import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults; +import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResultsImpl; import org.jetbrains.jet.lang.resolve.constants.*; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; @@ -727,7 +727,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { String name = "equals"; if (right != null) { ExpressionReceiver receiver = ExpressionTypingUtils.safeGetExpressionReceiver(facade, left, context.replaceScope(context.scope)); - OverloadResolutionResults resolutionResults = context.resolveExactSignature( + OverloadResolutionResultsImpl resolutionResults = context.resolveExactSignature( receiver, "equals", Collections.singletonList(JetStandardClasses.getNullableAnyType())); if (resolutionResults.isSuccess()) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java index f573e39e79a..961fb6fc9b3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java @@ -10,10 +10,8 @@ import org.jetbrains.jet.lang.diagnostics.Errors; 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.calls.OverloadResolutionResults; +import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResultsImpl; import org.jetbrains.jet.lang.resolve.DescriptorUtils; -import org.jetbrains.jet.lang.resolve.calls.TaskPrioritizers; -import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope; @@ -237,7 +235,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { @Nullable private JetType checkIterableConvention(@NotNull ExpressionReceiver loopRange, ExpressionTypingContext context) { JetExpression loopRangeExpression = loopRange.getExpression(); - OverloadResolutionResults iteratorResolutionResults = context.resolveExactSignature(loopRange, "iterator", Collections.emptyList()); + OverloadResolutionResultsImpl iteratorResolutionResults = context.resolveExactSignature(loopRange, "iterator", Collections.emptyList()); if (iteratorResolutionResults.isSuccess()) { FunctionDescriptor iteratorFunction = iteratorResolutionResults.getResult().getResultingDescriptor(); @@ -259,7 +257,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { context.trace.record(LOOP_RANGE_HAS_NEXT, loopRange.getExpression(), hasNextFunctionSupported ? hasNextFunction : hasNextProperty); } - OverloadResolutionResults nextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "next", Collections.emptyList()); + OverloadResolutionResultsImpl nextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "next", Collections.emptyList()); if (nextResolutionResults.isAmbiguity()) { context.trace.report(NEXT_AMBIGUITY.on(loopRangeExpression)); } else if (nextResolutionResults.isNothing()) { @@ -288,7 +286,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { @Nullable private FunctionDescriptor checkHasNextFunctionSupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, ExpressionTypingContext context) { - OverloadResolutionResults hasNextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "hasNext", Collections.emptyList()); + OverloadResolutionResultsImpl hasNextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "hasNext", Collections.emptyList()); if (hasNextResolutionResults.isAmbiguity()) { context.trace.report(HAS_NEXT_FUNCTION_AMBIGUITY.on(loopRange)); } else if (hasNextResolutionResults.isNothing()) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java index c27e9f998cd..3219126fdce 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java @@ -12,7 +12,7 @@ import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.TypeResolver; import org.jetbrains.jet.lang.resolve.calls.CallMaker; import org.jetbrains.jet.lang.resolve.calls.CallResolver; -import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults; +import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResultsImpl; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver; @@ -196,7 +196,7 @@ import java.util.Map; } @NotNull - public OverloadResolutionResults resolveExactSignature(@NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List parameterTypes) { + public OverloadResolutionResultsImpl resolveExactSignature(@NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List parameterTypes) { return getCallResolver().resolveExactSignature(scope, receiver, name, parameterTypes); } } diff --git a/compiler/tests/org/jetbrains/jet/resolve/JetResolveTest.java b/compiler/tests/org/jetbrains/jet/resolve/JetResolveTest.java index 0e772f2acd4..d8139d4ebd1 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/JetResolveTest.java +++ b/compiler/tests/org/jetbrains/jet/resolve/JetResolveTest.java @@ -16,7 +16,7 @@ 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.resolve.calls.CallResolver; -import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults; +import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResultsImpl; import org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; @@ -113,7 +113,7 @@ public class JetResolveTest extends ExtensibleResolveTestCase { // JetTypeInferrer.Services typeInferrerServices = JetSemanticServices.createSemanticServices(getProject()).getTypeInferrerServices(new BindingTraceContext()); CallResolver callResolver = new CallResolver(JetSemanticServices.createSemanticServices(getProject()), DataFlowInfo.EMPTY); - OverloadResolutionResults functions = callResolver.resolveExactSignature( + OverloadResolutionResultsImpl functions = callResolver.resolveExactSignature( classDescriptor.getMemberScope(typeArguments), ReceiverDescriptor.NO_RECEIVER, name, parameterTypeList); for (ResolvedCallImpl resolvedCall : functions.getResults()) { List unsubstitutedValueParameters = resolvedCall.getResultingDescriptor().getValueParameters(); From e8ed53df5f069a2f7a6b65a2c939dd8ac30f2840 Mon Sep 17 00:00:00 2001 From: svtk Date: Wed, 14 Dec 2011 14:10:58 +0400 Subject: [PATCH 03/33] bug with default parameter value --- .../src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java index 1ead3251e54..c3dab813a27 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java @@ -577,7 +577,7 @@ public class JetControlFlowProcessor { JetExpression defaultValue = parameter.getDefaultValue(); builder.declare(parameter); if (defaultValue != null) { - builder.read(defaultValue); + value(defaultValue, inCondition); } builder.write(parameter, parameter); } From 5e08376e0e6d1e36c0ccd887f8e5635fe4406054 Mon Sep 17 00:00:00 2001 From: svtk Date: Wed, 14 Dec 2011 14:27:07 +0400 Subject: [PATCH 04/33] KT-786 Exception on incomplete code with 'when' --- .../jetbrains/jet/lang/types/TypeUtils.java | 1 + .../tests/controlStructures/kt786.jet | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 compiler/testData/diagnostics/tests/controlStructures/kt786.jet diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeUtils.java index 2e3b5f83ede..6e6f3cfa7c9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeUtils.java @@ -361,6 +361,7 @@ public class TypeUtils { fullSubstitution.put(typeParameterDescriptor.getTypeConstructor(), substitutedTypeProjection); } } + if (JetStandardClasses.isNothingOrNullableNothing(context)) return; for (JetType supertype : context.getConstructor().getSupertypes()) { fillInDeepSubstitutor(supertype, substitutor, substitution, fullSubstitution); } diff --git a/compiler/testData/diagnostics/tests/controlStructures/kt786.jet b/compiler/testData/diagnostics/tests/controlStructures/kt786.jet new file mode 100644 index 00000000000..665af148d31 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlStructures/kt786.jet @@ -0,0 +1,26 @@ +namespace kt786 + +//KT-786 Exception on incomplete code with 'when' +fun foo() : Int { + val d = 2 + var z = 0 + when(d) { + is 5, is 3 => z++ + else => { z = -1000 } + return z => 34 + } +} + +//test unreachable code +fun fff(): Int { + var d = 3 + when(d) { + is 4 => 21 + return 2 => return 47 + bar() => 45 + 444 => true + } + return 34 +} + +fun bar(): Int = 8 \ No newline at end of file From 9aaf20bc95ec62ecd58573632eb8deaea362a129 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Wed, 14 Dec 2011 12:44:07 +0200 Subject: [PATCH 05/33] optimizations for instanceof List<*> --- .../org/jetbrains/jet/codegen/ExpressionCodegen.java | 10 +++++++--- examples/src/benchmarks/FList.kt | 4 ++-- stdlib/src/jet/typeinfo/TypeInfo.java | 10 +++++----- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index b8628fbc7c0..4513595264f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -2475,9 +2475,13 @@ If finally block is present, its last expression is the value of try expression. return hasTypeInfoForInstanceOf(type.getArguments().get(0).getType()); } - for(TypeParameterDescriptor proj : classDescriptor.getTypeConstructor().getParameters()) { - if(proj.isReified()) { - return true; + for (int i = 0; i < type.getArguments().size(); i++) { + TypeParameterDescriptor typeParameterDescriptor = classDescriptor.getTypeConstructor().getParameters().get(i); + if(typeParameterDescriptor.isReified()) { + TypeProjection typeProjection = type.getArguments().get(i); + if( !typeProjection.getType().equals(typeParameterDescriptor.getUpperBoundsAsType())) { + return true; + } } } diff --git a/examples/src/benchmarks/FList.kt b/examples/src/benchmarks/FList.kt index 5d806215920..17179b006bb 100644 --- a/examples/src/benchmarks/FList.kt +++ b/examples/src/benchmarks/FList.kt @@ -30,7 +30,7 @@ class StandardFList (override val head: T, override val tail: FList) : FLi fun FList.plus2(element: T): FList = when(this) { - is EmptyFList => OneElementFList(element) + is EmptyFList<*> => OneElementFList(element) else => StandardFList(element, this) } @@ -67,4 +67,4 @@ fun main(args: Array) { System.out?.println(System.currentTimeMillis() - start2) System.out?.println() } -} \ No newline at end of file +} diff --git a/stdlib/src/jet/typeinfo/TypeInfo.java b/stdlib/src/jet/typeinfo/TypeInfo.java index fbba351bcbd..dfdda4e367e 100644 --- a/stdlib/src/jet/typeinfo/TypeInfo.java +++ b/stdlib/src/jet/typeinfo/TypeInfo.java @@ -376,7 +376,7 @@ public abstract class TypeInfo implements JetObject { return false; } if (superType.projections == null || superType.projections.length != projections.length) { - throw new IllegalArgumentException("inconsistent type infos for the same class"); + throw new IllegalArgumentException("inconsistent type info for the same class"); } for (int i = 0; i < projections.length; i++) { // TODO handle variance here @@ -451,18 +451,18 @@ public abstract class TypeInfo implements JetObject { if(klass == null) return null; - lock.readLock().lock(); +// lock.readLock().lock(); Signature sig = map.get(klass); - lock.readLock().unlock(); +// lock.readLock().unlock(); if (sig == null) { - lock.writeLock().lock(); +// lock.writeLock().lock(); sig = map.get(klass); if (sig == null) { sig = internalParse(klass); } - lock.writeLock().unlock(); +// lock.writeLock().unlock(); } return sig; } From 7e969cf37035b1be1a3e22ebbde3452caded25ff Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Wed, 14 Dec 2011 13:17:57 +0200 Subject: [PATCH 06/33] Binary Boolean.and/or added by patch of Sergey Ignatov --- compiler/frontend/src/jet/Library.jet | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/frontend/src/jet/Library.jet b/compiler/frontend/src/jet/Library.jet index 888934c7121..580d1dd1a2b 100644 --- a/compiler/frontend/src/jet/Library.jet +++ b/compiler/frontend/src/jet/Library.jet @@ -198,6 +198,10 @@ trait Hashable { class Boolean : Comparable { fun not() : Boolean + fun and(other : Boolean) : Boolean + + fun or(other : Boolean) : Boolean + fun xor(other : Boolean) : Boolean fun equals(other : Any?) : Boolean From b58a986262fe430861d8414b1cf0c7336d05b63c Mon Sep 17 00:00:00 2001 From: svtk Date: Wed, 14 Dec 2011 16:01:23 +0400 Subject: [PATCH 07/33] KT-244 Use dataflow info while resolving variable initializers --- .../jet/lang/resolve/DescriptorResolver.java | 14 ++++---- .../expressions/ExpressionTypingServices.java | 8 +++-- .../ExpressionTypingVisitorForStatements.java | 2 +- .../tests/nullabilityAndAutoCasts/kt244.jet | 34 +++++++++++++++++++ 4 files changed, 48 insertions(+), 10 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/nullabilityAndAutoCasts/kt244.jet diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java index 89a95abcd27..c5df77d3682 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java @@ -12,6 +12,7 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; @@ -449,8 +450,8 @@ public class DescriptorResolver { } @NotNull - public VariableDescriptor resolveLocalVariableDescriptor(DeclarationDescriptor containingDeclaration, JetScope scope, JetProperty property) { - JetType type = getVariableType(scope, property, false); // For a local variable the type must not be deferred + public VariableDescriptor resolveLocalVariableDescriptor(DeclarationDescriptor containingDeclaration, JetScope scope, JetProperty property, DataFlowInfo dataFlowInfo) { + JetType type = getVariableType(scope, property, dataFlowInfo, false); // For a local variable the type must not be deferred return resolveLocalVariableDescriptorWithType(containingDeclaration, property, type); } @@ -548,9 +549,9 @@ public class DescriptorResolver { ? ReceiverDescriptor.NO_RECEIVER : new ExtensionReceiver(propertyDescriptor, receiverType); - JetScope scope2 = getPropertyDeclarationInnerScope(scope, propertyDescriptor, typeParameterDescriptors, receiverDescriptor); + JetScope propertyScope = getPropertyDeclarationInnerScope(scope, propertyDescriptor, typeParameterDescriptors, receiverDescriptor); - JetType type = getVariableType(scope2, property, true); + JetType type = getVariableType(propertyScope, property, DataFlowInfo.EMPTY, true); JetType inType = isVar ? type : null; propertyDescriptor.setType(inType, type, typeParameterDescriptors, DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration), receiverDescriptor); @@ -580,7 +581,7 @@ public class DescriptorResolver { } @NotNull - private JetType getVariableType(@NotNull final JetScope scope, @NotNull final JetProperty property, boolean allowDeferred) { + private JetType getVariableType(@NotNull final JetScope scope, @NotNull final JetProperty property, @NotNull final DataFlowInfo dataFlowInfo, boolean allowDeferred) { // TODO : receiver? JetTypeReference propertyTypeRef = property.getPropertyTypeRef(); @@ -598,8 +599,7 @@ public class DescriptorResolver { LazyValue lazyValue = new LazyValueWithDefault(ErrorUtils.createErrorType("Recursive dependency")) { @Override protected JetType compute() { - //JetFlowInformationProvider flowInformationProvider = computeFlowData(property, initializer); - return semanticServices.getTypeInferrerServices(trace).safeGetType(scope, initializer, TypeUtils.NO_EXPECTED_TYPE); + return semanticServices.getTypeInferrerServices(trace).safeGetType(scope, initializer, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo); } }; if (allowDeferred) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java index 3ed6dc0304e..39f1ba5c916 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java @@ -48,7 +48,11 @@ public class ExpressionTypingServices { @NotNull public JetType safeGetType(@NotNull JetScope scope, @NotNull JetExpression expression, @NotNull JetType expectedType) { - JetType type = getType(scope, expression, expectedType); + return safeGetType(scope, expression, expectedType, DataFlowInfo.EMPTY); + } + + public JetType safeGetType(@NotNull JetScope scope, @NotNull JetExpression expression, @NotNull JetType expectedType, @NotNull DataFlowInfo dataFlowInfo) { + JetType type = getType(scope, expression, expectedType, dataFlowInfo); if (type != null) { return type; } @@ -61,7 +65,7 @@ public class ExpressionTypingServices { } @Nullable - public JetType getType(@NotNull final JetScope scope, @NotNull JetExpression expression, @NotNull JetType expectedType, DataFlowInfo dataFlowInfo) { + public JetType getType(@NotNull final JetScope scope, @NotNull JetExpression expression, @NotNull JetType expectedType, @NotNull DataFlowInfo dataFlowInfo) { ExpressionTypingContext context = ExpressionTypingContext.newContext( semanticServices, new HashMap(), new HashMap>(), new LabelResolver(), diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java index d4d6cc95afd..56ce116c9df 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java @@ -85,7 +85,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito context.trace.report(LOCAL_VARIABLE_WITH_SETTER.on(setter)); } - VariableDescriptor propertyDescriptor = context.getDescriptorResolver().resolveLocalVariableDescriptor(scope.getContainingDeclaration(), scope, property); + VariableDescriptor propertyDescriptor = context.getDescriptorResolver().resolveLocalVariableDescriptor(scope.getContainingDeclaration(), scope, property, context.dataFlowInfo); JetExpression initializer = property.getInitializer(); if (property.getPropertyTypeRef() != null && initializer != null) { JetType outType = propertyDescriptor.getOutType(); diff --git a/compiler/testData/diagnostics/tests/nullabilityAndAutoCasts/kt244.jet b/compiler/testData/diagnostics/tests/nullabilityAndAutoCasts/kt244.jet new file mode 100644 index 00000000000..3fdb3fc0a75 --- /dev/null +++ b/compiler/testData/diagnostics/tests/nullabilityAndAutoCasts/kt244.jet @@ -0,0 +1,34 @@ +namespace kt244 + +//+JDK + +// KT-244 Use dataflow info while resolving variable initializers + +fun f(s: String?) { + if (s != null) { + s.length //ok + var i = s.length //error: Only safe calls are allowed on a nullable receiver + System.out?.println(s.length) //error + } +} + +// more tests +class A(a: String?) { + val b = if (a != null) a.length else 1 + { + if (a != null) { + val c = a.length + } + } + + val i : Int + + { + if (a is String) { + i = a.length + } + else { + i = 3 + } + } +} \ No newline at end of file From 5f2afb38a8d93c558adc8f0221d6b5ff0501adc2 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 14 Dec 2011 16:51:25 +0400 Subject: [PATCH 08/33] OverloadResolutionResult is returned from CallResolver instead of descriptors. This makes more information availbale to the caller (useful for better diagnostics). --- .../AmbiguousDescriptorDiagnosticFactory.java | 10 +-- .../jet/lang/resolve/AnnotationResolver.java | 11 ++- .../jet/lang/resolve/BodyResolver.java | 7 +- .../jet/lang/resolve/calls/CallResolver.java | 81 +++++++++---------- .../calls/OverloadResolutionResults.java | 9 ++- .../calls/OverloadResolutionResultsImpl.java | 16 ++-- .../BasicExpressionTypingVisitor.java | 43 +++++----- .../ControlStructureTypingVisitor.java | 20 ++--- .../expressions/ExpressionTypingContext.java | 26 +++--- .../ExpressionTypingVisitorForStatements.java | 10 +-- .../tests/FunctionCalleeExpressions.jet | 2 +- .../NoInferenceFromDeclaredBounds.jet | 12 +-- .../jetbrains/jet/resolve/JetResolveTest.java | 8 +- 13 files changed, 132 insertions(+), 123 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/AmbiguousDescriptorDiagnosticFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/AmbiguousDescriptorDiagnosticFactory.java index 23126722df9..74f47e8508c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/AmbiguousDescriptorDiagnosticFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/AmbiguousDescriptorDiagnosticFactory.java @@ -1,8 +1,8 @@ package org.jetbrains.jet.lang.diagnostics; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; -import org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl; +import org.jetbrains.jet.lang.descriptors.CallableDescriptor; +import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.jet.resolve.DescriptorRenderer; import java.util.Collection; @@ -10,7 +10,7 @@ import java.util.Collection; /** * @author abreslav */ -public class AmbiguousDescriptorDiagnosticFactory extends ParameterizedDiagnosticFactory1>> { +public class AmbiguousDescriptorDiagnosticFactory extends ParameterizedDiagnosticFactory1>> { public static AmbiguousDescriptorDiagnosticFactory create(String messageTemplate) { return new AmbiguousDescriptorDiagnosticFactory(messageTemplate); } @@ -20,9 +20,9 @@ public class AmbiguousDescriptorDiagnosticFactory extends ParameterizedDiagnosti } @Override - protected String makeMessageFor(@NotNull Collection> argument) { + protected String makeMessageFor(@NotNull Collection> argument) { StringBuilder stringBuilder = new StringBuilder("\n"); - for (ResolvedCallImpl call : argument) { + for (ResolvedCall call : argument) { stringBuilder.append(DescriptorRenderer.TEXT.render(call.getResultingDescriptor())).append("\n"); } return stringBuilder.toString(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java index f05397f66a5..779286f8b02 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java @@ -4,12 +4,14 @@ import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.JetSemanticServices; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; 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.CallMaker; import org.jetbrains.jet.lang.resolve.calls.CallResolver; +import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.scopes.JetScope; @@ -52,8 +54,13 @@ public class AnnotationResolver { } public void resolveAnnotationStub(@NotNull JetScope scope, @NotNull JetAnnotationEntry entryElement, @NotNull AnnotationDescriptor descriptor) { - 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); + OverloadResolutionResults results = callResolver.resolveCall(trace, scope, CallMaker.makeCall(ReceiverDescriptor.NO_RECEIVER, null, entryElement), NO_EXPECTED_TYPE); + if (results.isSuccess()) { + descriptor.setAnnotationType(results.getResultingDescriptor().getReturnType()); + } + else { + descriptor.setAnnotationType(ErrorUtils.createErrorType("Unresolved annotation type")); + } } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index a7559726cd6..171a69870b3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -3,7 +3,6 @@ package org.jetbrains.jet.lang.resolve; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.intellij.lang.ASTNode; -import com.intellij.openapi.util.Pair; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.containers.Queue; import org.jetbrains.annotations.NotNull; @@ -11,6 +10,7 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.calls.CallMaker; import org.jetbrains.jet.lang.resolve.calls.CallResolver; +import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope; @@ -122,10 +122,11 @@ public class BodyResolver { JetTypeReference typeReference = call.getTypeReference(); if (typeReference != null) { if (descriptor.getUnsubstitutedPrimaryConstructor() != null) { - JetType supertype = new CallResolver(context.getSemanticServices(), DataFlowInfo.EMPTY).resolveCall( + OverloadResolutionResults results = new CallResolver(context.getSemanticServices(), DataFlowInfo.EMPTY).resolveCall( context.getTrace(), scopeForConstructor, CallMaker.makeCall(ReceiverDescriptor.NO_RECEIVER, null, call), NO_EXPECTED_TYPE); - if (supertype != null) { + if (results.isSuccess()) { + JetType supertype = results.getResultingDescriptor().getReturnType(); recordSupertype(typeReference, supertype); ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype); if (classDescriptor != null) { 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 4f753b068a0..989710ce480 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 @@ -6,7 +6,6 @@ import com.google.common.collect.Sets; 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.JetSemanticServices; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; @@ -29,9 +28,7 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.*; import static org.jetbrains.jet.lang.resolve.calls.ResolutionStatus.*; import static org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl.MAP_TO_CANDIDATE; import static org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl.MAP_TO_RESULT; -import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintType.EXPECTED_TYPE; -import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintType.RECEIVER; -import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintType.VALUE_ARGUMENT; +import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintType.*; import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER; import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE; @@ -51,8 +48,8 @@ public class CallResolver { this.dataFlowInfo = dataFlowInfo; } - @Nullable - public VariableDescriptor resolveSimpleProperty( + @NotNull + public OverloadResolutionResults resolveSimpleProperty( @NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull Call call, @@ -76,19 +73,18 @@ public class CallResolver { return resolveCallToDescriptor(trace, scope, call, expectedType, prioritizedTasks, nameExpression); } - @Nullable - public JetType resolveCall( + @NotNull + public OverloadResolutionResults resolveCall( @NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull Call call, @NotNull JetType expectedType ) { - FunctionDescriptor functionDescriptor = resolveSimpleCallToFunctionDescriptor(trace, scope, call, expectedType); - return functionDescriptor == null ? null : functionDescriptor.getReturnType(); + return resolveSimpleCallToFunctionDescriptor(trace, scope, call, expectedType); } - @Nullable - public ResolvedCall resolveCallWithGivenName( + @NotNull + public OverloadResolutionResults resolveCallWithGivenName( @NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull final Call call, @@ -100,8 +96,8 @@ public class CallResolver { return doResolveCall(trace, scope, call, expectedType, tasks, functionReference); } - @Nullable - private FunctionDescriptor resolveSimpleCallToFunctionDescriptor( + @NotNull + private OverloadResolutionResults resolveSimpleCallToFunctionDescriptor( @NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull final Call call, @@ -189,11 +185,11 @@ public class CallResolver { JetType calleeType = typingServices.safeGetType(scope, calleeExpression, NO_EXPECTED_TYPE); // We are actually expecting a function, but there seems to be no easy way of expressing this if (!JetStandardClasses.isFunctionType(calleeType)) { - checkTypesWithNoCallee(trace, scope, call); +// checkTypesWithNoCallee(trace, scope, call); if (!ErrorUtils.isErrorType(calleeType)) { trace.report(CALLEE_NOT_A_FUNCTION.on(calleeExpression, calleeType)); } - return null; + return checkArgumentTypesAndFail(trace, scope, call); } FunctionDescriptorImpl functionDescriptor = new ExpressionAsFunctionDescriptor(scope.getContainingDeclaration(), "[for expression " + calleeExpression.getText() + "]"); @@ -209,33 +205,32 @@ public class CallResolver { functionReference = new JetFakeReference(calleeExpression); } else { - checkTypesWithNoCallee(trace, scope, call); - return null; +// checkTypesWithNoCallee(trace, scope, call); + return checkArgumentTypesAndFail(trace, scope, call); } } return resolveCallToDescriptor(trace, scope, call, expectedType, prioritizedTasks, functionReference); } - private FunctionDescriptor checkArgumentTypesAndFail(BindingTrace trace, JetScope scope, Call call) { + private OverloadResolutionResults checkArgumentTypesAndFail(BindingTrace trace, JetScope scope, Call call) { checkTypesWithNoCallee(trace, scope, call); - return null; + return OverloadResolutionResultsImpl.nameNotFound(); } - @Nullable - private D resolveCallToDescriptor( + @NotNull + private OverloadResolutionResults resolveCallToDescriptor( @NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull final Call call, @NotNull JetType expectedType, @NotNull final List> prioritizedTasks, // high to low priority @NotNull final JetReferenceExpression reference) { - ResolvedCallImpl resolvedCall = doResolveCall(trace, scope, call, expectedType, prioritizedTasks, reference); - return resolvedCall == null ? null : resolvedCall.getResultingDescriptor(); + return doResolveCall(trace, scope, call, expectedType, prioritizedTasks, reference); } - @Nullable - private ResolvedCallImpl doResolveCall( + @NotNull + private OverloadResolutionResults doResolveCall( @NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull final Call call, @@ -379,9 +374,9 @@ public class CallResolver { if (results.isSuccess()) { temporaryTrace.commit(); - debugInfo.set(ResolutionDebugInfo.RESULT, results.getResult()); + debugInfo.set(ResolutionDebugInfo.RESULT, results.getResultingCall()); - return results.getResult(); + return results; } if (traceForFirstNonemptyCandidateSet == null && !task.getCandidates().isEmpty()) { traceForFirstNonemptyCandidateSet = temporaryTrace; @@ -390,18 +385,16 @@ public class CallResolver { } if (traceForFirstNonemptyCandidateSet != null) { traceForFirstNonemptyCandidateSet.commit(); - if (resultsForFirstNonemptyCandidateSet.singleDescriptor()) { + if (resultsForFirstNonemptyCandidateSet.singleResult()) { - debugInfo.set(ResolutionDebugInfo.RESULT, resultsForFirstNonemptyCandidateSet.getResult()); - - return resultsForFirstNonemptyCandidateSet.getResult(); + debugInfo.set(ResolutionDebugInfo.RESULT, resultsForFirstNonemptyCandidateSet.getResultingCall()); } } else { trace.report(UNRESOLVED_REFERENCE.on(reference)); checkTypesWithNoCallee(trace, scope, call); } - return null; + return resultsForFirstNonemptyCandidateSet != null ? resultsForFirstNonemptyCandidateSet : OverloadResolutionResultsImpl.nameNotFound(); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -594,7 +587,7 @@ public class CallResolver { } OverloadResolutionResultsImpl results = computeResultAndReportErrors(trace, tracing, successfulCandidates, failedCandidates); - if (!results.singleDescriptor()) { + if (!results.singleResult()) { checkTypesWithNoCallee(trace, scope, task.getCall()); } return results; @@ -752,10 +745,10 @@ public class CallResolver { if (results.isAmbiguity()) { // This check is needed for the following case: // x.foo(unresolved) -- if there are multiple foo's, we'd report an ambiguity, and it does not make sense here - if (allClean(results.getResults())) { - tracing.ambiguity(trace, results.getResults()); + if (allClean(results.getResultingCalls())) { + tracing.ambiguity(trace, results.getResultingCalls()); } - tracing.recordAmbiguity(trace, results.getResults()); + tracing.recordAmbiguity(trace, results.getResultingCalls()); } return results; } @@ -774,13 +767,13 @@ public class CallResolver { if (!thisLevel.isEmpty()) { OverloadResolutionResultsImpl results = chooseAndReportMaximallySpecific(thisLevel, false); if (results.isSuccess()) { - results.getResult().getTrace().commit(); - return OverloadResolutionResultsImpl.singleFailedCandidate(results.getResult()); + results.getResultingCall().getTrace().commit(); + return OverloadResolutionResultsImpl.singleFailedCandidate(results.getResultingCall()); } - tracing.noneApplicable(trace, results.getResults()); - tracing.recordAmbiguity(trace, results.getResults()); - return OverloadResolutionResultsImpl.manyFailedCandidates(results.getResults()); + tracing.noneApplicable(trace, results.getResultingCalls()); + tracing.recordAmbiguity(trace, results.getResultingCalls()); + return OverloadResolutionResultsImpl.manyFailedCandidates(results.getResultingCalls()); } } assert false : "Should not be reachable, cause every status must belong to some level"; @@ -848,7 +841,7 @@ public class CallResolver { } } - public void checkGenericBoundsInAFunctionCall(List jetTypeArguments, List typeArguments, CallableDescriptor functionDescriptor, BindingTrace trace) { + private void checkGenericBoundsInAFunctionCall(List jetTypeArguments, List typeArguments, CallableDescriptor functionDescriptor, BindingTrace trace) { Map context = Maps.newHashMap(); List typeParameters = functionDescriptor.getOriginal().getTypeParameters(); @@ -868,7 +861,7 @@ public class CallResolver { } @NotNull - public OverloadResolutionResultsImpl resolveExactSignature(@NotNull JetScope scope, @NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List parameterTypes) { + public OverloadResolutionResults resolveExactSignature(@NotNull JetScope scope, @NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List parameterTypes) { List> result = findCandidatesByExactSignature(scope, receiver, name, parameterTypes); BindingTraceContext trace = new BindingTraceContext(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResults.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResults.java index 9525accd886..83cd6084ccd 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResults.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResults.java @@ -28,17 +28,20 @@ public interface OverloadResolutionResults { } @NotNull - Collection> getResults(); + Collection> getResultingCalls(); @NotNull - ResolvedCall getResult(); + ResolvedCall getResultingCall(); + + @NotNull + D getResultingDescriptor(); @NotNull Code getResultCode(); boolean isSuccess(); - boolean singleDescriptor(); + boolean singleResult(); boolean isNothing(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResultsImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResultsImpl.java index 577c365b694..7225aa2ce39 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResultsImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResultsImpl.java @@ -9,7 +9,7 @@ import java.util.Collections; /** * @author abreslav */ -public class OverloadResolutionResultsImpl implements OverloadResolutionResults { +/*package*/ class OverloadResolutionResultsImpl implements OverloadResolutionResults { public static OverloadResolutionResultsImpl success(@NotNull ResolvedCallImpl descriptor) { return new OverloadResolutionResultsImpl(Code.SUCCESS, Collections.singleton(descriptor)); @@ -40,17 +40,23 @@ public class OverloadResolutionResultsImpl impleme @Override @NotNull - public Collection> getResults() { + public Collection> getResultingCalls() { return results; } @Override @NotNull - public ResolvedCallImpl getResult() { - assert singleDescriptor(); + public ResolvedCallImpl getResultingCall() { + assert singleResult(); return results.iterator().next(); } + @NotNull + @Override + public D getResultingDescriptor() { + return getResultingCall().getResultingDescriptor(); + } + @Override @NotNull public Code getResultCode() { @@ -63,7 +69,7 @@ public class OverloadResolutionResultsImpl impleme } @Override - public boolean singleDescriptor() { + public boolean singleResult() { return isSuccess() || resultCode == Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java index f3600ca8c13..94096c3e154 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -13,10 +13,10 @@ import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.calls.CallMaker; -import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; +import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; -import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResultsImpl; import org.jetbrains.jet.lang.resolve.constants.*; +import org.jetbrains.jet.lang.resolve.constants.StringValue; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver; @@ -30,7 +30,8 @@ import org.jetbrains.jet.lexer.JetTokens; import java.util.*; import static org.jetbrains.jet.lang.diagnostics.Errors.*; -import static org.jetbrains.jet.lang.resolve.BindingContext.*; +import static org.jetbrains.jet.lang.resolve.BindingContext.INDEXED_LVALUE_GET; +import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER; import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE; import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.*; @@ -584,10 +585,10 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) selectorExpression; TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace); - VariableDescriptor variableDescriptor = context.replaceBindingTrace(temporaryTrace).resolveSimpleProperty(receiver, callOperationNode, nameExpression); - if (variableDescriptor != null) { + OverloadResolutionResults variableDescriptor = context.replaceBindingTrace(temporaryTrace).resolveSimpleProperty(receiver, callOperationNode, nameExpression); + if (variableDescriptor.isSuccess()) { temporaryTrace.commit(); - return variableDescriptor.getOutType(); + return variableDescriptor.getResultingDescriptor().getOutType(); } ExpressionTypingContext newContext = receiver.exists() ? context.replaceScope(receiver.getType().getMemberScope()) : context; JetType jetType = lookupNamespaceOrClassObject(nameExpression, nameExpression.getReferencedName(), newContext); @@ -645,13 +646,13 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { ExpressionReceiver receiver = getExpressionReceiver(facade, baseExpression, context.replaceExpectedType(NO_EXPECTED_TYPE).replaceScope(context.scope)); if (receiver == null) return null; - FunctionDescriptor functionDescriptor = context.resolveCallWithGivenNameToDescriptor( + OverloadResolutionResults functionDescriptor = context.resolveCallWithGivenNameToDescriptor( CallMaker.makeCall(receiver, expression), expression.getOperationReference(), name); - if (functionDescriptor == null) return null; - JetType returnType = functionDescriptor.getReturnType(); + if (!functionDescriptor.isSuccess()) return null; + JetType returnType = functionDescriptor.getResultingDescriptor().getReturnType(); JetType result; if (operationType == JetTokens.PLUSPLUS || operationType == JetTokens.MINUSMINUS) { if (context.semanticServices.getTypeChecker().isSubtypeOf(returnType, JetStandardClasses.getUnitType())) { @@ -740,11 +741,11 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { String name = "equals"; if (right != null) { ExpressionReceiver receiver = ExpressionTypingUtils.safeGetExpressionReceiver(facade, left, context.replaceScope(context.scope)); - OverloadResolutionResultsImpl resolutionResults = context.resolveExactSignature( + OverloadResolutionResults resolutionResults = context.resolveExactSignature( receiver, "equals", Collections.singletonList(JetStandardClasses.getNullableAnyType())); if (resolutionResults.isSuccess()) { - FunctionDescriptor equals = resolutionResults.getResult().getResultingDescriptor(); + FunctionDescriptor equals = resolutionResults.getResultingCall().getResultingDescriptor(); context.trace.record(REFERENCE_TARGET, operationSign, equals); if (ensureBooleanResult(operationSign, name, equals.getReturnType(), context)) { ensureNonemptyIntersectionOfOperandTypes(expression, context); @@ -752,7 +753,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } else { if (resolutionResults.isAmbiguity()) { - context.trace.report(OVERLOAD_RESOLUTION_AMBIGUITY.on(operationSign, resolutionResults.getResults())); + context.trace.report(OVERLOAD_RESOLUTION_AMBIGUITY.on(operationSign, resolutionResults.getResultingCalls())); } else { context.trace.report(EQUALS_MISSING.on(operationSign)); @@ -812,11 +813,11 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { public void checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @NotNull JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context) { String name = "contains"; ExpressionReceiver receiver = safeGetExpressionReceiver(facade, right, context.replaceExpectedType(NO_EXPECTED_TYPE)); - FunctionDescriptor functionDescriptor = context.resolveCallWithGivenNameToDescriptor( + OverloadResolutionResults functionDescriptor = context.resolveCallWithGivenNameToDescriptor( CallMaker.makeCallWithExpressions(callElement, receiver, null, operationSign, Collections.singletonList(left)), operationSign, name); - JetType containsType = functionDescriptor != null ? functionDescriptor.getReturnType() : null; + JetType containsType = functionDescriptor.isSuccess() ? functionDescriptor.getResultingDescriptor().getReturnType() : null; ensureBooleanResult(operationSign, name, containsType, context); } @@ -860,14 +861,14 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { ExpressionReceiver receiver = getExpressionReceiver(facade, arrayExpression, context.replaceScope(context.scope)); if (receiver != null) { - ResolvedCall resolvedCall = context.resolveCallWithGivenName( + OverloadResolutionResults results = context.resolveCallWithGivenName( CallMaker.makeCallWithExpressions(expression, receiver, null, expression, expression.getIndexExpressions()), expression, "get" ); - if (resolvedCall != null) { - context.trace.record(INDEXED_LVALUE_GET, expression, resolvedCall); - return DataFlowUtils.checkType(resolvedCall.getResultingDescriptor().getReturnType(), expression, contextWithExpectedType); + if (results.isSuccess()) { + context.trace.record(INDEXED_LVALUE_GET, expression, results.getResultingCall()); + return DataFlowUtils.checkType(results.getResultingDescriptor().getReturnType(), expression, contextWithExpectedType); } } return null; @@ -876,13 +877,13 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { @Nullable public JetType getTypeForBinaryCall(JetScope scope, String name, ExpressionTypingContext context, JetBinaryExpression binaryExpression) { ExpressionReceiver receiver = safeGetExpressionReceiver(facade, binaryExpression.getLeft(), context.replaceScope(scope)); - FunctionDescriptor functionDescriptor = context.replaceScope(scope).resolveCallWithGivenNameToDescriptor( + OverloadResolutionResults results = context.replaceScope(scope).resolveCallWithGivenNameToDescriptor( CallMaker.makeCall(receiver, binaryExpression), binaryExpression.getOperationReference(), name ); - if (functionDescriptor != null) { - return functionDescriptor.getReturnType(); + if (results.isSuccess()) { + return results.getResultingDescriptor().getReturnType(); } return null; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java index 059baf138fe..4ba03453c46 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java @@ -10,8 +10,8 @@ import org.jetbrains.jet.lang.diagnostics.Errors; 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.calls.OverloadResolutionResultsImpl; import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope; @@ -258,9 +258,9 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { @Nullable private JetType checkIterableConvention(@NotNull ExpressionReceiver loopRange, ExpressionTypingContext context) { JetExpression loopRangeExpression = loopRange.getExpression(); - OverloadResolutionResultsImpl iteratorResolutionResults = context.resolveExactSignature(loopRange, "iterator", Collections.emptyList()); + OverloadResolutionResults iteratorResolutionResults = context.resolveExactSignature(loopRange, "iterator", Collections.emptyList()); if (iteratorResolutionResults.isSuccess()) { - FunctionDescriptor iteratorFunction = iteratorResolutionResults.getResult().getResultingDescriptor(); + FunctionDescriptor iteratorFunction = iteratorResolutionResults.getResultingCall().getResultingDescriptor(); context.trace.record(LOOP_RANGE_ITERATOR, loopRangeExpression, iteratorFunction); @@ -280,13 +280,13 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { context.trace.record(LOOP_RANGE_HAS_NEXT, loopRange.getExpression(), hasNextFunctionSupported ? hasNextFunction : hasNextProperty); } - OverloadResolutionResultsImpl nextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "next", Collections.emptyList()); + OverloadResolutionResults nextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "next", Collections.emptyList()); if (nextResolutionResults.isAmbiguity()) { context.trace.report(NEXT_AMBIGUITY.on(loopRangeExpression)); } else if (nextResolutionResults.isNothing()) { context.trace.report(NEXT_MISSING.on(loopRangeExpression)); } else { - FunctionDescriptor nextFunction = nextResolutionResults.getResult().getResultingDescriptor(); + FunctionDescriptor nextFunction = nextResolutionResults.getResultingCall().getResultingDescriptor(); context.trace.record(LOOP_RANGE_NEXT, loopRange.getExpression(), nextFunction); return nextFunction.getReturnType(); } @@ -294,11 +294,11 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { else { if (iteratorResolutionResults.isAmbiguity()) { // StringBuffer stringBuffer = new StringBuffer("Method 'iterator()' is ambiguous for this expression: "); -// for (FunctionDescriptor functionDescriptor : iteratorResolutionResults.getResults()) { +// for (FunctionDescriptor functionDescriptor : iteratorResolutionResults.getResultingCalls()) { // stringBuffer.append(DescriptorRenderer.TEXT.render(functionDescriptor)).append(" "); // } // errorMessage = stringBuffer.toString(); - context.trace.report(ITERATOR_AMBIGUITY.on(loopRangeExpression, iteratorResolutionResults.getResults())); + context.trace.report(ITERATOR_AMBIGUITY.on(loopRangeExpression, iteratorResolutionResults.getResultingCalls())); } else { context.trace.report(ITERATOR_MISSING.on(loopRangeExpression)); @@ -309,19 +309,19 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { @Nullable private FunctionDescriptor checkHasNextFunctionSupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, ExpressionTypingContext context) { - OverloadResolutionResultsImpl hasNextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "hasNext", Collections.emptyList()); + OverloadResolutionResults hasNextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "hasNext", Collections.emptyList()); if (hasNextResolutionResults.isAmbiguity()) { context.trace.report(HAS_NEXT_FUNCTION_AMBIGUITY.on(loopRange)); } else if (hasNextResolutionResults.isNothing()) { return null; } else { assert hasNextResolutionResults.isSuccess(); - JetType hasNextReturnType = hasNextResolutionResults.getResult().getResultingDescriptor().getReturnType(); + JetType hasNextReturnType = hasNextResolutionResults.getResultingDescriptor().getReturnType(); if (!isBoolean(context.semanticServices, hasNextReturnType)) { context.trace.report(HAS_NEXT_FUNCTION_TYPE_MISMATCH.on(loopRange, hasNextReturnType)); } } - return hasNextResolutionResults.getResult().getResultingDescriptor(); + return hasNextResolutionResults.getResultingCall().getResultingDescriptor(); } @Nullable diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java index 3219126fdce..a6116fc2852 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java @@ -10,10 +10,7 @@ import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.TypeResolver; -import org.jetbrains.jet.lang.resolve.calls.CallMaker; -import org.jetbrains.jet.lang.resolve.calls.CallResolver; -import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResultsImpl; -import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; +import org.jetbrains.jet.lang.resolve.calls.*; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver; import org.jetbrains.jet.lang.resolve.scopes.JetScope; @@ -173,30 +170,31 @@ import java.util.Map; ////////// Call resolution utilities - @Nullable - public ResolvedCall resolveCallWithGivenName(@NotNull Call call, @NotNull JetReferenceExpression functionReference, @NotNull String name) { + @NotNull + public OverloadResolutionResults resolveCallWithGivenName(@NotNull Call call, @NotNull JetReferenceExpression functionReference, @NotNull String name) { return getCallResolver().resolveCallWithGivenName(trace, scope, call, functionReference, name, expectedType); } - @Nullable - public FunctionDescriptor resolveCallWithGivenNameToDescriptor(@NotNull Call call, @NotNull JetReferenceExpression functionReference, @NotNull String name) { - ResolvedCall resolvedCall = resolveCallWithGivenName(call, functionReference, name); - return resolvedCall == null ? null : resolvedCall.getResultingDescriptor(); + @NotNull + public OverloadResolutionResults resolveCallWithGivenNameToDescriptor(@NotNull Call call, @NotNull JetReferenceExpression functionReference, @NotNull String name) { + return resolveCallWithGivenName(call, functionReference, name); +// return results == null ? null : results.getResultingDescriptor(); } @Nullable public JetType resolveCall(@NotNull ReceiverDescriptor receiver, @Nullable ASTNode callOperationNode, @NotNull JetCallExpression callExpression) { - return getCallResolver().resolveCall(trace, scope, CallMaker.makeCall(receiver, callOperationNode, callExpression), expectedType); + OverloadResolutionResults results = getCallResolver().resolveCall(trace, scope, CallMaker.makeCall(receiver, callOperationNode, callExpression), expectedType); + return results.singleResult() ? results.getResultingDescriptor().getReturnType() : null; } - @Nullable - public VariableDescriptor resolveSimpleProperty(@NotNull ReceiverDescriptor receiver, @Nullable ASTNode callOperationNode, @NotNull JetSimpleNameExpression nameExpression) { + @NotNull + public OverloadResolutionResults resolveSimpleProperty(@NotNull ReceiverDescriptor receiver, @Nullable ASTNode callOperationNode, @NotNull JetSimpleNameExpression nameExpression) { Call call = CallMaker.makePropertyCall(receiver, callOperationNode, nameExpression); return getCallResolver().resolveSimpleProperty(trace, scope, call, expectedType); } @NotNull - public OverloadResolutionResultsImpl resolveExactSignature(@NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List parameterTypes) { + public OverloadResolutionResults resolveExactSignature(@NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List parameterTypes) { return getCallResolver().resolveExactSignature(scope, receiver, name, parameterTypes); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java index 56ce116c9df..2bd86462462 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorForStatements.java @@ -11,7 +11,7 @@ import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace; import org.jetbrains.jet.lang.resolve.TopDownAnalyzer; import org.jetbrains.jet.lang.resolve.calls.CallMaker; -import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; +import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; @@ -223,14 +223,14 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito if (receiver == null) return null; Call call = CallMaker.makeArraySetCall(receiver, arrayAccessExpression, rightHandSide); - ResolvedCall setFunctionCall = context.replaceScope(scope).replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).resolveCallWithGivenName( + OverloadResolutionResults setFunctionResults = context.replaceScope(scope).replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).resolveCallWithGivenName( call, arrayAccessExpression, "set"); - if (setFunctionCall == null) return null; - FunctionDescriptor setFunctionDescriptor = setFunctionCall.getResultingDescriptor(); + if (!setFunctionResults.isSuccess()) return null; + FunctionDescriptor setFunctionDescriptor = setFunctionResults.getResultingDescriptor(); - context.trace.record(INDEXED_LVALUE_SET, arrayAccessExpression, setFunctionCall); + context.trace.record(INDEXED_LVALUE_SET, arrayAccessExpression, setFunctionResults.getResultingCall()); // if (getterNeeded) { // ResolvedCall getFunctionCall = context.replaceScope(scope).replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).resolveCallWithGivenName( diff --git a/compiler/testData/diagnostics/tests/FunctionCalleeExpressions.jet b/compiler/testData/diagnostics/tests/FunctionCalleeExpressions.jet index 7e36dc38033..852e49c45fe 100644 --- a/compiler/testData/diagnostics/tests/FunctionCalleeExpressions.jet +++ b/compiler/testData/diagnostics/tests/FunctionCalleeExpressions.jet @@ -42,7 +42,7 @@ fun main(args : Array) { val b = fooT2()(1) b : Int - fooT2()(1) // : Any? + fooT2()(1) // : Any? 1() 1{} diff --git a/compiler/testData/diagnostics/tests/inference/NoInferenceFromDeclaredBounds.jet b/compiler/testData/diagnostics/tests/inference/NoInferenceFromDeclaredBounds.jet index 4436d18abf9..4ee535aae1f 100644 --- a/compiler/testData/diagnostics/tests/inference/NoInferenceFromDeclaredBounds.jet +++ b/compiler/testData/diagnostics/tests/inference/NoInferenceFromDeclaredBounds.jet @@ -1,9 +1,9 @@ -fun fooT2() : fun(t : T) : T { - return {it} +fun fooT22() : T? { + return null +} + +fun foo1() { + fooT22() } val n : Nothing = null.sure() - -fun test() { - fooT2()(1) -} diff --git a/compiler/tests/org/jetbrains/jet/resolve/JetResolveTest.java b/compiler/tests/org/jetbrains/jet/resolve/JetResolveTest.java index d8139d4ebd1..cca4e1ee90d 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/JetResolveTest.java +++ b/compiler/tests/org/jetbrains/jet/resolve/JetResolveTest.java @@ -16,8 +16,8 @@ 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.resolve.calls.CallResolver; -import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResultsImpl; -import org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl; +import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults; +import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.JetStandardLibrary; @@ -113,9 +113,9 @@ public class JetResolveTest extends ExtensibleResolveTestCase { // JetTypeInferrer.Services typeInferrerServices = JetSemanticServices.createSemanticServices(getProject()).getTypeInferrerServices(new BindingTraceContext()); CallResolver callResolver = new CallResolver(JetSemanticServices.createSemanticServices(getProject()), DataFlowInfo.EMPTY); - OverloadResolutionResultsImpl functions = callResolver.resolveExactSignature( + OverloadResolutionResults functions = callResolver.resolveExactSignature( classDescriptor.getMemberScope(typeArguments), ReceiverDescriptor.NO_RECEIVER, name, parameterTypeList); - for (ResolvedCallImpl resolvedCall : functions.getResults()) { + for (ResolvedCall resolvedCall : functions.getResultingCalls()) { List unsubstitutedValueParameters = resolvedCall.getResultingDescriptor().getValueParameters(); for (int i = 0, unsubstitutedValueParametersSize = unsubstitutedValueParameters.size(); i < unsubstitutedValueParametersSize; i++) { ValueParameterDescriptor unsubstitutedValueParameter = unsubstitutedValueParameters.get(i); From af3b6783aba353703c109ed56eed166ce6c2aec1 Mon Sep 17 00:00:00 2001 From: svtk Date: Wed, 14 Dec 2011 16:59:53 +0400 Subject: [PATCH 09/33] KT-830 Action "Copy Current File As Diagnostic Test" doesn't works correctly --- .../jet/checkers/CheckerTestUtil.java | 40 ++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/checkers/CheckerTestUtil.java b/compiler/frontend/src/org/jetbrains/jet/checkers/CheckerTestUtil.java index d002d67284d..0eba8704826 100644 --- a/compiler/frontend/src/org/jetbrains/jet/checkers/CheckerTestUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/checkers/CheckerTestUtil.java @@ -1,12 +1,15 @@ package org.jetbrains.jet.checkers; +import com.google.common.base.Predicate; import com.google.common.collect.*; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory; +import org.jetbrains.jet.lang.diagnostics.DiagnosticWithTextRange; import org.jetbrains.jet.lang.diagnostics.Severity; import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -41,7 +44,7 @@ public class CheckerTestUtil { ArrayList diagnostics = new ArrayList(); diagnostics.addAll(bindingContext.getDiagnostics()); for (TextRange textRange : AnalyzingUtils.getSyntaxErrorRanges(root)) { - diagnostics.add(new SyntaxErrorDiagnostic(textRange)); + diagnostics.add(new SyntaxErrorDiagnostic(textRange, root.getContainingFile())); } return diagnostics; } @@ -176,15 +179,22 @@ public class CheckerTestUtil { Collection diagnostics = new ArrayList(); diagnostics.addAll(bindingContext.getDiagnostics()); for (TextRange syntaxError : syntaxErrors) { - diagnostics.add(new SyntaxErrorDiagnostic(syntaxError)); + diagnostics.add(new SyntaxErrorDiagnostic(syntaxError, psiFile)); } return addDiagnosticMarkersToText(psiFile, diagnostics); } - public static StringBuffer addDiagnosticMarkersToText(PsiFile psiFile, Collection diagnostics) { + public static StringBuffer addDiagnosticMarkersToText(@NotNull final PsiFile psiFile, Collection diagnostics) { StringBuffer result = new StringBuffer(); String text = psiFile.getText(); + diagnostics = Collections2.filter(diagnostics, new Predicate() { + @Override + public boolean apply(@Nullable Diagnostic diagnostic) { + if (diagnostic == null || !psiFile.equals(diagnostic.getFactory().getPsiFile(diagnostic))) return false; + return true; + } + }); if (!diagnostics.isEmpty()) { List diagnosticDescriptors = getSortedDiagnosticDescriptors(diagnostics); @@ -265,7 +275,7 @@ public class CheckerTestUtil { @NotNull @Override public PsiFile getPsiFile(@NotNull Diagnostic diagnostic) { - throw new IllegalStateException(); + return ((SyntaxErrorDiagnostic)diagnostic).getPsiFile(); } @NotNull @@ -275,12 +285,14 @@ public class CheckerTestUtil { } } - public static class SyntaxErrorDiagnostic implements Diagnostic { + public static class SyntaxErrorDiagnostic implements DiagnosticWithTextRange { private final TextRange textRange; + private final PsiFile psiFile; - public SyntaxErrorDiagnostic(TextRange textRange) { + public SyntaxErrorDiagnostic(@NotNull TextRange textRange, @NotNull PsiFile psiFile) { this.textRange = textRange; + this.psiFile = psiFile; } @NotNull @@ -300,6 +312,18 @@ public class CheckerTestUtil { public Severity getSeverity() { throw new IllegalStateException(); } + + @NotNull + @Override + public TextRange getTextRange() { + return textRange; + } + + @NotNull + @Override + public PsiFile getPsiFile() { + return psiFile; + } } private static List getSortedDiagnosticDescriptors(Collection diagnostics) { @@ -308,9 +332,7 @@ public class CheckerTestUtil { List diagnosticDescriptors = Lists.newArrayList(); DiagnosticDescriptor currentDiagnosticDescriptor = null; - for (Iterator iterator = list.iterator(); iterator.hasNext(); ) { - Diagnostic diagnostic = iterator.next(); - + for (Diagnostic diagnostic : list) { TextRange textRange = getTextRange(diagnostic); if (currentDiagnosticDescriptor != null && currentDiagnosticDescriptor.equalRange(textRange)) { currentDiagnosticDescriptor.diagnostics.add(diagnostic); From 2e92e056873037eb4e5af776b1b4f04f9ee84103 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Wed, 14 Dec 2011 15:06:54 +0200 Subject: [PATCH 10/33] tests for KT-828 (fromm Sergey Ignatov) --- compiler/testData/codegen/regressions/kt828.kt | 15 +++++++++++++++ .../testData/diagnostics/tests/library/kt828.jet | 12 ++++++++++++ .../org/jetbrains/jet/codegen/StdlibTest.java | 4 ++++ 3 files changed, 31 insertions(+) create mode 100644 compiler/testData/codegen/regressions/kt828.kt create mode 100644 compiler/testData/diagnostics/tests/library/kt828.jet diff --git a/compiler/testData/codegen/regressions/kt828.kt b/compiler/testData/codegen/regressions/kt828.kt new file mode 100644 index 00000000000..34801b54b8d --- /dev/null +++ b/compiler/testData/codegen/regressions/kt828.kt @@ -0,0 +1,15 @@ +namespace demo + +fun box() : String { + var res : Boolean = true + res = (res and false) + res = (res or false) + res = (res xor false) + res = (true and false) + res = (true or false) + res = (true xor false) + res = (!true) + res = (true && false) + res = (true || false) + return "OK" +} diff --git a/compiler/testData/diagnostics/tests/library/kt828.jet b/compiler/testData/diagnostics/tests/library/kt828.jet new file mode 100644 index 00000000000..2b14c81a02c --- /dev/null +++ b/compiler/testData/diagnostics/tests/library/kt828.jet @@ -0,0 +1,12 @@ +fun test() { + var res : Boolean = true + res = (res and false) + res = (res or false) + res = (res xor false) + res = (true and false) + res = (true or false) + res = (true xor false) + res = (!true) + res = (true && false) + res = (true || false) +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java b/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java index da0d87d46fc..6c26a8833ee 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/StdlibTest.java @@ -84,6 +84,10 @@ public class StdlibTest extends CodegenTestCase { // blackBoxFile("regressions/kt789.jet"); } + public void testKt828 () { + blackBoxFile("regressions/kt828.kt"); + } + public void testCollectionSize () throws Exception { loadText("import std.util.*; fun box() = if(java.util.Arrays.asList(0, 1, 2)?.size == 3) \"OK\" else \"fail\""); // System.out.println(generateToText()); From 268081df733a48d120abaf31409fc628b003fae5 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 14 Dec 2011 17:18:19 +0400 Subject: [PATCH 11/33] Unmappable character removed --- .../jetbrains/jet/lang/resolve/calls/inference/TypeValue.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/TypeValue.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/TypeValue.java index 48d6e24c57e..4768036b4b7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/TypeValue.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/TypeValue.java @@ -18,7 +18,7 @@ public class TypeValue implements BoundsOwner { private final Variance positionVariance; private final TypeParameterDescriptor typeParameterDescriptor; // Null for known types private final JetType originalType; - private JetType value; // For an unknown — the value found by constraint resolution, for a known — just it's value + private JetType value; // For an unknown - the value found by constraint resolution, for a known - just it's value // Unknown type public TypeValue(@NotNull TypeParameterDescriptor typeParameterDescriptor, @NotNull Variance positionVariance) { From 9a100cad44b8d4f775e546695045b1b978a7613a Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Wed, 14 Dec 2011 17:42:52 +0400 Subject: [PATCH 12/33] synchronizing my and Alex' signature writers and readers --- .../jet/codegen/BothSignatureWriter.java | 5 +++-- .../org/jetbrains/jet/codegen/JetTypeMapper.java | 2 +- .../org/jetbrains/jet/codegen/SignatureUtil.java | 1 - .../resolve/java/JetTypeJetSignatureReader.java | 2 +- .../java/signature/JetSignatureAdapter.java | 4 +++- .../java/signature/JetSignatureReader.java | 14 +++++++++++++- .../java/signature/JetSignatureVisitor.java | 3 ++- .../java/signature/JetSignatureWriter.java | 15 ++++++++++++++- stdlib/src/jet/typeinfo/TypeInfo.java | 4 ---- 9 files changed, 37 insertions(+), 13 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java b/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java index ab2d5de350d..df828641deb 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java @@ -5,6 +5,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.resolve.java.signature.JetSignatureAdapter; import org.jetbrains.jet.lang.resolve.java.signature.JetSignatureReader; import org.jetbrains.jet.lang.resolve.java.signature.JetSignatureWriter; +import org.jetbrains.jet.lang.types.Variance; import org.objectweb.asm.Type; import org.objectweb.asm.signature.SignatureVisitor; import org.objectweb.asm.signature.SignatureWriter; @@ -182,11 +183,11 @@ public class BothSignatureWriter { jetSignatureWriter.visitTypeVariable(name, nullable); } - public void writeFormalTypeParameter(final String name) { + public void writeFormalTypeParameter(final String name, Variance variance) { checkTopLevel(); signatureVisitor().visitFormalTypeParameter(name); - jetSignatureWriter.visitFormalTypeParameter(name); + jetSignatureWriter.visitFormalTypeParameter(name, variance); } public void writerFormalTypeParametersStart() { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 58a60e131b6..45344286ed0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -540,7 +540,7 @@ public class JetTypeMapper { } private void writeFormalTypeParameter(TypeParameterDescriptor typeParameterDescriptor, BothSignatureWriter signatureVisitor) { - signatureVisitor.writeFormalTypeParameter(typeParameterDescriptor.getName()); + signatureVisitor.writeFormalTypeParameter(typeParameterDescriptor.getName(), typeParameterDescriptor.getVariance()); classBound: { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/SignatureUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/SignatureUtil.java index 2903242169c..392037c636e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/SignatureUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/SignatureUtil.java @@ -73,7 +73,6 @@ public class SignatureUtil { } sb.append('<'); for(JetTypeParameter param : parameters) { - sb.append("T"); Variance variance = param.getVariance(); if(variance == Variance.IN_VARIANCE) sb.append("in "); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java index 0e0819d8f7a..69f5e4b1444 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java @@ -34,7 +34,7 @@ public abstract class JetTypeJetSignatureReader implements JetSignatureVisitor { @Override - public void visitFormalTypeParameter(String name) { + public void visitFormalTypeParameter(String name, Variance variance) { throw new IllegalStateException(); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureAdapter.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureAdapter.java index 5f9d10245b0..a1c62a009ff 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureAdapter.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureAdapter.java @@ -1,11 +1,13 @@ package org.jetbrains.jet.lang.resolve.java.signature; +import org.jetbrains.jet.lang.types.Variance; + /** * @author Stepan Koltsov */ public class JetSignatureAdapter implements JetSignatureVisitor { @Override - public void visitFormalTypeParameter(String name) { + public void visitFormalTypeParameter(String name, Variance variance) { } @Override diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureReader.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureReader.java index cbdebb01b3a..f4c78b26a44 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureReader.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureReader.java @@ -1,5 +1,6 @@ package org.jetbrains.jet.lang.resolve.java.signature; +import org.jetbrains.jet.lang.types.Variance; import org.objectweb.asm.signature.SignatureReader; import org.objectweb.asm.signature.SignatureVisitor; @@ -26,8 +27,19 @@ public class JetSignatureReader { if (signature.charAt(0) == '<') { pos = 2; do { + Variance variance; + if (signature.substring(pos).startsWith("in ")) { + variance = Variance.IN_VARIANCE; + pos += "in ".length(); + } else if (signature.substring(pos).startsWith("out ")) { + variance = Variance.OUT_VARIANCE; + pos += "out ".length(); + } else { + variance = Variance.INVARIANT; + pos += "".length(); + } int end = signature.indexOf(':', pos); - v.visitFormalTypeParameter(signature.substring(pos - 1, end)); + v.visitFormalTypeParameter(signature.substring(pos - 1, end), variance); pos = end + 1; c = signature.charAt(pos); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureVisitor.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureVisitor.java index e353dd6dbb3..6995d8b7e86 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureVisitor.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureVisitor.java @@ -1,5 +1,6 @@ package org.jetbrains.jet.lang.resolve.java.signature; +import org.jetbrains.jet.lang.types.Variance; import org.objectweb.asm.signature.SignatureVisitor; /** @@ -30,7 +31,7 @@ public interface JetSignatureVisitor { * * @param name the name of the formal parameter. */ - void visitFormalTypeParameter(String name); + void visitFormalTypeParameter(String name, Variance variance); /** * Visits the class bound of the last visited formal type parameter. diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureWriter.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureWriter.java index 7e1a7837a08..4755613ff2f 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureWriter.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureWriter.java @@ -1,5 +1,6 @@ package org.jetbrains.jet.lang.resolve.java.signature; +import org.jetbrains.jet.lang.types.Variance; import org.objectweb.asm.signature.SignatureWriter; /** @@ -43,11 +44,23 @@ public class JetSignatureWriter implements JetSignatureVisitor { // ------------------------------------------------------------------------ @Override - public void visitFormalTypeParameter(final String name) { + public void visitFormalTypeParameter(final String name, Variance variance) { if (!hasFormals) { hasFormals = true; buf.append('<'); } + switch (variance) { + case OUT_VARIANCE: + buf.append("out "); + break; + case IN_VARIANCE: + buf.append("in "); + break; + case INVARIANT: + break; + default: + throw new IllegalStateException(); + } buf.append(name); buf.append(':'); } diff --git a/stdlib/src/jet/typeinfo/TypeInfo.java b/stdlib/src/jet/typeinfo/TypeInfo.java index dfdda4e367e..925cb84d745 100644 --- a/stdlib/src/jet/typeinfo/TypeInfo.java +++ b/stdlib/src/jet/typeinfo/TypeInfo.java @@ -543,10 +543,6 @@ public abstract class TypeInfo implements JetObject { signature.variables = new LinkedList(); signature.varNames = new HashMap(); } - if (string[cur] != 'T') { - throw new IllegalStateException(new String(string)); - } - cur++; signature.variables.add(parseVar(signature)); } cur++; From 6277c4c0fa43436f883f33cbc47560e8158e9b77 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Wed, 14 Dec 2011 19:07:39 +0400 Subject: [PATCH 13/33] make frontend.java module dependent on stdlib --- compiler/frontend.java/frontend.java.iml | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/frontend.java/frontend.java.iml b/compiler/frontend.java/frontend.java.iml index ec086b20ffc..51021970c69 100644 --- a/compiler/frontend.java/frontend.java.iml +++ b/compiler/frontend.java/frontend.java.iml @@ -8,6 +8,7 @@ + From 526538788b45cf106258063f3f89e2360846f010 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Wed, 14 Dec 2011 19:07:49 +0400 Subject: [PATCH 14/33] move jet signature read/write utils into stdlib module --- .../jet/codegen/BothSignatureWriter.java | 18 ++++++++++++++---- .../lang/resolve/java/JavaTypeTransformer.java | 3 +-- .../java/JetTypeJetSignatureReader.java | 7 +++---- .../signature/JetSignatureAdapter.java | 6 +++--- .../signature/JetSignatureReader.java | 14 ++++++-------- .../signature/JetSignatureVisitor.java | 7 +++---- .../signature/JetSignatureWriter.java | 11 +++++------ 7 files changed, 35 insertions(+), 31 deletions(-) rename {compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java => stdlib/src/jet/typeinfo/internal}/signature/JetSignatureAdapter.java (89%) rename {compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java => stdlib/src/jet/typeinfo/internal}/signature/JetSignatureReader.java (93%) rename {compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java => stdlib/src/jet/typeinfo/internal}/signature/JetSignatureVisitor.java (94%) rename {compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java => stdlib/src/jet/typeinfo/internal}/signature/JetSignatureWriter.java (94%) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java b/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java index df828641deb..153765f12d0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java @@ -1,10 +1,11 @@ package org.jetbrains.jet.codegen; +import jet.typeinfo.TypeInfoVariance; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.resolve.java.signature.JetSignatureAdapter; -import org.jetbrains.jet.lang.resolve.java.signature.JetSignatureReader; -import org.jetbrains.jet.lang.resolve.java.signature.JetSignatureWriter; +import jet.typeinfo.internal.signature.JetSignatureAdapter; +import jet.typeinfo.internal.signature.JetSignatureReader; +import jet.typeinfo.internal.signature.JetSignatureWriter; import org.jetbrains.jet.lang.types.Variance; import org.objectweb.asm.Type; import org.objectweb.asm.signature.SignatureVisitor; @@ -183,11 +184,20 @@ public class BothSignatureWriter { jetSignatureWriter.visitTypeVariable(name, nullable); } + private TypeInfoVariance translateVariance(Variance variance) { + switch (variance) { + case IN_VARIANCE: return TypeInfoVariance.IN; + case OUT_VARIANCE: return TypeInfoVariance.OUT; + case INVARIANT: return TypeInfoVariance.INVARIANT; + default: throw new IllegalStateException(); + } + } + public void writeFormalTypeParameter(final String name, Variance variance) { checkTopLevel(); signatureVisitor().visitFormalTypeParameter(name); - jetSignatureWriter.visitFormalTypeParameter(name, variance); + jetSignatureWriter.visitFormalTypeParameter(name, translateVariance(variance)); } public void writerFormalTypeParametersStart() { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java index 82d25433ac1..fd74d3d4d1e 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java @@ -2,12 +2,11 @@ package org.jetbrains.jet.lang.resolve.java; import com.google.common.collect.Lists; import com.intellij.psi.*; +import jet.typeinfo.internal.signature.JetSignatureReader; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; -import org.jetbrains.jet.lang.resolve.java.signature.JetSignatureReader; -import org.jetbrains.jet.lang.resolve.java.signature.JetSignatureVisitor; import org.jetbrains.jet.lang.types.*; import java.util.Collections; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java index 69f5e4b1444..7694f3eb8a2 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java @@ -1,11 +1,10 @@ package org.jetbrains.jet.lang.resolve.java; +import jet.typeinfo.TypeInfoVariance; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; -import org.jetbrains.jet.lang.resolve.java.signature.JetSignatureReader; -import org.jetbrains.jet.lang.resolve.java.signature.JetSignatureVisitor; -import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import jet.typeinfo.internal.signature.JetSignatureVisitor; import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetStandardClasses; import org.jetbrains.jet.lang.types.JetStandardLibrary; @@ -34,7 +33,7 @@ public abstract class JetTypeJetSignatureReader implements JetSignatureVisitor { @Override - public void visitFormalTypeParameter(String name, Variance variance) { + public void visitFormalTypeParameter(String name, TypeInfoVariance variance) { throw new IllegalStateException(); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureAdapter.java b/stdlib/src/jet/typeinfo/internal/signature/JetSignatureAdapter.java similarity index 89% rename from compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureAdapter.java rename to stdlib/src/jet/typeinfo/internal/signature/JetSignatureAdapter.java index a1c62a009ff..8e229360bc4 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureAdapter.java +++ b/stdlib/src/jet/typeinfo/internal/signature/JetSignatureAdapter.java @@ -1,13 +1,13 @@ -package org.jetbrains.jet.lang.resolve.java.signature; +package jet.typeinfo.internal.signature; -import org.jetbrains.jet.lang.types.Variance; +import jet.typeinfo.TypeInfoVariance; /** * @author Stepan Koltsov */ public class JetSignatureAdapter implements JetSignatureVisitor { @Override - public void visitFormalTypeParameter(String name, Variance variance) { + public void visitFormalTypeParameter(String name, TypeInfoVariance variance) { } @Override diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureReader.java b/stdlib/src/jet/typeinfo/internal/signature/JetSignatureReader.java similarity index 93% rename from compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureReader.java rename to stdlib/src/jet/typeinfo/internal/signature/JetSignatureReader.java index f4c78b26a44..3922801bbee 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureReader.java +++ b/stdlib/src/jet/typeinfo/internal/signature/JetSignatureReader.java @@ -1,8 +1,6 @@ -package org.jetbrains.jet.lang.resolve.java.signature; +package jet.typeinfo.internal.signature; -import org.jetbrains.jet.lang.types.Variance; -import org.objectweb.asm.signature.SignatureReader; -import org.objectweb.asm.signature.SignatureVisitor; +import jet.typeinfo.TypeInfoVariance; /** * @author Stepan Koltsov @@ -27,15 +25,15 @@ public class JetSignatureReader { if (signature.charAt(0) == '<') { pos = 2; do { - Variance variance; + TypeInfoVariance variance; if (signature.substring(pos).startsWith("in ")) { - variance = Variance.IN_VARIANCE; + variance = TypeInfoVariance.IN; pos += "in ".length(); } else if (signature.substring(pos).startsWith("out ")) { - variance = Variance.OUT_VARIANCE; + variance = TypeInfoVariance.OUT; pos += "out ".length(); } else { - variance = Variance.INVARIANT; + variance = TypeInfoVariance.INVARIANT; pos += "".length(); } int end = signature.indexOf(':', pos); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureVisitor.java b/stdlib/src/jet/typeinfo/internal/signature/JetSignatureVisitor.java similarity index 94% rename from compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureVisitor.java rename to stdlib/src/jet/typeinfo/internal/signature/JetSignatureVisitor.java index 6995d8b7e86..4aa667d515a 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureVisitor.java +++ b/stdlib/src/jet/typeinfo/internal/signature/JetSignatureVisitor.java @@ -1,7 +1,6 @@ -package org.jetbrains.jet.lang.resolve.java.signature; +package jet.typeinfo.internal.signature; -import org.jetbrains.jet.lang.types.Variance; -import org.objectweb.asm.signature.SignatureVisitor; +import jet.typeinfo.TypeInfoVariance; /** * @author Stepan Koltsov @@ -31,7 +30,7 @@ public interface JetSignatureVisitor { * * @param name the name of the formal parameter. */ - void visitFormalTypeParameter(String name, Variance variance); + void visitFormalTypeParameter(String name, TypeInfoVariance variance); /** * Visits the class bound of the last visited formal type parameter. diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureWriter.java b/stdlib/src/jet/typeinfo/internal/signature/JetSignatureWriter.java similarity index 94% rename from compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureWriter.java rename to stdlib/src/jet/typeinfo/internal/signature/JetSignatureWriter.java index 4755613ff2f..3ac43dba3fd 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/signature/JetSignatureWriter.java +++ b/stdlib/src/jet/typeinfo/internal/signature/JetSignatureWriter.java @@ -1,7 +1,6 @@ -package org.jetbrains.jet.lang.resolve.java.signature; +package jet.typeinfo.internal.signature; -import org.jetbrains.jet.lang.types.Variance; -import org.objectweb.asm.signature.SignatureWriter; +import jet.typeinfo.TypeInfoVariance; /** * @author Stepan Koltsov @@ -44,16 +43,16 @@ public class JetSignatureWriter implements JetSignatureVisitor { // ------------------------------------------------------------------------ @Override - public void visitFormalTypeParameter(final String name, Variance variance) { + public void visitFormalTypeParameter(final String name, TypeInfoVariance variance) { if (!hasFormals) { hasFormals = true; buf.append('<'); } switch (variance) { - case OUT_VARIANCE: + case OUT: buf.append("out "); break; - case IN_VARIANCE: + case IN: buf.append("in "); break; case INVARIANT: From 7a909ff4b95559eab31bfb5b6ad0094e3ac95f19 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Wed, 14 Dec 2011 22:30:30 +0400 Subject: [PATCH 15/33] commit missing tests --- compiler/testData/readClass/FunClassParamNotNull.kt | 5 +++++ compiler/testData/readClass/FunClassParamNullable.kt | 5 +++++ compiler/testData/readClass/ReturnTypeClassParamNotNull.kt | 6 ++++++ compiler/testData/readClass/ReturnTypeClassParamNullable.kt | 6 ++++++ 4 files changed, 22 insertions(+) create mode 100644 compiler/testData/readClass/FunClassParamNotNull.kt create mode 100644 compiler/testData/readClass/FunClassParamNullable.kt create mode 100644 compiler/testData/readClass/ReturnTypeClassParamNotNull.kt create mode 100644 compiler/testData/readClass/ReturnTypeClassParamNullable.kt diff --git a/compiler/testData/readClass/FunClassParamNotNull.kt b/compiler/testData/readClass/FunClassParamNotNull.kt new file mode 100644 index 00000000000..5dd2abe1afb --- /dev/null +++ b/compiler/testData/readClass/FunClassParamNotNull.kt @@ -0,0 +1,5 @@ +namespace test + +import java.util.List + +fun ff(p: List) = 1 diff --git a/compiler/testData/readClass/FunClassParamNullable.kt b/compiler/testData/readClass/FunClassParamNullable.kt new file mode 100644 index 00000000000..fafa4387a77 --- /dev/null +++ b/compiler/testData/readClass/FunClassParamNullable.kt @@ -0,0 +1,5 @@ +namespace test + +import java.util.List + +fun ff(p: List) = 1 diff --git a/compiler/testData/readClass/ReturnTypeClassParamNotNull.kt b/compiler/testData/readClass/ReturnTypeClassParamNotNull.kt new file mode 100644 index 00000000000..90e394a811a --- /dev/null +++ b/compiler/testData/readClass/ReturnTypeClassParamNotNull.kt @@ -0,0 +1,6 @@ +namespace test + +import java.util.List +import java.util.ArrayList + +fun ffgg(): List = ArrayList() diff --git a/compiler/testData/readClass/ReturnTypeClassParamNullable.kt b/compiler/testData/readClass/ReturnTypeClassParamNullable.kt new file mode 100644 index 00000000000..447be6bbfaa --- /dev/null +++ b/compiler/testData/readClass/ReturnTypeClassParamNullable.kt @@ -0,0 +1,6 @@ +namespace test + +import java.util.List +import java.util.ArrayList + +fun ffgg(): List = ArrayList() From 7ddfa09be0c1741427808e5a170234610de2f34e Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Wed, 14 Dec 2011 22:30:34 +0400 Subject: [PATCH 16/33] merge Alex' work with mine, move internal classes to internal subpackage --- .../jet/codegen/BothSignatureWriter.java | 23 +- .../codegen/ImplementationBodyCodegen.java | 5 +- .../jetbrains/jet/codegen/SignatureUtil.java | 86 --- .../java/JetTypeJetSignatureReader.java | 65 +- stdlib/src/jet/typeinfo/JetSignature.java | 2 +- stdlib/src/jet/typeinfo/TypeInfo.java | 643 +----------------- .../src/jet/typeinfo/TypeInfoProjection.java | 34 - .../src/jet/typeinfo/internal/Signature.java | 60 ++ .../jet/typeinfo/internal/TypeInfoImpl.java | 229 +++++++ .../jet/typeinfo/internal/TypeInfoParser.java | 281 ++++++++ .../internal/TypeInfoProjectionImpl.java | 46 ++ .../jet/typeinfo/internal/TypeInfoUtils.java | 40 ++ .../jet/typeinfo/internal/TypeInfoVar.java | 89 +++ .../JetSignatureExceptionsAdapter.java | 88 +++ .../signature/JetSignatureReader.java | 80 ++- 15 files changed, 922 insertions(+), 849 deletions(-) delete mode 100644 compiler/backend/src/org/jetbrains/jet/codegen/SignatureUtil.java create mode 100644 stdlib/src/jet/typeinfo/internal/Signature.java create mode 100644 stdlib/src/jet/typeinfo/internal/TypeInfoImpl.java create mode 100644 stdlib/src/jet/typeinfo/internal/TypeInfoParser.java create mode 100644 stdlib/src/jet/typeinfo/internal/TypeInfoProjectionImpl.java create mode 100644 stdlib/src/jet/typeinfo/internal/TypeInfoUtils.java create mode 100644 stdlib/src/jet/typeinfo/internal/TypeInfoVar.java create mode 100644 stdlib/src/jet/typeinfo/internal/signature/JetSignatureExceptionsAdapter.java diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java b/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java index 153765f12d0..8fcbabac1ac 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java @@ -52,6 +52,7 @@ public class BothSignatureWriter { private JetSignatureWriter jetSignatureWriter; + private String kotlinClassParameters; private String kotlinClassSignature; private List kotlinParameterTypes = new ArrayList(); @@ -207,7 +208,16 @@ public class BothSignatureWriter { } public void writeFormalTypeParametersEnd() { + jetSignatureWriter.visitSuperclass(); // just to call endFormals + + kotlinClassParameters = jetSignatureWriter.toString(); + jetSignatureWriter = null; + + if (DEBUG_SIGNATURE_WRITER) { + new JetSignatureReader(kotlinClassParameters).acceptFormalTypeParametersOnly(new JetSignatureAdapter()); + } + checkState(State.TYPE_PARAMETERS); } @@ -285,6 +295,11 @@ public class BothSignatureWriter { public void writeSupersEnd() { kotlinClassSignature = jetSignatureWriter.toString(); jetSignatureWriter = null; + + if (DEBUG_SIGNATURE_WRITER) { + new JetSignatureReader(kotlinClassSignature).accept(new JetSignatureAdapter()); + } + transitionState(State.SUPERS, State.CLASS_END); } @@ -344,7 +359,13 @@ public class BothSignatureWriter { @Nullable public String makeKotlinClassSignature() { checkState(State.CLASS_END); - return kotlinClassSignature; + if (kotlinClassParameters == null) { + throw new IllegalStateException(); + } + if (kotlinClassSignature == null) { + throw new IllegalStateException(); + } + return kotlinClassParameters + kotlinClassSignature; } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index cd89380cbf5..da2066e7623 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -71,9 +71,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { v.visitOuterClass(typeMapper.mapType(((ClassDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), null, null); } - if(myClass instanceof JetClass) { + if(myClass instanceof JetClass && signature.getKotlinGenericSignature() != null) { AnnotationVisitor annotationVisitor = v.newAnnotation(myClass, "Ljet/typeinfo/JetSignature;", true); - annotationVisitor.visit("value", SignatureUtil.classToSignature((JetClass)myClass, bindingContext, typeMapper)); + //annotationVisitor.visit("value", SignatureUtil.classToSignature((JetClass)myClass, bindingContext, typeMapper)); + annotationVisitor.visit("value", signature.getKotlinGenericSignature()); annotationVisitor.visitEnd(); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/SignatureUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/SignatureUtil.java deleted file mode 100644 index 392037c636e..00000000000 --- a/compiler/backend/src/org/jetbrains/jet/codegen/SignatureUtil.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.jetbrains.jet.codegen; - -import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; -import org.jetbrains.jet.lang.psi.JetClass; -import org.jetbrains.jet.lang.psi.JetDelegationSpecifier; -import org.jetbrains.jet.lang.psi.JetTypeParameter; -import org.jetbrains.jet.lang.psi.JetTypeReference; -import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.jet.lang.types.TypeProjection; -import org.jetbrains.jet.lang.types.Variance; -import org.objectweb.asm.Type; - -import java.util.List; - -/** - * @author alex.tkachman - */ -public class SignatureUtil { - private SignatureUtil() { - } - - public static String classToSignature(JetClass type, BindingContext bindingContext, JetTypeMapper typeMapper) { - StringBuilder sb = new StringBuilder(); - genTypeParams(type, sb); - List delegationSpecifiers = type.getDelegationSpecifiers(); - for (JetDelegationSpecifier specifier : delegationSpecifiers) { - JetTypeReference typeReference = specifier.getTypeReference(); - JetType jetType = bindingContext.get(BindingContext.TYPE, typeReference); - genJetType(sb, jetType, typeMapper); - } - return sb.toString(); - } - - private static void genJetType(StringBuilder sb, JetType jetType, JetTypeMapper typeMapper) { - DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor(); - if(descriptor instanceof ClassDescriptor) { - JetType defaultType = ((ClassDescriptor) descriptor).getDefaultType(); - Type type = typeMapper.mapType(defaultType, OwnerKind.IMPLEMENTATION); - if(JetTypeMapper.isPrimitive(type)) { - type = JetTypeMapper.boxType(type); - } - sb.append(type.getDescriptor()); - } - else { - sb.append("T"); - JetType defaultType = ((ClassDescriptor) descriptor.getContainingDeclaration()).getDefaultType(); - Type type = typeMapper.mapType(defaultType, OwnerKind.IMPLEMENTATION); - sb.append(type.getDescriptor()); - sb.append(descriptor.getName()); - sb.append(";"); - } - if(!jetType.getArguments().isEmpty()) { - sb.append("<"); - for (TypeProjection typeProjection : jetType.getArguments()) { - if(typeProjection.getProjectionKind() == Variance.IN_VARIANCE) - sb.append("in "); - if(typeProjection.getProjectionKind() == Variance.OUT_VARIANCE) - sb.append("out "); - genJetType(sb, typeProjection.getType(), typeMapper); - } - sb.append(">"); - } - if(jetType.isNullable()) - sb.append("?"); - } - - private static void genTypeParams(JetClass type, StringBuilder sb) { - List parameters = type.getTypeParameterList().getParameters(); - if (parameters.isEmpty()) { - return; - } - sb.append('<'); - for(JetTypeParameter param : parameters) { - Variance variance = param.getVariance(); - if(variance == Variance.IN_VARIANCE) - sb.append("in "); - else if(variance == Variance.OUT_VARIANCE) - sb.append("out "); - sb.append(param.getName()); - sb.append(";"); - } - sb.append('>'); - } -} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java index 7694f3eb8a2..2c190cbc956 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java @@ -1,6 +1,8 @@ package org.jetbrains.jet.lang.resolve.java; import jet.typeinfo.TypeInfoVariance; +import jet.typeinfo.internal.signature.JetSignatureAdapter; +import jet.typeinfo.internal.signature.JetSignatureExceptionsAdapter; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; @@ -20,7 +22,7 @@ import java.util.List; /** * @author Stepan Koltsov */ -public abstract class JetTypeJetSignatureReader implements JetSignatureVisitor { +public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAdapter { private final JavaDescriptorResolver javaDescriptorResolver; private final JetStandardLibrary jetStandardLibrary; @@ -31,47 +33,6 @@ public abstract class JetTypeJetSignatureReader implements JetSignatureVisitor { } - - @Override - public void visitFormalTypeParameter(String name, TypeInfoVariance variance) { - throw new IllegalStateException(); - } - - @Override - public JetSignatureVisitor visitClassBound() { - throw new IllegalStateException(); - } - - @Override - public JetSignatureVisitor visitInterfaceBound() { - throw new IllegalStateException(); - } - - @Override - public JetSignatureVisitor visitSuperclass() { - throw new IllegalStateException(); - } - - @Override - public JetSignatureVisitor visitInterface() { - throw new IllegalStateException(); - } - - @Override - public JetSignatureVisitor visitParameterType() { - throw new IllegalStateException(); - } - - @Override - public JetSignatureVisitor visitReturnType() { - throw new IllegalStateException(); - } - - @Override - public JetSignatureVisitor visitExceptionType() { - throw new IllegalStateException(); - } - private JetType getPrimitiveType(char descriptor, boolean nullable) { if (!nullable) { switch (descriptor) { @@ -124,16 +85,6 @@ public abstract class JetTypeJetSignatureReader implements JetSignatureVisitor { done(getPrimitiveType(descriptor, nullable)); } - @Override - public void visitTypeVariable(String name, boolean nullable) { - throw new IllegalStateException(); - } - - @Override - public JetSignatureVisitor visitArrayType(boolean nullable) { - throw new IllegalStateException(); - } - private ClassDescriptor classDescriptor; private boolean nullable; @@ -150,16 +101,6 @@ public abstract class JetTypeJetSignatureReader implements JetSignatureVisitor { this.typeArguments = new ArrayList(); } - @Override - public void visitInnerClassType(String name, boolean nullable) { - throw new IllegalStateException(); - } - - @Override - public void visitTypeArgument() { - throw new IllegalStateException(); - } - private static Variance parseVariance(char wildcard) { switch (wildcard) { case '=': return Variance.INVARIANT; diff --git a/stdlib/src/jet/typeinfo/JetSignature.java b/stdlib/src/jet/typeinfo/JetSignature.java index fe43b49b50d..c93f818951b 100644 --- a/stdlib/src/jet/typeinfo/JetSignature.java +++ b/stdlib/src/jet/typeinfo/JetSignature.java @@ -11,7 +11,7 @@ import java.util.*; * @url http://confluence.jetbrains.net/display/JET/Jet+Signatures */ @Retention(RetentionPolicy.RUNTIME) -@interface JetSignature { +public @interface JetSignature { String value(); } diff --git a/stdlib/src/jet/typeinfo/TypeInfo.java b/stdlib/src/jet/typeinfo/TypeInfo.java index 925cb84d745..f2bc7734534 100644 --- a/stdlib/src/jet/typeinfo/TypeInfo.java +++ b/stdlib/src/jet/typeinfo/TypeInfo.java @@ -2,12 +2,8 @@ package jet.typeinfo; import jet.JetObject; import jet.Tuple0; - -import java.lang.reflect.Array; -import java.lang.reflect.Field; -import java.lang.reflect.TypeVariable; -import java.util.*; -import java.util.concurrent.locks.ReentrantReadWriteLock; +import jet.typeinfo.internal.TypeInfoImpl; +import jet.typeinfo.internal.TypeInfoProjectionImpl; /** * @author abreslav @@ -15,7 +11,6 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; * @author alex.tkachman */ public abstract class TypeInfo implements JetObject { - private final static TypeInfoProjection[] EMPTY = new TypeInfoProjection[0]; public static final TypeInfo BYTE_TYPE_INFO = getTypeInfo(Byte.class, false); public static final TypeInfo SHORT_TYPE_INFO = getTypeInfo(Short.class, false); @@ -56,7 +51,7 @@ public abstract class TypeInfo implements JetObject { } public static TypeInfoProjection inProjection(TypeInfo typeInfo) { - return new TypeInfoProjection.TypeInfoProjectionImpl(typeInfo) { + return new TypeInfoProjectionImpl(typeInfo) { // @NotNull @Override public TypeInfoVariance getVariance() { @@ -66,7 +61,7 @@ public abstract class TypeInfo implements JetObject { } public static TypeInfoProjection outProjection(TypeInfo typeInfo) { - return new TypeInfoProjection.TypeInfoProjectionImpl(typeInfo) { + return new TypeInfoProjectionImpl(typeInfo) { // @NotNull @Override public TypeInfoVariance getVariance() { @@ -75,6 +70,15 @@ public abstract class TypeInfo implements JetObject { }; } + private static TypeInfoProjection projection(TypeInfo typeInfo, TypeInfoVariance variance) { + switch (variance) { + case IN: return inProjection(typeInfo); + case OUT: return outProjection(typeInfo); + case INVARIANT: return invariantProjection(typeInfo); + default: throw new IllegalStateException(); + } + } + public static TypeInfo getTypeInfo(Class klazz, boolean nullable) { return new TypeInfoImpl(klazz, nullable); } @@ -94,626 +98,5 @@ public abstract class TypeInfo implements JetObject { public abstract TypeInfoProjection getProjection(int index); public abstract TypeInfo getArgumentType(Class klass, int index); - - protected abstract TypeInfo substitute(List myVars); - protected abstract TypeInfo substitute(TypeInfoProjection[] projections); - - private static class TypeInfoVar extends TypeInfo { - final int varIndex; - final Signature signature; - final boolean nullable; - - private TypeInfoVar(Signature signature, Integer varIndex) { - this.signature = signature; - this.varIndex = varIndex; - nullable = false; - } - - public TypeInfoVar(Signature signature, boolean nullable, int varIndex) { - this.signature = signature; - this.nullable = nullable; - this.varIndex = varIndex; - } - - @Override - public Object[] newArray(int length) { - throw new UnsupportedOperationException(); - } - - @Override - public Class getJavaClass() { - throw new UnsupportedOperationException(); - } - - @Override - public Object getClassObject() { - throw new UnsupportedOperationException("Abstract TypeInfo"); - } - - @Override - public boolean isInstance(Object obj) { - throw new UnsupportedOperationException("Abstract TypeInfo"); - } - - @Override - public int getProjectionCount() { - return 0; - } - - @Override - public TypeInfoProjection getProjection(int index) { - throw new UnsupportedOperationException("Abstract TypeInfo"); - } - - @Override - public TypeInfo getArgumentType(Class klass, int index) { - throw new UnsupportedOperationException("Abstract TypeInfo"); - } - - @Override - public TypeInfo substitute(List myVars) { - return myVars.get(varIndex); - } - - @Override - protected TypeInfo substitute(TypeInfoProjection[] projections) { - return projections[varIndex].getType(); - } - - @Override - public TypeInfo getTypeInfo() { - throw new UnsupportedOperationException("Abstract TypeInfo"); - } - - @Override - public JetObject getOuterObject() { - return null; - } - - @Override - public String toString() { - return "T:" + signature.klazz.getName() + ":" + varIndex; - } - } - - private static class TypeInfoImpl extends TypeInfo implements TypeInfoProjection { - private TypeInfo typeInfo; - private final Signature signature; - private final boolean nullable; - private final TypeInfoProjection[] projections; - - private TypeInfoImpl(Class theClass, boolean nullable) { - this(theClass, nullable, EMPTY); - } - - private TypeInfoImpl(Class theClass, boolean nullable, TypeInfoProjection[] projections) { - this.signature = Parser.parse(theClass); - this.nullable = nullable; - this.projections = projections; - if(signature.variables.size() != projections.length) - throw new IllegalStateException("Wrong signature " + theClass.getName()); - } - - public final TypeInfoProjection getProjection(int index) { - return projections[index]; - } - - @Override - public Object[] newArray(int length) { - return (Object[]) Array.newInstance(signature.klazz, length); - } - - @Override - public Class getJavaClass() { - return signature.klazz; - } - - public final Object getClassObject() { - try { - final Class implClass = signature.klazz.getClassLoader().loadClass(signature.klazz.getCanonicalName()); - final Field classobj = implClass.getField("$classobj"); - return classobj.get(null); - } catch (Exception e) { - return null; - } - } - - TypeInfo getSuperTypeInfo(Class klass) { - return signature.superSignatures.get(klass); - } - - public final TypeInfo getArgumentType(Class klass, int index) { - if(klass == this.signature.klazz) - return projections[index].getType(); - else { - return getSuperTypeInfo(klass).substitute(projections).getArgumentType(klass, index); - } - } - - @Override - public TypeInfo substitute(final List myVars) { - if(projections.length == 0) - return new TypeInfoImpl(this.signature.klazz, nullable, EMPTY); - else { - TypeInfoProjection [] proj = new TypeInfoProjection[projections.length]; - for(int i = 0; i != proj.length; ++i) { - final int finalI = i; - final TypeInfo substitute = projections[finalI].getType().substitute(myVars); - proj[i] = new TypeInfoProjection(){ - - @Override - public TypeInfoVariance getVariance() { - return projections[finalI].getVariance(); - } - - @Override - public TypeInfo getType() { - return substitute; - } - - @Override - public String toString() { - return getVariance().toString() + " " + substitute; - } - }; - } - return new TypeInfoImpl(this.signature.klazz, nullable, proj); - } - } - - @Override - protected TypeInfo substitute(TypeInfoProjection[] prj) { - if(projections.length == 0) - return new TypeInfoImpl(signature.klazz, nullable, EMPTY); - else { - TypeInfoProjection [] proj = new TypeInfoProjection[projections.length]; - for(int i = 0; i != proj.length; ++i) { - final int finalI = i; - final TypeInfo substitute = projections[finalI].getType().substitute(prj); - proj[i] = new TypeInfoProjection(){ - - @Override - public TypeInfoVariance getVariance() { - return projections[finalI].getVariance(); - } - - @Override - public TypeInfo getType() { - return substitute; - } - - @Override - public String toString() { - return getVariance().toString() + " " + substitute; - } - }; - } - return new TypeInfoImpl(signature.klazz, nullable, proj); - } - } - - @Override - public final boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - TypeInfoImpl typeInfo = (TypeInfoImpl) o; - - if (!signature.klazz.equals(typeInfo.signature.klazz)) return false; - if (nullable != typeInfo.nullable) return false; - if (!Arrays.equals(projections, typeInfo.projections)) return false; - - return true; - } - -// @NotNull - @Override - public TypeInfoVariance getVariance() { - return TypeInfoVariance.INVARIANT; - } - -// @NotNull - @Override - public TypeInfo getType() { - return this; - } - - @Override - public final int hashCode() { - return 31 * signature.klazz.hashCode() + Arrays.hashCode(projections); - } - - public final boolean isInstance(Object obj) { - if (obj == null) return nullable; - - if (obj instanceof JetObject) { - return ((TypeInfoImpl)((JetObject) obj).getTypeInfo()).isSubtypeOf(this); - } - - return signature.klazz.isAssignableFrom(obj.getClass()); // TODO - } - - @Override - public int getProjectionCount() { - return projections.length; - } - - @Override - public final String toString() { - StringBuilder sb = new StringBuilder().append(signature.klazz.getName()); - if (projections.length != 0) { - sb.append("<"); - for (int i = 0; i != projections.length - 1; ++i) { - sb.append(projections[i].toString()).append(","); - } - sb.append(projections[projections.length - 1].toString()).append(">"); - } - if (nullable) - sb.append("?"); - return sb.toString(); - } - - @Override - public final TypeInfo getTypeInfo() { - if (typeInfo == null) { - // TODO: Implementation must be lazy, otherwise the result would be of an infinite size - throw new UnsupportedOperationException(); // TODO - } - return typeInfo; - } - - @Override - public JetObject getOuterObject() { - return null; - } - - public final boolean isSubtypeOf(TypeInfoImpl superType) { - if (nullable && !superType.nullable) { - return false; - } - if (!superType.signature.klazz.isAssignableFrom(signature.klazz)) { - return false; - } - if (superType.projections == null || superType.projections.length != projections.length) { - throw new IllegalArgumentException("inconsistent type info for the same class"); - } - for (int i = 0; i < projections.length; i++) { - // TODO handle variance here - if (!projections[i].getType().equals(superType.projections[i].getType())) { - return false; - } - } - return true; - } - - } - - public static class Signature { - final Class klazz; - - List variables; - Map varNames; - List superTypes; - - final HashMap superSignatures = new HashMap(); - - public Signature(Class klazz) { - this.klazz = klazz; - } - - protected void afterParse() { - List myVars = variables == null ? Collections.emptyList() : new LinkedList(); - if(variables != null) - for(int i = 0; i != variables.size(); ++i) - myVars.add(new TypeInfoVar(this, false, i)); - - for(TypeInfo superType : superTypes) { - if(superType instanceof TypeInfoImpl) { - TypeInfoImpl type = (TypeInfoImpl) superType; - Signature superSignature = Parser.parse(type.signature.klazz); - - TypeInfo substituted = type.substitute(myVars); - superSignatures.put(type.signature.klazz, substituted); - - List vars = Collections.emptyList(); - if(superType.getProjectionCount() != 0) { - vars = new LinkedList(); - for(int i=0; i != superType.getProjectionCount(); ++i) { - TypeInfo substitute = superType.getProjection(i).getType().substitute(myVars); - vars.add(substitute); - } - } - - for(Map.Entry entry : superSignature.superSignatures.entrySet()) { - superSignatures.put(entry.getKey(), entry.getValue().substitute(vars)); - } - } - } - } - } - - public static class Parser { - static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); - static final WeakHashMap map = new WeakHashMap(); - - int cur; - final char [] string; - - final ClassLoader classLoader; - - Parser(String string, ClassLoader classLoader) { - this.classLoader = classLoader; - this.string = string.toCharArray(); - } - - public static Signature parse(Class klass) { - if(klass == null) - return null; - -// lock.readLock().lock(); - Signature sig = map.get(klass); -// lock.readLock().unlock(); - if (sig == null) { -// lock.writeLock().lock(); - - sig = map.get(klass); - if (sig == null) { - sig = internalParse(klass); - } - -// lock.writeLock().unlock(); - } - return sig; - } - - private static Signature internalParse(Class klass) { - if(klass.isArray() && !klass.getComponentType().isPrimitive()) { - Signature signature = new ArraySignature(klass); - map.put(klass, signature); - return signature; - } - - JetSignature annotation = (JetSignature) klass.getAnnotation(JetSignature.class); - if(annotation != null) { - String value = annotation.value(); - if(value != null) { - Parser parser = new Parser(value, klass.getClassLoader()); - Class enclosingClass = klass.getEnclosingClass(); - Signature signature = new Signature(klass); - map.put(klass, signature); - parser.parseVars(signature); - parser.parseTypes(signature); - signature.afterParse(); - return signature; - } - } - return getGenericSignature(klass); - } - - private static Signature getGenericSignature(Class klass) { - // todo complete impl - - java.lang.reflect.Type genericSuperclass = klass.getGenericSuperclass(); - Signature signature = new Signature(klass); - - TypeVariable[] typeParameters = klass.getTypeParameters(); - if(typeParameters == null || typeParameters.length == 0) { - signature.varNames = Collections.emptyMap(); - signature.variables = Collections.emptyList(); - } - else { - signature.varNames = new HashMap(); - signature.variables = new LinkedList(); - } - - if (typeParameters != null && typeParameters.length != 0) { - for (int i = 0; i < typeParameters.length; i++) { - TypeVariable typeParameter = typeParameters[i]; - signature.varNames.put(typeParameter.getName(), i); - final TypeInfoVar typeInfoVar = new TypeInfoVar(signature, false, i); - signature.variables.add(new TypeInfoProjection(){ - - @Override - public TypeInfoVariance getVariance() { - return TypeInfoVariance.INVARIANT; - } - - @Override - public TypeInfo getType() { - return typeInfoVar; - } - - @Override - public String toString() { - return typeInfoVar.toString(); - } - }); - } - } - - return signature; - } - - public void parseVars(Signature signature) { - if (cur < string.length && string[cur] == '<') { - cur++; - while(cur < string.length && string[cur] != '>') { - if(signature.variables == null) { - signature.variables = new LinkedList(); - signature.varNames = new HashMap(); - } - signature.variables.add(parseVar(signature)); - } - cur++; - } - signature.variables = signature.variables == null ? Collections.emptyList() : signature.variables; - signature.varNames = signature.varNames == null ? Collections.emptyMap() : signature.varNames; - } - - private TypeInfoProjection parseVar(Signature signature) { - final TypeInfoVariance variance = parseVariance(); - String name = parseName(); - final TypeInfoVar typeInfoVar = new TypeInfoVar(signature, signature.variables.size()); - signature.varNames.put(name, signature.variables.size()); - return new TypeInfoProjection(){ - @Override - public TypeInfoVariance getVariance() { - return variance; - } - - @Override - public TypeInfo getType() { - return typeInfoVar; - } - - @Override - public String toString() { - return typeInfoVar.toString(); - } - }; - } - - private String parseName() { - int c = cur; - while (string[c] != ';') { - c++; - } - String name = new String(string, cur, c - cur); - cur = c+1; - return name; - } - - private TypeInfoVariance parseVariance() { - if(string[cur] == 'i' && string[cur+1] == 'n' && string[cur+2] == ' ' ) { - cur += 3; - return TypeInfoVariance.IN; - } - else if (string[cur] == 'o' && string[cur+1] == 'u' && string[cur+2] == 't' && string[cur+3] == ' ') { - cur += 4; - return TypeInfoVariance.OUT; - } - else { - return TypeInfoVariance.INVARIANT; - } - } - - public void parseTypes(Signature signature) { - List types = null; - while(cur != string.length) { - if(types == null) { - types = new LinkedList(); - } - types.add(parseType(signature)); - } - signature.superTypes = types == null ? Collections.emptyList() : types; - } - - private TypeInfo parseType(Signature signature) { - switch (string[cur]) { - case 'L': - cur++; - String name = parseName(); - Class aClass; - try { - aClass = classLoader.loadClass(name.replace('/','.')); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } - List proj = null; - boolean nullable = false; - if(cur != string.length && string[cur] == '<') { - cur++; - while(string[cur] != '>') { - if(proj == null) - proj = new LinkedList(); - proj.add(parseProjection(signature)); - } - cur++; - } - if(cur != string.length && string[cur] == '?') { - cur++; - nullable = true; - } - if(proj == null) - proj = Collections.emptyList(); - return new TypeInfoImpl(aClass, nullable,proj.toArray(new TypeInfoProjection[proj.size()])); - - case 'T': - cur++; - return parseTypeVar(signature); - - default: - throw new IllegalStateException(new String(string)); - } - } - - private TypeInfo parseTypeVar(Signature signature) { - TypeInfoVariance variance = parseVariance(); - assert string[cur] == 'L'; - cur++; - String klazz = parseName().replace('/','.'); - String name = parseName(); - boolean nullable = false; - if(string[cur] == '?') { - nullable = true; - cur++; - } - - if(klazz.equals(signature.klazz.getName())) - return new TypeInfoVar(signature, nullable, signature.varNames.get(name)); - else { -// Signature sig = signature; -// while(!klazz.equals(sig.klazz.getName())) { -// sig = sig.outer; -// if(sig == null) -// throw new IllegalStateException(); -// } - - throw new UnsupportedOperationException("outer type info does not supported"); - } - } - - private TypeInfoProjection parseProjection(Signature signature) { - final TypeInfoVariance variance = parseVariance(); - final TypeInfo type = parseType(signature); - return new TypeInfoProjection(){ - @Override - public TypeInfoVariance getVariance() { - return variance; - } - - @Override - public TypeInfo getType() { - return type; - } - - @Override - public String toString() { - return type.toString(); - } - }; - } - - private static class ArraySignature extends Signature { - public ArraySignature(Class klass) { - super(klass); - variables = new LinkedList(); - varNames = new HashMap(); - varNames.put("T", 0); - final TypeInfoVar typeInfoVar = new TypeInfoVar(this, 0); - variables.add(new TypeInfoProjection(){ - @Override - public TypeInfoVariance getVariance() { - return TypeInfoVariance.INVARIANT; - } - - @Override - public TypeInfo getType() { - return typeInfoVar; - } - }); - } - } - } } diff --git a/stdlib/src/jet/typeinfo/TypeInfoProjection.java b/stdlib/src/jet/typeinfo/TypeInfoProjection.java index 654794eb539..8f20bcd52d0 100644 --- a/stdlib/src/jet/typeinfo/TypeInfoProjection.java +++ b/stdlib/src/jet/typeinfo/TypeInfoProjection.java @@ -12,38 +12,4 @@ public interface TypeInfoProjection { TypeInfo getType(); - abstract class TypeInfoProjectionImpl implements TypeInfoProjection { - private final TypeInfo type; - - TypeInfoProjectionImpl(TypeInfo typeInfo) { - this.type = typeInfo; - } - - @Override - public final TypeInfo getType() { - return type; - } - - @Override - public final boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - TypeInfoProjectionImpl that = (TypeInfoProjectionImpl) o; - // no need to compare variance as we compared classes already - return type.equals(that.type); - } - - @Override - public final int hashCode() { - int result = type.hashCode(); - result = 31 * result + (getVariance().hashCode()); - return result; - } - - @Override - public final String toString() { - return (getVariance() == TypeInfoVariance.INVARIANT ? "" : getVariance().toString() + " ") + type; - } - } } diff --git a/stdlib/src/jet/typeinfo/internal/Signature.java b/stdlib/src/jet/typeinfo/internal/Signature.java new file mode 100644 index 00000000000..879ad3e46ae --- /dev/null +++ b/stdlib/src/jet/typeinfo/internal/Signature.java @@ -0,0 +1,60 @@ +package jet.typeinfo.internal; + +import jet.typeinfo.TypeInfo; +import jet.typeinfo.TypeInfoProjection; + +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** +* @author Stepan Koltsov +*/ +class Signature { + + // TODO: make all these fields private + + final Class klazz; + + List variables; + Map varNames; + List superTypes; + + HashMap superSignatures = new HashMap(); + + Signature(Class klazz) { + this.klazz = klazz; + } + + void afterParse() { + List myVars = variables == null ? Collections.emptyList() : new LinkedList(); + if(variables != null) + for(int i = 0; i != variables.size(); ++i) + myVars.add(new TypeInfoVar(this, false, i)); + + for(TypeInfo superType : superTypes) { + if(superType instanceof TypeInfoImpl) { + TypeInfoImpl type = (TypeInfoImpl) superType; + Signature superSignature = TypeInfoParser.parse(type.signature.klazz); + + TypeInfo substituted = TypeInfoUtils.substitute(type, myVars); + superSignatures.put(type.signature.klazz, substituted); + + List vars = Collections.emptyList(); + if(superType.getProjectionCount() != 0) { + vars = new LinkedList(); + for(int i=0; i != superType.getProjectionCount(); ++i) { + TypeInfo substitute = TypeInfoUtils.substitute(superType.getProjection(i).getType(), myVars); + vars.add(substitute); + } + } + + for(Map.Entry entry : superSignature.superSignatures.entrySet()) { + superSignatures.put(entry.getKey(), TypeInfoUtils.substitute(entry.getValue(), vars)); + } + } + } + } +} diff --git a/stdlib/src/jet/typeinfo/internal/TypeInfoImpl.java b/stdlib/src/jet/typeinfo/internal/TypeInfoImpl.java new file mode 100644 index 00000000000..fe784eb8eae --- /dev/null +++ b/stdlib/src/jet/typeinfo/internal/TypeInfoImpl.java @@ -0,0 +1,229 @@ +package jet.typeinfo.internal; + +import jet.JetObject; +import jet.typeinfo.TypeInfo; +import jet.typeinfo.TypeInfoProjection; +import jet.typeinfo.TypeInfoVariance; + +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.List; + +/** + * @author abreslav + * @author yole + * @author alex.tkachman + * @author Stepan Koltsov + */ +public class TypeInfoImpl extends TypeInfo implements TypeInfoProjection { + private final static TypeInfoProjection[] EMPTY = new TypeInfoProjection[0]; + + private TypeInfo typeInfo; + public final Signature signature; + private final boolean nullable; + private final TypeInfoProjection[] projections; + + public TypeInfoImpl(Class theClass, boolean nullable) { + this(theClass, nullable, EMPTY); + } + + public TypeInfoImpl(Class theClass, boolean nullable, TypeInfoProjection[] projections) { + this.signature = TypeInfoParser.parse(theClass); + this.nullable = nullable; + this.projections = projections; + if(signature.variables.size() != projections.length) + throw new IllegalStateException("Wrong signature " + theClass.getName()); + } + + public final TypeInfoProjection getProjection(int index) { + return projections[index]; + } + + @Override + public Object[] newArray(int length) { + return (Object[]) Array.newInstance(signature.klazz, length); + } + + @Override + public Class getJavaClass() { + return signature.klazz; + } + + public final Object getClassObject() { + try { + final Class implClass = signature.klazz.getClassLoader().loadClass(signature.klazz.getCanonicalName()); + final Field classobj = implClass.getField("$classobj"); + return classobj.get(null); + } catch (Exception e) { + return null; + } + } + + TypeInfo getSuperTypeInfo(Class klass) { + return signature.superSignatures.get(klass); + } + + public final TypeInfo getArgumentType(Class klass, int index) { + if(klass == this.signature.klazz) + return projections[index].getType(); + else { + return TypeInfoUtils.substitute(getSuperTypeInfo(klass), projections).getArgumentType(klass, index); + } + } + + TypeInfo substitute(final List myVars) { + if(projections.length == 0) + return new TypeInfoImpl(this.signature.klazz, nullable, EMPTY); + else { + TypeInfoProjection [] proj = new TypeInfoProjection[projections.length]; + for(int i = 0; i != proj.length; ++i) { + final int finalI = i; + final TypeInfo substitute = TypeInfoUtils.substitute(projections[finalI].getType(), myVars); + proj[i] = new TypeInfoProjection(){ + + @Override + public TypeInfoVariance getVariance() { + return projections[finalI].getVariance(); + } + + @Override + public TypeInfo getType() { + return substitute; + } + + @Override + public String toString() { + return getVariance().toString() + " " + substitute; + } + }; + } + return new TypeInfoImpl(this.signature.klazz, nullable, proj); + } + } + + TypeInfo substitute(TypeInfoProjection[] prj) { + if(projections.length == 0) + return new TypeInfoImpl(signature.klazz, nullable, EMPTY); + else { + TypeInfoProjection [] proj = new TypeInfoProjection[projections.length]; + for(int i = 0; i != proj.length; ++i) { + final int finalI = i; + final TypeInfo substitute = TypeInfoUtils.substitute(projections[finalI].getType(), prj); + proj[i] = new TypeInfoProjection(){ + + @Override + public TypeInfoVariance getVariance() { + return projections[finalI].getVariance(); + } + + @Override + public TypeInfo getType() { + return substitute; + } + + @Override + public String toString() { + return getVariance().toString() + " " + substitute; + } + }; + } + return new TypeInfoImpl(signature.klazz, nullable, proj); + } + } + + @Override + public final boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + TypeInfoImpl typeInfo = (TypeInfoImpl) o; + + if (!signature.klazz.equals(typeInfo.signature.klazz)) return false; + if (nullable != typeInfo.nullable) return false; + if (!Arrays.equals(projections, typeInfo.projections)) return false; + + return true; + } + +// @NotNull + @Override + public TypeInfoVariance getVariance() { + return TypeInfoVariance.INVARIANT; + } + +// @NotNull + @Override + public TypeInfo getType() { + return this; + } + + @Override + public final int hashCode() { + return 31 * signature.klazz.hashCode() + Arrays.hashCode(projections); + } + + public final boolean isInstance(Object obj) { + if (obj == null) return nullable; + + if (obj instanceof JetObject) { + return ((TypeInfoImpl)((JetObject) obj).getTypeInfo()).isSubtypeOf(this); + } + + return signature.klazz.isAssignableFrom(obj.getClass()); // TODO + } + + @Override + public int getProjectionCount() { + return projections.length; + } + + @Override + public final String toString() { + StringBuilder sb = new StringBuilder().append(signature.klazz.getName()); + if (projections.length != 0) { + sb.append("<"); + for (int i = 0; i != projections.length - 1; ++i) { + sb.append(projections[i].toString()).append(","); + } + sb.append(projections[projections.length - 1].toString()).append(">"); + } + if (nullable) + sb.append("?"); + return sb.toString(); + } + + @Override + public final TypeInfo getTypeInfo() { + if (typeInfo == null) { + // TODO: Implementation must be lazy, otherwise the result would be of an infinite size + throw new UnsupportedOperationException(); // TODO + } + return typeInfo; + } + + @Override + public JetObject getOuterObject() { + return null; + } + + public final boolean isSubtypeOf(TypeInfoImpl superType) { + if (nullable && !superType.nullable) { + return false; + } + if (!superType.signature.klazz.isAssignableFrom(signature.klazz)) { + return false; + } + if (superType.projections == null || superType.projections.length != projections.length) { + throw new IllegalArgumentException("inconsistent type info for the same class"); + } + for (int i = 0; i < projections.length; i++) { + // TODO handle variance here + if (!projections[i].getType().equals(superType.projections[i].getType())) { + return false; + } + } + return true; + } + +} diff --git a/stdlib/src/jet/typeinfo/internal/TypeInfoParser.java b/stdlib/src/jet/typeinfo/internal/TypeInfoParser.java new file mode 100644 index 00000000000..4ffdf66fc30 --- /dev/null +++ b/stdlib/src/jet/typeinfo/internal/TypeInfoParser.java @@ -0,0 +1,281 @@ +package jet.typeinfo.internal; + +import jet.typeinfo.JetSignature; +import jet.typeinfo.TypeInfo; +import jet.typeinfo.TypeInfoProjection; +import jet.typeinfo.TypeInfoVariance; +import jet.typeinfo.internal.signature.JetSignatureExceptionsAdapter; +import jet.typeinfo.internal.signature.JetSignatureReader; +import jet.typeinfo.internal.signature.JetSignatureVisitor; + +import java.lang.reflect.TypeVariable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.WeakHashMap; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** +* @author Stepan Koltsov +*/ +class TypeInfoParser { + static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + static final WeakHashMap map = new WeakHashMap(); + + public static Signature parse(Class klass) { + if(klass == null) + return null; + +// lock.readLock().lock(); + Signature sig = map.get(klass); +// lock.readLock().unlock(); + if (sig == null) { +// lock.writeLock().lock(); + + sig = map.get(klass); + if (sig == null) { + sig = internalParse(klass); + } + +// lock.writeLock().unlock(); + } + return sig; + } + + private static Signature internalParse(Class klass) { + if(klass.isArray() && !klass.getComponentType().isPrimitive()) { + Signature signature = new ArraySignature(klass); + map.put(klass, signature); + return signature; + } + + JetSignature annotation = (JetSignature) klass.getAnnotation(JetSignature.class); + if(annotation != null) { + String value = annotation.value(); + if(value != null) { + Class enclosingClass = klass.getEnclosingClass(); + Signature signature = new Signature(klass); + map.put(klass, signature); + parse(value, signature); + signature.afterParse(); + return signature; + } + } + return getGenericSignature(klass); + } + + private static void parse(String annotationValue, final Signature signature) { + signature.variables = new ArrayList(); + signature.varNames = new HashMap(); + signature.superTypes = new ArrayList(); + new JetSignatureReader(annotationValue).accept(new JetSignatureExceptionsAdapter() { + int varIndex = 0; + + @Override + public void visitFormalTypeParameter(String name, final TypeInfoVariance variance) { + + final TypeInfoVar typeInfoVar = new TypeInfoVar(signature, signature.variables.size()); + + signature.varNames.put(name, signature.variables.size()); + TypeInfoProjection typeInfoProjection = new TypeInfoProjection() { + @Override + public TypeInfoVariance getVariance() { + return variance; + } + + @Override + public TypeInfo getType() { + return typeInfoVar; + } + + @Override + public String toString() { + return typeInfoVar.toString(); + } + }; + + signature.variables.add(typeInfoProjection); + // TODO: supers + // TODO: nullability + } + + @Override + public JetSignatureVisitor visitClassBound() { + return new SignatureParserJetSignatureAdapter(signature.klazz.getClassLoader(), signature) { + @Override + protected void done(TypeInfo typeInfo) { + // TODO + } + }; + } + + @Override + public JetSignatureVisitor visitInterfaceBound() { + return new SignatureParserJetSignatureAdapter(signature.klazz.getClassLoader(), signature) { + @Override + protected void done(TypeInfo typeInfo) { + // TODO + } + }; + } + + @Override + public JetSignatureVisitor visitSuperclass() { + return new SignatureParserJetSignatureAdapter(signature.klazz.getClassLoader(), signature) { + @Override + protected void done(TypeInfo typeInfo) { + signature.superTypes.add(typeInfo); + signature.superSignatures.put(typeInfo.getJavaClass(), typeInfo); + } + }; + } + + @Override + public JetSignatureVisitor visitInterface() { + return new SignatureParserJetSignatureAdapter(signature.klazz.getClassLoader(), signature) { + @Override + protected void done(TypeInfo typeInfo) { + signature.superTypes.add(typeInfo); + signature.superSignatures.put(typeInfo.getJavaClass(), typeInfo); + } + }; + } + }); + } + + + private static abstract class SignatureParserJetSignatureAdapter extends JetSignatureExceptionsAdapter { + private final ClassLoader classLoader; + private final Signature signature; + + protected SignatureParserJetSignatureAdapter(ClassLoader classLoader, Signature signature) { + this.classLoader = classLoader; + this.signature = signature; + } + + protected abstract void done(TypeInfo typeInfo); + + private Class klass; + private boolean nullable; + private List projections; + + @Override + public void visitClassType(String name, boolean nullable) { + try { + klass = classLoader.loadClass(name.replace('/', '.')); + } catch (ClassNotFoundException e) { + throw new RuntimeException(); + } + this.nullable = nullable; + this.projections = new ArrayList(); + } + + private static TypeInfoVariance parseVariance(char wildcard) { + switch (wildcard) { + case '=': return TypeInfoVariance.INVARIANT; + case '+': return TypeInfoVariance.OUT; + case '-': return TypeInfoVariance.IN; + default: throw new IllegalStateException(); + } + } + + @Override + public JetSignatureVisitor visitTypeArgument(final char wildcard) { + final TypeInfoVariance variance = parseVariance(wildcard); + return new SignatureParserJetSignatureAdapter(classLoader, signature) { + @Override + protected void done(TypeInfo typeInfo) { + projections.add(new TypeInfoProjectionImpl(typeInfo) { + @Override + public TypeInfoVariance getVariance() { + return variance; + } + }); + } + }; + } + + @Override + public void visitTypeVariable(String name, boolean nullable) { + Integer varIndex = signature.varNames.get(name); + if (varIndex == null) { + throw new IllegalStateException("unresolved type variable: " + name); + } + TypeInfoVar typeInfo = new TypeInfoVar(signature, nullable, varIndex); + done(typeInfo); + } + + @Override + public void visitEnd() { + done(new TypeInfoImpl(klass, nullable, projections.toArray(new TypeInfoProjection[0]))); + } + } + + + private static Signature getGenericSignature(Class klass) { + // todo complete impl + + java.lang.reflect.Type genericSuperclass = klass.getGenericSuperclass(); + Signature signature = new Signature(klass); + + TypeVariable[] typeParameters = klass.getTypeParameters(); + if(typeParameters == null || typeParameters.length == 0) { + signature.varNames = Collections.emptyMap(); + signature.variables = Collections.emptyList(); + } + else { + signature.varNames = new HashMap(); + signature.variables = new LinkedList(); + } + + if (typeParameters != null && typeParameters.length != 0) { + for (int i = 0; i < typeParameters.length; i++) { + TypeVariable typeParameter = typeParameters[i]; + signature.varNames.put(typeParameter.getName(), i); + final TypeInfoVar typeInfoVar = new TypeInfoVar(signature, false, i); + signature.variables.add(new TypeInfoProjection(){ + + @Override + public TypeInfoVariance getVariance() { + return TypeInfoVariance.INVARIANT; + } + + @Override + public TypeInfo getType() { + return typeInfoVar; + } + + @Override + public String toString() { + return typeInfoVar.toString(); + } + }); + } + } + + return signature; + } + + private static class ArraySignature extends Signature { + public ArraySignature(Class klass) { + super(klass); + variables = new LinkedList(); + varNames = new HashMap(); + varNames.put("T", 0); + final TypeInfoVar typeInfoVar = new TypeInfoVar(this, 0); + variables.add(new TypeInfoProjection() { + @Override + public TypeInfoVariance getVariance() { + return TypeInfoVariance.INVARIANT; + } + + @Override + public TypeInfo getType() { + return typeInfoVar; + } + }); + } + } +} diff --git a/stdlib/src/jet/typeinfo/internal/TypeInfoProjectionImpl.java b/stdlib/src/jet/typeinfo/internal/TypeInfoProjectionImpl.java new file mode 100644 index 00000000000..94438ffbd5e --- /dev/null +++ b/stdlib/src/jet/typeinfo/internal/TypeInfoProjectionImpl.java @@ -0,0 +1,46 @@ +package jet.typeinfo.internal; + +import jet.typeinfo.TypeInfo; +import jet.typeinfo.TypeInfoProjection; +import jet.typeinfo.TypeInfoVariance; + +/** + * @author abreslav + * @author yole + * @author alex.tkachman + * @author Stepan Koltsov + */ +public abstract class TypeInfoProjectionImpl implements TypeInfoProjection { + private final TypeInfo type; + + public TypeInfoProjectionImpl(TypeInfo typeInfo) { + this.type = typeInfo; + } + + @Override + public final TypeInfo getType() { + return type; + } + + @Override + public final boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + jet.typeinfo.internal.TypeInfoProjectionImpl that = (jet.typeinfo.internal.TypeInfoProjectionImpl) o; + // no need to compare variance as we compared classes already + return type.equals(that.type); + } + + @Override + public final int hashCode() { + int result = type.hashCode(); + result = 31 * result + (getVariance().hashCode()); + return result; + } + + @Override + public final String toString() { + return (getVariance() == TypeInfoVariance.INVARIANT ? "" : getVariance().toString() + " ") + type; + } +} diff --git a/stdlib/src/jet/typeinfo/internal/TypeInfoUtils.java b/stdlib/src/jet/typeinfo/internal/TypeInfoUtils.java new file mode 100644 index 00000000000..15747bb7c74 --- /dev/null +++ b/stdlib/src/jet/typeinfo/internal/TypeInfoUtils.java @@ -0,0 +1,40 @@ +package jet.typeinfo.internal; + +import jet.typeinfo.TypeInfo; +import jet.typeinfo.TypeInfoProjection; + +import java.util.List; + +/** + * @author abreslav + * @author yole + * @author alex.tkachman + * @author Stepan Koltsov + */ +class TypeInfoUtils { + + static TypeInfo substitute(TypeInfo typeInfo, TypeInfoProjection[] projections) { + if (typeInfo instanceof TypeInfoImpl) { + TypeInfoImpl typeInfoImpl = (TypeInfoImpl) typeInfo; + return typeInfoImpl.substitute(projections); + } else if (typeInfo instanceof TypeInfoVar) { + TypeInfoVar typeInfoVar = (TypeInfoVar) typeInfo; + return typeInfoVar.substitute(projections); + } else { + throw new IllegalStateException(); + } + } + + static TypeInfo substitute(TypeInfo typeInfo, List myVars) { + if (typeInfo instanceof TypeInfoImpl) { + TypeInfoImpl typeInfoImpl = (TypeInfoImpl) typeInfo; + return typeInfoImpl.substitute(myVars); + } else if (typeInfo instanceof TypeInfoVar) { + TypeInfoVar typeInfoVar = (TypeInfoVar) typeInfo; + return typeInfoVar.substitute(myVars); + } else { + throw new IllegalStateException(); + } + } + +} diff --git a/stdlib/src/jet/typeinfo/internal/TypeInfoVar.java b/stdlib/src/jet/typeinfo/internal/TypeInfoVar.java new file mode 100644 index 00000000000..9b20798ab93 --- /dev/null +++ b/stdlib/src/jet/typeinfo/internal/TypeInfoVar.java @@ -0,0 +1,89 @@ +package jet.typeinfo.internal; + +import jet.JetObject; +import jet.typeinfo.TypeInfo; +import jet.typeinfo.TypeInfoProjection; + +import java.util.List; + +/** + * @author abreslav + * @author yole + * @author alex.tkachman + * @author Stepan Koltsov + */ +class TypeInfoVar extends TypeInfo { + final int varIndex; + final Signature signature; + final boolean nullable; + + public TypeInfoVar(Signature signature, Integer varIndex) { + this.signature = signature; + this.varIndex = varIndex; + nullable = false; + } + + public TypeInfoVar(Signature signature, boolean nullable, int varIndex) { + this.signature = signature; + this.nullable = nullable; + this.varIndex = varIndex; + } + + @Override + public Object[] newArray(int length) { + throw new UnsupportedOperationException(); + } + + @Override + public Class getJavaClass() { + throw new UnsupportedOperationException(); + } + + @Override + public Object getClassObject() { + throw new UnsupportedOperationException("Abstract TypeInfo"); + } + + @Override + public boolean isInstance(Object obj) { + throw new UnsupportedOperationException("Abstract TypeInfo"); + } + + @Override + public int getProjectionCount() { + return 0; + } + + @Override + public TypeInfoProjection getProjection(int index) { + throw new UnsupportedOperationException("Abstract TypeInfo"); + } + + @Override + public TypeInfo getArgumentType(Class klass, int index) { + throw new UnsupportedOperationException("Abstract TypeInfo"); + } + + TypeInfo substitute(List myVars) { + return myVars.get(varIndex); + } + + TypeInfo substitute(TypeInfoProjection[] projections) { + return projections[varIndex].getType(); + } + + @Override + public TypeInfo getTypeInfo() { + throw new UnsupportedOperationException("Abstract TypeInfo"); + } + + @Override + public JetObject getOuterObject() { + return null; + } + + @Override + public String toString() { + return "T:" + signature.klazz.getName() + ":" + varIndex; + } +} diff --git a/stdlib/src/jet/typeinfo/internal/signature/JetSignatureExceptionsAdapter.java b/stdlib/src/jet/typeinfo/internal/signature/JetSignatureExceptionsAdapter.java new file mode 100644 index 00000000000..02b54de2868 --- /dev/null +++ b/stdlib/src/jet/typeinfo/internal/signature/JetSignatureExceptionsAdapter.java @@ -0,0 +1,88 @@ +package jet.typeinfo.internal.signature; + +import jet.typeinfo.TypeInfoVariance; + +/** + * @author Stepan Koltsov + */ +public class JetSignatureExceptionsAdapter implements JetSignatureVisitor { + @Override + public void visitFormalTypeParameter(String name, TypeInfoVariance variance) { + throw new IllegalStateException(); + } + + @Override + public JetSignatureVisitor visitClassBound() { + throw new IllegalStateException(); + } + + @Override + public JetSignatureVisitor visitInterfaceBound() { + throw new IllegalStateException(); + } + + @Override + public JetSignatureVisitor visitSuperclass() { + throw new IllegalStateException(); + } + + @Override + public JetSignatureVisitor visitInterface() { + throw new IllegalStateException(); + } + + @Override + public JetSignatureVisitor visitParameterType() { + throw new IllegalStateException(); + } + + @Override + public JetSignatureVisitor visitReturnType() { + throw new IllegalStateException(); + } + + @Override + public JetSignatureVisitor visitExceptionType() { + throw new IllegalStateException(); + } + + @Override + public void visitBaseType(char descriptor, boolean nullable) { + throw new IllegalStateException(); + } + + @Override + public void visitTypeVariable(String name, boolean nullable) { + throw new IllegalStateException(); + } + + @Override + public JetSignatureVisitor visitArrayType(boolean nullable) { + throw new IllegalStateException(); + } + + @Override + public void visitClassType(String name, boolean nullable) { + throw new IllegalStateException(); + } + + @Override + public void visitInnerClassType(String name, boolean nullable) { + throw new IllegalStateException(); + } + + @Override + public void visitTypeArgument() { + throw new IllegalStateException(); + } + + @Override + public JetSignatureVisitor visitTypeArgument(char wildcard) { + throw new IllegalStateException(); + } + + @Override + public void visitEnd() { + throw new IllegalStateException(); + } +} diff --git a/stdlib/src/jet/typeinfo/internal/signature/JetSignatureReader.java b/stdlib/src/jet/typeinfo/internal/signature/JetSignatureReader.java index 3922801bbee..4b94431bf88 100644 --- a/stdlib/src/jet/typeinfo/internal/signature/JetSignatureReader.java +++ b/stdlib/src/jet/typeinfo/internal/signature/JetSignatureReader.java @@ -19,39 +19,7 @@ public class JetSignatureReader { public void accept(final JetSignatureVisitor v) { String signature = this.signature; int len = signature.length(); - int pos; - char c; - - if (signature.charAt(0) == '<') { - pos = 2; - do { - TypeInfoVariance variance; - if (signature.substring(pos).startsWith("in ")) { - variance = TypeInfoVariance.IN; - pos += "in ".length(); - } else if (signature.substring(pos).startsWith("out ")) { - variance = TypeInfoVariance.OUT; - pos += "out ".length(); - } else { - variance = TypeInfoVariance.INVARIANT; - pos += "".length(); - } - int end = signature.indexOf(':', pos); - v.visitFormalTypeParameter(signature.substring(pos - 1, end), variance); - pos = end + 1; - - c = signature.charAt(pos); - if (c == 'L' || c == '[' || c == 'T') { - pos = parseType(signature, pos, v.visitClassBound()); - } - - while ((c = signature.charAt(pos++)) == ':') { - pos = parseType(signature, pos, v.visitInterfaceBound()); - } - } while (c != '>'); - } else { - pos = 0; - } + int pos = acceptFormalTypeParameters(v); if (signature.charAt(pos) == '(') { pos++; @@ -70,6 +38,52 @@ public class JetSignatureReader { } } + public int acceptFormalTypeParameters(JetSignatureVisitor v) { + int pos; + char c; + if (signature.length() > 0 && signature.charAt(0) == '<') { + pos = 1; + do { + TypeInfoVariance variance; + if (signature.substring(pos).startsWith("in ")) { + variance = TypeInfoVariance.IN; + pos += "in ".length(); + } else if (signature.substring(pos).startsWith("out ")) { + variance = TypeInfoVariance.OUT; + pos += "out ".length(); + } else { + variance = TypeInfoVariance.INVARIANT; + pos += "".length(); + } + int end = signature.indexOf(':', pos); + if (end < 0) { + throw new IllegalStateException(); + } + v.visitFormalTypeParameter(signature.substring(pos, end), variance); + pos = end + 1; + + c = signature.charAt(pos); + if (c == 'L' || c == '[' || c == 'T' || c == '?') { + pos = parseType(signature, pos, v.visitClassBound()); + } + + while ((c = signature.charAt(pos++)) == ':') { + pos = parseType(signature, pos, v.visitInterfaceBound()); + } + } while (c != '>'); + } else { + pos = 0; + } + return pos; + } + + public void acceptFormalTypeParametersOnly(JetSignatureVisitor v) { + int r = acceptFormalTypeParameters(v); + if (r != signature.length()) { + throw new IllegalStateException(); + } + } + public int acceptType(JetSignatureVisitor v) { return parseType(this.signature, 0, v); } From 21ce7d88e734557004701ca13cd4dbb29105d108 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Wed, 14 Dec 2011 22:38:31 +0400 Subject: [PATCH 17/33] rename internal package --- .../org/jetbrains/jet/codegen/BothSignatureWriter.java | 6 +++--- .../jet/lang/resolve/java/JavaTypeTransformer.java | 2 +- .../jet/lang/resolve/java/JetTypeJetSignatureReader.java | 6 ++---- stdlib/src/jet/typeinfo/TypeInfo.java | 4 ++-- .../internal => org/jetbrains/jet/rt}/Signature.java | 2 +- .../internal => org/jetbrains/jet/rt}/TypeInfoImpl.java | 2 +- .../internal => org/jetbrains/jet/rt}/TypeInfoParser.java | 8 ++++---- .../jetbrains/jet/rt}/TypeInfoProjectionImpl.java | 4 ++-- .../internal => org/jetbrains/jet/rt}/TypeInfoUtils.java | 2 +- .../internal => org/jetbrains/jet/rt}/TypeInfoVar.java | 2 +- .../jetbrains/jet/rt}/signature/JetSignatureAdapter.java | 2 +- .../jet/rt}/signature/JetSignatureExceptionsAdapter.java | 2 +- .../jetbrains/jet/rt}/signature/JetSignatureReader.java | 2 +- .../jetbrains/jet/rt}/signature/JetSignatureVisitor.java | 2 +- .../jetbrains/jet/rt}/signature/JetSignatureWriter.java | 2 +- 15 files changed, 23 insertions(+), 25 deletions(-) rename stdlib/src/{jet/typeinfo/internal => org/jetbrains/jet/rt}/Signature.java (98%) rename stdlib/src/{jet/typeinfo/internal => org/jetbrains/jet/rt}/TypeInfoImpl.java (99%) rename stdlib/src/{jet/typeinfo/internal => org/jetbrains/jet/rt}/TypeInfoParser.java (97%) rename stdlib/src/{jet/typeinfo/internal => org/jetbrains/jet/rt}/TypeInfoProjectionImpl.java (88%) rename stdlib/src/{jet/typeinfo/internal => org/jetbrains/jet/rt}/TypeInfoUtils.java (97%) rename stdlib/src/{jet/typeinfo/internal => org/jetbrains/jet/rt}/TypeInfoVar.java (98%) rename stdlib/src/{jet/typeinfo/internal => org/jetbrains/jet/rt}/signature/JetSignatureAdapter.java (97%) rename stdlib/src/{jet/typeinfo/internal => org/jetbrains/jet/rt}/signature/JetSignatureExceptionsAdapter.java (98%) rename stdlib/src/{jet/typeinfo/internal => org/jetbrains/jet/rt}/signature/JetSignatureReader.java (99%) rename stdlib/src/{jet/typeinfo/internal => org/jetbrains/jet/rt}/signature/JetSignatureVisitor.java (98%) rename stdlib/src/{jet/typeinfo/internal => org/jetbrains/jet/rt}/signature/JetSignatureWriter.java (99%) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java b/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java index 8fcbabac1ac..d83d838cb95 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java @@ -3,9 +3,9 @@ package org.jetbrains.jet.codegen; import jet.typeinfo.TypeInfoVariance; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import jet.typeinfo.internal.signature.JetSignatureAdapter; -import jet.typeinfo.internal.signature.JetSignatureReader; -import jet.typeinfo.internal.signature.JetSignatureWriter; +import org.jetbrains.jet.rt.signature.JetSignatureAdapter; +import org.jetbrains.jet.rt.signature.JetSignatureReader; +import org.jetbrains.jet.rt.signature.JetSignatureWriter; import org.jetbrains.jet.lang.types.Variance; import org.objectweb.asm.Type; import org.objectweb.asm.signature.SignatureVisitor; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java index fd74d3d4d1e..4aed6ee493d 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java @@ -2,7 +2,7 @@ package org.jetbrains.jet.lang.resolve.java; import com.google.common.collect.Lists; import com.intellij.psi.*; -import jet.typeinfo.internal.signature.JetSignatureReader; +import org.jetbrains.jet.rt.signature.JetSignatureReader; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java index 2c190cbc956..64bf4d30633 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java @@ -1,12 +1,10 @@ package org.jetbrains.jet.lang.resolve.java; -import jet.typeinfo.TypeInfoVariance; -import jet.typeinfo.internal.signature.JetSignatureAdapter; -import jet.typeinfo.internal.signature.JetSignatureExceptionsAdapter; +import org.jetbrains.jet.rt.signature.JetSignatureExceptionsAdapter; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; -import jet.typeinfo.internal.signature.JetSignatureVisitor; +import org.jetbrains.jet.rt.signature.JetSignatureVisitor; import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetStandardClasses; import org.jetbrains.jet.lang.types.JetStandardLibrary; diff --git a/stdlib/src/jet/typeinfo/TypeInfo.java b/stdlib/src/jet/typeinfo/TypeInfo.java index f2bc7734534..3e9a3ddaa30 100644 --- a/stdlib/src/jet/typeinfo/TypeInfo.java +++ b/stdlib/src/jet/typeinfo/TypeInfo.java @@ -2,8 +2,8 @@ package jet.typeinfo; import jet.JetObject; import jet.Tuple0; -import jet.typeinfo.internal.TypeInfoImpl; -import jet.typeinfo.internal.TypeInfoProjectionImpl; +import org.jetbrains.jet.rt.TypeInfoImpl; +import org.jetbrains.jet.rt.TypeInfoProjectionImpl; /** * @author abreslav diff --git a/stdlib/src/jet/typeinfo/internal/Signature.java b/stdlib/src/org/jetbrains/jet/rt/Signature.java similarity index 98% rename from stdlib/src/jet/typeinfo/internal/Signature.java rename to stdlib/src/org/jetbrains/jet/rt/Signature.java index 879ad3e46ae..ffa29d62636 100644 --- a/stdlib/src/jet/typeinfo/internal/Signature.java +++ b/stdlib/src/org/jetbrains/jet/rt/Signature.java @@ -1,4 +1,4 @@ -package jet.typeinfo.internal; +package org.jetbrains.jet.rt; import jet.typeinfo.TypeInfo; import jet.typeinfo.TypeInfoProjection; diff --git a/stdlib/src/jet/typeinfo/internal/TypeInfoImpl.java b/stdlib/src/org/jetbrains/jet/rt/TypeInfoImpl.java similarity index 99% rename from stdlib/src/jet/typeinfo/internal/TypeInfoImpl.java rename to stdlib/src/org/jetbrains/jet/rt/TypeInfoImpl.java index fe784eb8eae..48ba799f33d 100644 --- a/stdlib/src/jet/typeinfo/internal/TypeInfoImpl.java +++ b/stdlib/src/org/jetbrains/jet/rt/TypeInfoImpl.java @@ -1,4 +1,4 @@ -package jet.typeinfo.internal; +package org.jetbrains.jet.rt; import jet.JetObject; import jet.typeinfo.TypeInfo; diff --git a/stdlib/src/jet/typeinfo/internal/TypeInfoParser.java b/stdlib/src/org/jetbrains/jet/rt/TypeInfoParser.java similarity index 97% rename from stdlib/src/jet/typeinfo/internal/TypeInfoParser.java rename to stdlib/src/org/jetbrains/jet/rt/TypeInfoParser.java index 4ffdf66fc30..1a3b67a3d2e 100644 --- a/stdlib/src/jet/typeinfo/internal/TypeInfoParser.java +++ b/stdlib/src/org/jetbrains/jet/rt/TypeInfoParser.java @@ -1,12 +1,12 @@ -package jet.typeinfo.internal; +package org.jetbrains.jet.rt; import jet.typeinfo.JetSignature; import jet.typeinfo.TypeInfo; import jet.typeinfo.TypeInfoProjection; import jet.typeinfo.TypeInfoVariance; -import jet.typeinfo.internal.signature.JetSignatureExceptionsAdapter; -import jet.typeinfo.internal.signature.JetSignatureReader; -import jet.typeinfo.internal.signature.JetSignatureVisitor; +import org.jetbrains.jet.rt.signature.JetSignatureExceptionsAdapter; +import org.jetbrains.jet.rt.signature.JetSignatureReader; +import org.jetbrains.jet.rt.signature.JetSignatureVisitor; import java.lang.reflect.TypeVariable; import java.util.ArrayList; diff --git a/stdlib/src/jet/typeinfo/internal/TypeInfoProjectionImpl.java b/stdlib/src/org/jetbrains/jet/rt/TypeInfoProjectionImpl.java similarity index 88% rename from stdlib/src/jet/typeinfo/internal/TypeInfoProjectionImpl.java rename to stdlib/src/org/jetbrains/jet/rt/TypeInfoProjectionImpl.java index 94438ffbd5e..6a9d46f1c7e 100644 --- a/stdlib/src/jet/typeinfo/internal/TypeInfoProjectionImpl.java +++ b/stdlib/src/org/jetbrains/jet/rt/TypeInfoProjectionImpl.java @@ -1,4 +1,4 @@ -package jet.typeinfo.internal; +package org.jetbrains.jet.rt; import jet.typeinfo.TypeInfo; import jet.typeinfo.TypeInfoProjection; @@ -27,7 +27,7 @@ public abstract class TypeInfoProjectionImpl implements TypeInfoProjection { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - jet.typeinfo.internal.TypeInfoProjectionImpl that = (jet.typeinfo.internal.TypeInfoProjectionImpl) o; + TypeInfoProjectionImpl that = (TypeInfoProjectionImpl) o; // no need to compare variance as we compared classes already return type.equals(that.type); } diff --git a/stdlib/src/jet/typeinfo/internal/TypeInfoUtils.java b/stdlib/src/org/jetbrains/jet/rt/TypeInfoUtils.java similarity index 97% rename from stdlib/src/jet/typeinfo/internal/TypeInfoUtils.java rename to stdlib/src/org/jetbrains/jet/rt/TypeInfoUtils.java index 15747bb7c74..3a249cf295e 100644 --- a/stdlib/src/jet/typeinfo/internal/TypeInfoUtils.java +++ b/stdlib/src/org/jetbrains/jet/rt/TypeInfoUtils.java @@ -1,4 +1,4 @@ -package jet.typeinfo.internal; +package org.jetbrains.jet.rt; import jet.typeinfo.TypeInfo; import jet.typeinfo.TypeInfoProjection; diff --git a/stdlib/src/jet/typeinfo/internal/TypeInfoVar.java b/stdlib/src/org/jetbrains/jet/rt/TypeInfoVar.java similarity index 98% rename from stdlib/src/jet/typeinfo/internal/TypeInfoVar.java rename to stdlib/src/org/jetbrains/jet/rt/TypeInfoVar.java index 9b20798ab93..598151b8bd4 100644 --- a/stdlib/src/jet/typeinfo/internal/TypeInfoVar.java +++ b/stdlib/src/org/jetbrains/jet/rt/TypeInfoVar.java @@ -1,4 +1,4 @@ -package jet.typeinfo.internal; +package org.jetbrains.jet.rt; import jet.JetObject; import jet.typeinfo.TypeInfo; diff --git a/stdlib/src/jet/typeinfo/internal/signature/JetSignatureAdapter.java b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureAdapter.java similarity index 97% rename from stdlib/src/jet/typeinfo/internal/signature/JetSignatureAdapter.java rename to stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureAdapter.java index 8e229360bc4..3366e3b410f 100644 --- a/stdlib/src/jet/typeinfo/internal/signature/JetSignatureAdapter.java +++ b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureAdapter.java @@ -1,4 +1,4 @@ -package jet.typeinfo.internal.signature; +package org.jetbrains.jet.rt.signature; import jet.typeinfo.TypeInfoVariance; diff --git a/stdlib/src/jet/typeinfo/internal/signature/JetSignatureExceptionsAdapter.java b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureExceptionsAdapter.java similarity index 98% rename from stdlib/src/jet/typeinfo/internal/signature/JetSignatureExceptionsAdapter.java rename to stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureExceptionsAdapter.java index 02b54de2868..cca55b64951 100644 --- a/stdlib/src/jet/typeinfo/internal/signature/JetSignatureExceptionsAdapter.java +++ b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureExceptionsAdapter.java @@ -1,4 +1,4 @@ -package jet.typeinfo.internal.signature; +package org.jetbrains.jet.rt.signature; import jet.typeinfo.TypeInfoVariance; diff --git a/stdlib/src/jet/typeinfo/internal/signature/JetSignatureReader.java b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureReader.java similarity index 99% rename from stdlib/src/jet/typeinfo/internal/signature/JetSignatureReader.java rename to stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureReader.java index 4b94431bf88..49624917f09 100644 --- a/stdlib/src/jet/typeinfo/internal/signature/JetSignatureReader.java +++ b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureReader.java @@ -1,4 +1,4 @@ -package jet.typeinfo.internal.signature; +package org.jetbrains.jet.rt.signature; import jet.typeinfo.TypeInfoVariance; diff --git a/stdlib/src/jet/typeinfo/internal/signature/JetSignatureVisitor.java b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureVisitor.java similarity index 98% rename from stdlib/src/jet/typeinfo/internal/signature/JetSignatureVisitor.java rename to stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureVisitor.java index 4aa667d515a..ee7bfc3e2d1 100644 --- a/stdlib/src/jet/typeinfo/internal/signature/JetSignatureVisitor.java +++ b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureVisitor.java @@ -1,4 +1,4 @@ -package jet.typeinfo.internal.signature; +package org.jetbrains.jet.rt.signature; import jet.typeinfo.TypeInfoVariance; diff --git a/stdlib/src/jet/typeinfo/internal/signature/JetSignatureWriter.java b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureWriter.java similarity index 99% rename from stdlib/src/jet/typeinfo/internal/signature/JetSignatureWriter.java rename to stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureWriter.java index 3ac43dba3fd..9bd16db1c52 100644 --- a/stdlib/src/jet/typeinfo/internal/signature/JetSignatureWriter.java +++ b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureWriter.java @@ -1,4 +1,4 @@ -package jet.typeinfo.internal.signature; +package org.jetbrains.jet.rt.signature; import jet.typeinfo.TypeInfoVariance; From a37c015f021530ec0331d59f19339ec62981bc2e Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Wed, 14 Dec 2011 22:58:21 +0400 Subject: [PATCH 18/33] fail earlier --- .../src/org/jetbrains/jet/codegen/GeneratedClassLoader.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/GeneratedClassLoader.java b/compiler/backend/src/org/jetbrains/jet/codegen/GeneratedClassLoader.java index b851b21a8a0..f9f9e790c8f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/GeneratedClassLoader.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/GeneratedClassLoader.java @@ -1,12 +1,14 @@ package org.jetbrains.jet.codegen; +import org.jetbrains.annotations.NotNull; + /** * @author yole */ public class GeneratedClassLoader extends ClassLoader { private final ClassFileFactory state; - public GeneratedClassLoader(ClassFileFactory state) { + public GeneratedClassLoader(@NotNull ClassFileFactory state) { super(GeneratedClassLoader.class.getClassLoader()); this.state = state; } From 2b23ed005fb57659843e570a4a80842f267ecc5a Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Thu, 15 Dec 2011 03:04:12 +0400 Subject: [PATCH 19/33] skip @JetTypeParameter parameters --- .../resolve/java/JavaDescriptorResolver.java | 7 ++- .../testData/readClass/FunGenericParam.kt | 3 + .../org/jetbrains/jet/ReadClassDataTest.java | 61 ++++++++++++++++++- 3 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 compiler/testData/readClass/FunGenericParam.kt diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index b70626a96a7..473600d3bb3 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -341,11 +341,14 @@ public class JavaDescriptorResolver { for (int i = 0, parametersLength = parameters.length; i < parametersLength; i++) { PsiParameter parameter = parameters[i]; ValueParameterDescriptor valueParameterDescriptor = resolveParameterDescriptor(containingDeclaration, i, parameter); - result.add(valueParameterDescriptor); + if (valueParameterDescriptor != null) { + result.add(valueParameterDescriptor); + } } return result; } + @Nullable private ValueParameterDescriptor resolveParameterDescriptor(DeclarationDescriptor containingDeclaration, int i, PsiParameter parameter) { PsiType psiType = parameter.getType(); @@ -389,6 +392,8 @@ public class JavaDescriptorResolver { if (signatureExpression != null) { typeFromAnnotation = (String) signatureExpression.getValue(); } + } else if (annotation.getQualifiedName().equals(StdlibNames.JET_TYPE_PARAMETER_CLASS)) { + return null; } } diff --git a/compiler/testData/readClass/FunGenericParam.kt b/compiler/testData/readClass/FunGenericParam.kt new file mode 100644 index 00000000000..56db0deab7e --- /dev/null +++ b/compiler/testData/readClass/FunGenericParam.kt @@ -0,0 +1,3 @@ +namespace test + +fun f() = 1 diff --git a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java index b7ceb359a44..4f72a7af786 100644 --- a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java +++ b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java @@ -21,8 +21,10 @@ import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorImpl; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.AnalyzingUtils; @@ -30,13 +32,16 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTraceContext; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices; +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.plugin.JetLanguage; import org.junit.Assert; import java.io.File; import java.lang.reflect.Method; +import java.util.List; import java.util.Set; /** @@ -154,6 +159,12 @@ public class ReadClassDataTest extends UsefulTestCase { private void compareFunctions(@NotNull FunctionDescriptor a, @NotNull FunctionDescriptor b) { Assert.assertEquals(a.getName(), b.getName()); + + Assert.assertEquals(a.getTypeParameters().size(), b.getTypeParameters().size()); + for (int i = 0; i < a.getTypeParameters().size(); ++i) { + compareAnything(TypeParameterDescriptor.class, a.getTypeParameters().get(i), b.getTypeParameters().get(i)); + } + Assert.assertEquals(a.getValueParameters().size(), b.getValueParameters().size()); for (int i = 0; i < a.getValueParameters().size(); ++i) { compareAnything(ValueParameterDescriptor.class, a.getValueParameters().get(i), b.getValueParameters().get(i)); @@ -165,17 +176,43 @@ public class ReadClassDataTest extends UsefulTestCase { private void compareAnything(Object a, Object b) { if (a instanceof JetType || b instanceof JetType) { compareTypes((JetType) a, (JetType) b); + } else if (a instanceof TypeConstructor && b instanceof TypeConstructor) { + compareTypeConstructors((TypeConstructor) a, (TypeConstructor) b); + } else if (a instanceof List || b instanceof List) { + compareLists((List) a, (List) b); + } else if (a instanceof TypeProjection || b instanceof TypeProjection) { + compareTypeProjections((TypeProjection) a, (TypeProjection) b); + } else if (a instanceof TypeParameterDescriptor || b instanceof TypeParameterDescriptor) { + compareTypeParameterDescriptors((TypeParameterDescriptor) a, (TypeParameterDescriptor) b); } else { Assert.assertEquals(a, b); } } - private void compareTypes(JetType a, JetType b) { - // cannot just call a.equals(b) because "a" and "b" were created in different environments, - // TypeConstructor does not override equals() + private void compareTypeParameterDescriptors(TypeParameterDescriptor a, TypeParameterDescriptor b) { + compareAnything(TypeParameterDescriptor.class, a, b); + } + + private void compareTypeProjections(TypeProjection a, TypeProjection b) { + compareAnything(TypeProjection.class, a, b); + } + + private void compareLists(List a, List b) { + Assert.assertEquals(a.size(), b.size()); + for (int i = 0; i < a.size(); ++i) { + compareAnything(a.get(i), b.get(i)); + } + } + + private void compareTypeConstructors(TypeConstructor a, TypeConstructor b) { + //compareAnything(TypeConstructor.class, a, b); Assert.assertEquals(a.toString(), b.toString()); } + private void compareTypes(JetType a, JetType b) { + compareAnything(JetType.class, a, b); + } + private void compareAnything(Class clazz, T a, T b) { System.out.println("Comparing " + clazz); Assert.assertNotNull(a); @@ -185,16 +222,34 @@ public class ReadClassDataTest extends UsefulTestCase { if (!isGetter(method)) { continue; } + + if (JetScope.class.isAssignableFrom(method.getReturnType())) { + continue; + } + if (method.getName().equals("getContainingDeclaration")) { continue; } + if (method.getName().equals("isReified")) { + // TODO + continue; + } + if (clazz.equals(ValueParameterDescriptor.class)) { if (method.getName().equals("isRef") || method.getName().equals("getOriginal")) { continue; } } + if (method.getDeclaringClass().equals(DeclarationDescriptorImpl.class) + || method.getDeclaringClass().equals(DeclarationDescriptor.class)) + { + if (method.getName().equals("getOriginal")) { + continue; + } + } + System.out.println(method.getName()); Object ap = invoke(method, a); Object bp = invoke(method, b); From 33967c32f77b54efe15bcdb219c1db0038a662fe Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Thu, 15 Dec 2011 03:04:18 +0400 Subject: [PATCH 20/33] test class data reading by comparing serialization to string --- .../readClass/FunClassParamNotNull.kt | 3 +- .../readClass/FunClassParamNullable.kt | 3 +- .../testData/readClass/FunParamNotNull.kt | 2 +- .../testData/readClass/FunParamNullable.kt | 2 +- .../readClass/ReturnTypeClassParamNotNull.kt | 3 +- .../readClass/ReturnTypeClassParamNullable.kt | 3 +- .../testData/readClass/ReturnTypeNotNull.kt | 2 +- .../testData/readClass/ReturnTypeNullable.kt | 2 +- .../org/jetbrains/jet/ReadClassDataTest.java | 282 ++++++++++-------- 9 files changed, 177 insertions(+), 125 deletions(-) diff --git a/compiler/testData/readClass/FunClassParamNotNull.kt b/compiler/testData/readClass/FunClassParamNotNull.kt index 5dd2abe1afb..92e6b8f1fd8 100644 --- a/compiler/testData/readClass/FunClassParamNotNull.kt +++ b/compiler/testData/readClass/FunClassParamNotNull.kt @@ -1,5 +1,6 @@ namespace test import java.util.List +import java.lang.CharSequence -fun ff(p: List) = 1 +fun ff(p: List) = 1 diff --git a/compiler/testData/readClass/FunClassParamNullable.kt b/compiler/testData/readClass/FunClassParamNullable.kt index fafa4387a77..8b40b9ff0bc 100644 --- a/compiler/testData/readClass/FunClassParamNullable.kt +++ b/compiler/testData/readClass/FunClassParamNullable.kt @@ -1,5 +1,6 @@ namespace test import java.util.List +import java.lang.CharSequence -fun ff(p: List) = 1 +fun ff(p: List) = 1 diff --git a/compiler/testData/readClass/FunParamNotNull.kt b/compiler/testData/readClass/FunParamNotNull.kt index 72d84f88278..1673576064f 100644 --- a/compiler/testData/readClass/FunParamNotNull.kt +++ b/compiler/testData/readClass/FunParamNotNull.kt @@ -1,3 +1,3 @@ namespace test -fun fff(a: String) = 1 +fun fff(a: java.lang.CharSequence) = 1 diff --git a/compiler/testData/readClass/FunParamNullable.kt b/compiler/testData/readClass/FunParamNullable.kt index 288582a2f08..af1e70d8115 100644 --- a/compiler/testData/readClass/FunParamNullable.kt +++ b/compiler/testData/readClass/FunParamNullable.kt @@ -1,3 +1,3 @@ namespace test -fun fff(a: String?) = 1 +fun fff(a: java.lang.CharSequence?) = 1 diff --git a/compiler/testData/readClass/ReturnTypeClassParamNotNull.kt b/compiler/testData/readClass/ReturnTypeClassParamNotNull.kt index 90e394a811a..94613473c88 100644 --- a/compiler/testData/readClass/ReturnTypeClassParamNotNull.kt +++ b/compiler/testData/readClass/ReturnTypeClassParamNotNull.kt @@ -2,5 +2,6 @@ namespace test import java.util.List import java.util.ArrayList +import java.lang.CharSequence -fun ffgg(): List = ArrayList() +fun ffgg(): List = ArrayList() diff --git a/compiler/testData/readClass/ReturnTypeClassParamNullable.kt b/compiler/testData/readClass/ReturnTypeClassParamNullable.kt index 447be6bbfaa..4c9bb54a59e 100644 --- a/compiler/testData/readClass/ReturnTypeClassParamNullable.kt +++ b/compiler/testData/readClass/ReturnTypeClassParamNullable.kt @@ -2,5 +2,6 @@ namespace test import java.util.List import java.util.ArrayList +import java.lang.CharSequence -fun ffgg(): List = ArrayList() +fun ffgg(): List = ArrayList() diff --git a/compiler/testData/readClass/ReturnTypeNotNull.kt b/compiler/testData/readClass/ReturnTypeNotNull.kt index 0e025241a22..fd57fb31d3d 100644 --- a/compiler/testData/readClass/ReturnTypeNotNull.kt +++ b/compiler/testData/readClass/ReturnTypeNotNull.kt @@ -1,3 +1,3 @@ namespace test -fun ff(): String = "" +fun ff(): java.lang.CharSequence = throw Exception() diff --git a/compiler/testData/readClass/ReturnTypeNullable.kt b/compiler/testData/readClass/ReturnTypeNullable.kt index 6b3e33f7136..61d5a242d1d 100644 --- a/compiler/testData/readClass/ReturnTypeNullable.kt +++ b/compiler/testData/readClass/ReturnTypeNullable.kt @@ -1,3 +1,3 @@ namespace test -fun ff(): String? = "" +fun ff(): java.lang.CharSequence? = null diff --git a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java index 4f72a7af786..03936722192 100644 --- a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java +++ b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java @@ -23,6 +23,7 @@ import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorImpl; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; @@ -36,11 +37,13 @@ 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 org.jetbrains.jet.plugin.JetLanguage; import org.junit.Assert; import java.io.File; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -146,137 +149,182 @@ public class ReadClassDataTest extends UsefulTestCase { } private void compareClassifiers(@NotNull ClassifierDescriptor a, @NotNull ClassifierDescriptor b) { - Assert.assertEquals(a.getName(), b.getName()); - System.out.println("classifier " + a.getName()); - if (a instanceof ClassDescriptor || b instanceof ClassDescriptor) { - compareClasses((ClassDescriptor) a, (ClassDescriptor) b); - } - } + String as = serializeContent((ClassDescriptor) a); + String bs = serializeContent((ClassDescriptor) b); - private void compareClasses(@NotNull ClassDescriptor a, @NotNull ClassDescriptor b) { - System.out.println("... is class"); + Assert.assertEquals(as, bs); + System.out.println(a); } + private String serializeContent(ClassDescriptor klass) { + + StringBuilder sb = new StringBuilder(); + sb.append("class "); + + serialize(klass, sb); + + // TODO: supers + // TODO: constructors + + sb.append(" {\n"); + + if (false) { + // TODO: for some reason I don't understand scope of ClassDescriptor came from source is empty + + List typeArguments = new ArrayList(); + for (TypeParameterDescriptor param : klass.getTypeConstructor().getParameters()) { + typeArguments.add(new TypeProjection(Variance.INVARIANT, param.getDefaultType())); + } + + JetScope memberScope = klass.getMemberScope(typeArguments); + for (DeclarationDescriptor member : memberScope.getAllDescriptors()) { + serialize(member, sb); + sb.append("\n"); + } + + } + + sb.append("}\n"); + return sb.toString(); + } + + private void compareFunctions(@NotNull FunctionDescriptor a, @NotNull FunctionDescriptor b) { - Assert.assertEquals(a.getName(), b.getName()); + String as = serialize(a); + String bs = serialize(b); - Assert.assertEquals(a.getTypeParameters().size(), b.getTypeParameters().size()); - for (int i = 0; i < a.getTypeParameters().size(); ++i) { - compareAnything(TypeParameterDescriptor.class, a.getTypeParameters().get(i), b.getTypeParameters().get(i)); - } - - Assert.assertEquals(a.getValueParameters().size(), b.getValueParameters().size()); - for (int i = 0; i < a.getValueParameters().size(); ++i) { - compareAnything(ValueParameterDescriptor.class, a.getValueParameters().get(i), b.getValueParameters().get(i)); - } - compareTypes(a.getReturnType(), b.getReturnType()); - System.out.println("fun " + a.getName() + "(...): " + a.getReturnType()); + Assert.assertEquals(as, bs); + System.out.println(as); } - private void compareAnything(Object a, Object b) { - if (a instanceof JetType || b instanceof JetType) { - compareTypes((JetType) a, (JetType) b); - } else if (a instanceof TypeConstructor && b instanceof TypeConstructor) { - compareTypeConstructors((TypeConstructor) a, (TypeConstructor) b); - } else if (a instanceof List || b instanceof List) { - compareLists((List) a, (List) b); - } else if (a instanceof TypeProjection || b instanceof TypeProjection) { - compareTypeProjections((TypeProjection) a, (TypeProjection) b); - } else if (a instanceof TypeParameterDescriptor || b instanceof TypeParameterDescriptor) { - compareTypeParameterDescriptors((TypeParameterDescriptor) a, (TypeParameterDescriptor) b); - } else { - Assert.assertEquals(a, b); - } - } - - private void compareTypeParameterDescriptors(TypeParameterDescriptor a, TypeParameterDescriptor b) { - compareAnything(TypeParameterDescriptor.class, a, b); - } - - private void compareTypeProjections(TypeProjection a, TypeProjection b) { - compareAnything(TypeProjection.class, a, b); - } - - private void compareLists(List a, List b) { - Assert.assertEquals(a.size(), b.size()); - for (int i = 0; i < a.size(); ++i) { - compareAnything(a.get(i), b.get(i)); - } - } - private void compareTypeConstructors(TypeConstructor a, TypeConstructor b) { - //compareAnything(TypeConstructor.class, a, b); - Assert.assertEquals(a.toString(), b.toString()); - } - - private void compareTypes(JetType a, JetType b) { - compareAnything(JetType.class, a, b); - } - - private void compareAnything(Class clazz, T a, T b) { - System.out.println("Comparing " + clazz); - Assert.assertNotNull(a); - Assert.assertNotNull(b); - - for (Method method : clazz.getMethods()) { - if (!isGetter(method)) { - continue; - } - - if (JetScope.class.isAssignableFrom(method.getReturnType())) { - continue; - } - - if (method.getName().equals("getContainingDeclaration")) { - continue; - } - - if (method.getName().equals("isReified")) { - // TODO - continue; - } - - if (clazz.equals(ValueParameterDescriptor.class)) { - if (method.getName().equals("isRef") || method.getName().equals("getOriginal")) { - continue; - } - } - - if (method.getDeclaringClass().equals(DeclarationDescriptorImpl.class) - || method.getDeclaringClass().equals(DeclarationDescriptor.class)) - { - if (method.getName().equals("getOriginal")) { - continue; - } - } - - System.out.println(method.getName()); - Object ap = invoke(method, a); - Object bp = invoke(method, b); - compareAnything(ap, bp); - } - } - - private static boolean isGetter(Method method) { - if (method.getParameterTypes().length > 0) { - return false; - } - if (method.getName().matches("is.+")) { - return method.getReturnType().equals(boolean.class); - } else if (method.getName().matches("get.+")) { - return true; - } else { - return false; - } - } - private static Object invoke(Method method, Object thiz, Object... args) { try { + method.setAccessible(true); return method.invoke(thiz, args); } catch (Exception e) { - throw new RuntimeException("failed to invoke " + method + ": " + e); + throw new RuntimeException("failed to invoke " + method + ": " + e, e); } } + + + private void serialize(FunctionDescriptor fun, StringBuilder sb) { + sb.append("fun "); + if (!fun.getTypeParameters().isEmpty()) { + sb.append("<"); + serializeCommaSeparated(fun.getTypeParameters(), sb); + sb.append(">"); + } + sb.append(fun.getName()); + sb.append("("); + serializeCommaSeparated(fun.getValueParameters(), sb); + sb.append("): "); + serialize(fun.getReturnType(), sb); + } + + private void serialize(ValueParameterDescriptor valueParameter, StringBuilder sb) { + sb.append(valueParameter.getName()); + sb.append(": "); + if (valueParameter.getVarargElementType() != null) { + sb.append("vararg "); + serialize(valueParameter.getVarargElementType()); + } else { + serialize(valueParameter.getOutType()); + } + if (valueParameter.hasDefaultValue()) { + sb.append(" = ?"); + } + } + + private void serialize(Variance variance, StringBuilder sb) { + sb.append(variance); + } + + private void serialize(JetType type, StringBuilder sb) { + serialize(type.getConstructor().getDeclarationDescriptor(), sb); + if (!type.getArguments().isEmpty()) { + sb.append("<"); + boolean first = true; + for (TypeProjection proj : type.getArguments()) { + serialize(proj.getProjectionKind(), sb); + serialize(proj.getType(), sb); + if (!first) { + sb.append(", "); + } + first = false; + } + sb.append(">"); + } + } + + private String serialize(Object o) { + StringBuilder sb = new StringBuilder(); + serialize(o, sb); + return sb.toString(); + } + + private void serializeCommaSeparated(List list, StringBuilder sb) { + boolean first = true; + for (Object o : list) { + if (!first) { + sb.append(", "); + } + serialize(o, sb); + first = false; + } + } + + private void serialize(Object o, StringBuilder sb) { + // TODO: cache + for (Method method : ReadClassDataTest.class.getDeclaredMethods()) { + if (!method.getName().equals("serialize")) { + continue; + } + if (method.getParameterTypes().length != 2) { + continue; + } + if (!method.getParameterTypes()[1].equals(StringBuilder.class)) { + continue; + } + if (method.getParameterTypes()[0].equals(Object.class)) { + continue; + } + if (method.getParameterTypes()[0].isInstance(o)) { + invoke(method, this, o, sb); + return; + } + } + throw new IllegalStateException("don't know how to serialize " + o + " (of " + o.getClass() + ")"); + } + + private void serialize(ModuleDescriptor module, StringBuilder sb) { + // nop + } + + private void serialize(ClassDescriptor clazz, StringBuilder sb) { + serialize(clazz.getContainingDeclaration(), sb); + sb.append("."); + sb.append(clazz.getName()); + } + + private void serialize(NamespaceDescriptor ns, StringBuilder sb) { + if (ns.getContainingDeclaration() == null) { + // root ns + return; + } + serialize(ns.getContainingDeclaration(), sb); + sb.append("."); + sb.append(ns.getName()); + } + + private void serialize(TypeParameterDescriptor param, StringBuilder sb) { + if (param.getVariance() != Variance.INVARIANT) { + serialize(param.getVariance(), sb); + } + sb.append(param.getName()); + // TODO: serialize bounds + } + public static Test suite() { return JetTestCaseBuilder.suiteForDirectory(JetTestCaseBuilder.getTestDataPathBase(), "/readClass", true, new JetTestCaseBuilder.NamedTestFactory() { From cbe6dcc8c21c4fc8d1734757f9fa737b6f15ec2c Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Thu, 15 Dec 2011 03:04:21 +0400 Subject: [PATCH 21/33] dummy implementation of method type parameters reader and refactoring --- .../jet/codegen/BothSignatureWriter.java | 13 +++- .../jetbrains/jet/codegen/ClosureCodegen.java | 4 +- .../jet/codegen/FunctionCodegen.java | 3 + .../codegen/ImplementationBodyCodegen.java | 2 +- .../jetbrains/jet/codegen/JetTypeMapper.java | 16 ++-- .../jet/codegen/JvmMethodSignature.java | 9 ++- .../resolve/java/JavaDescriptorResolver.java | 71 ++++++++++++++++- .../jet/lang/resolve/java/StdlibNames.java | 3 +- stdlib/src/jet/typeinfo/JetMethod.java | 6 ++ .../org/jetbrains/jet/rt/TypeInfoParser.java | 78 ++++++++++--------- .../jet/rt/signature/JetSignatureAdapter.java | 7 +- .../JetSignatureExceptionsAdapter.java | 7 +- .../jet/rt/signature/JetSignatureReader.java | 8 +- .../jet/rt/signature/JetSignatureVisitor.java | 4 +- .../jet/rt/signature/JetSignatureWriter.java | 7 +- 15 files changed, 178 insertions(+), 60 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java b/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java index d83d838cb95..440d0587873 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java @@ -200,6 +200,10 @@ public class BothSignatureWriter { signatureVisitor().visitFormalTypeParameter(name); jetSignatureWriter.visitFormalTypeParameter(name, translateVariance(variance)); } + + public void writeFormalTypeParameterEnd() { + jetSignatureWriter.visitFormalTypeParameterEnd(); + } public void writerFormalTypeParametersStart() { checkTopLevel(); @@ -342,9 +346,9 @@ public class BothSignatureWriter { // TODO: return null if not generic return signatureWriter.toString(); } - + @NotNull - public List makeKotlinSignatures() { + public List makeKotlinParameterTypes() { checkState(State.METHOD_END); // TODO: return nulls if equal to #makeJavaString return kotlinParameterTypes; @@ -355,6 +359,11 @@ public class BothSignatureWriter { checkState(State.METHOD_END); return kotlinReturnType; } + + public String makeKotlinMethodTypeParameters() { + checkState(State.METHOD_END); + return kotlinClassParameters; + } @Nullable public String makeKotlinClassSignature() { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java index 75e3d28323a..6ace88a728b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java @@ -53,7 +53,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { public static CallableMethod asCallableMethod(FunctionDescriptor fd) { Method descriptor = erasedInvokeSignature(fd); String owner = getInternalClassName(fd); - final CallableMethod result = new CallableMethod(owner, new JvmMethodSignature(descriptor, null, null, null), INVOKEVIRTUAL, Arrays.asList(descriptor.getArgumentTypes())); + final CallableMethod result = new CallableMethod(owner, new JvmMethodSignature(descriptor, null, null, null, null), INVOKEVIRTUAL, Arrays.asList(descriptor.getArgumentTypes())); if (fd.getReceiverParameter().exists()) { result.setNeedsReceiver(fd); } @@ -165,7 +165,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { final CodegenContext.ClosureContext closureContext = context.intoClosure(funDescriptor, function, name, this, state.getTypeMapper()); FunctionCodegen fc = new FunctionCodegen(closureContext, cv, state); - fc.generateMethod(body, new JvmMethodSignature(invokeSignature(funDescriptor), null, null, null), funDescriptor); + fc.generateMethod(body, new JvmMethodSignature(invokeSignature(funDescriptor), null, null, null, null), funDescriptor); return closureContext.outerWasUsed; } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 27cea25ce10..001ff53bf88 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -93,6 +93,9 @@ public class FunctionCodegen { if (jvmSignature.getKotlinReturnType() != null) { av.visit(StdlibNames.JET_METHOD_RETURN_TYPE_FIELD, jvmSignature.getKotlinReturnType()); } + if (jvmSignature.getKotlinTypeParameter() != null) { + av.visit(StdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD, jvmSignature.getKotlinTypeParameter()); + } av.visitEnd(); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index da2066e7623..1fe54ebc47f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -323,7 +323,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } constructorMethod = new Method("", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()])); - callableMethod = new CallableMethod("", new JvmMethodSignature(constructorMethod, null, null, null) /* TODO */, Opcodes.INVOKESPECIAL, Collections.emptyList()); + callableMethod = new CallableMethod("", new JvmMethodSignature(constructorMethod, null, null, null, null) /* TODO */, Opcodes.INVOKESPECIAL, Collections.emptyList()); } else { callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, kind); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 45344286ed0..0272124ec9b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -519,10 +519,12 @@ public class JetTypeMapper { } Method method = new Method(f.getName(), returnType, parameterTypes.toArray(new Type[parameterTypes.size()])); if (signatureVisitor == null) { - return new JvmMethodSignature(method, null, null, null); + return new JvmMethodSignature(method, null, null, null, null); } else { return new JvmMethodSignature(method, signatureVisitor.makeJavaString(), - signatureVisitor.makeKotlinSignatures(), signatureVisitor.makeKotlinReturnTypeSignature()); + signatureVisitor.makeKotlinMethodTypeParameters(), + signatureVisitor.makeKotlinParameterTypes(), + signatureVisitor.makeKotlinReturnTypeSignature()); } } @@ -568,6 +570,8 @@ public class JetTypeMapper { } } } + + signatureVisitor.writeFormalTypeParameterEnd(); } @@ -583,7 +587,7 @@ public class JetTypeMapper { } Type returnType = mapReturnType(f.getReturnType()); // TODO: proper generic signature - return new JvmMethodSignature(new Method(name, returnType, parameterTypes.toArray(new Type[parameterTypes.size()])), null, null, null); + return new JvmMethodSignature(new Method(name, returnType, parameterTypes.toArray(new Type[parameterTypes.size()])), null, null, null, null); } @@ -608,7 +612,7 @@ public class JetTypeMapper { } // TODO: proper generic signature - return new JvmMethodSignature(new Method(name, returnType, params.toArray(new Type[params.size()])), null, null, null); + return new JvmMethodSignature(new Method(name, returnType, params.toArray(new Type[params.size()])), null, null, null, null); } @Nullable @@ -638,7 +642,7 @@ public class JetTypeMapper { params.add(mapType(inType)); // TODO: proper generic signature - return new JvmMethodSignature(new Method(name, Type.VOID_TYPE, params.toArray(new Type[params.size()])), null, null, null); + return new JvmMethodSignature(new Method(name, Type.VOID_TYPE, params.toArray(new Type[params.size()])), null, null, null, null); } private JvmMethodSignature mapConstructorSignature(ConstructorDescriptor descriptor, List valueParameterTypes) { @@ -660,7 +664,7 @@ public class JetTypeMapper { } Method method = new Method("", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()])); - return new JvmMethodSignature(method, null, null, null); // TODO: generics signature + return new JvmMethodSignature(method, null, null, null, null); // TODO: generics signature } public CallableMethod mapToCallableMethod(ConstructorDescriptor descriptor, OwnerKind kind) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JvmMethodSignature.java b/compiler/backend/src/org/jetbrains/jet/codegen/JvmMethodSignature.java index 6eda7035501..2deac1ab39b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JvmMethodSignature.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JvmMethodSignature.java @@ -14,14 +14,15 @@ public class JvmMethodSignature { private final Method asmMethod; /** Null when we don't care about type parameters */ private final String genericsSignature; - // TODO: type parameters + private final String kotlinTypeParameter; private final List kotlinParameterTypes; private final String kotlinReturnType; public JvmMethodSignature(@NotNull Method asmMethod, @Nullable String genericsSignature, - @Nullable List kotlinParameterTypes, @Nullable String kotlinReturnType) { + @Nullable String kotlinTypeParameters, @Nullable List kotlinParameterTypes, @Nullable String kotlinReturnType) { this.asmMethod = asmMethod; this.genericsSignature = genericsSignature; + this.kotlinTypeParameter = kotlinTypeParameters; this.kotlinParameterTypes = kotlinParameterTypes; this.kotlinReturnType = kotlinReturnType; } @@ -34,6 +35,10 @@ public class JvmMethodSignature { return genericsSignature; } + public String getKotlinTypeParameter() { + return kotlinTypeParameter; + } + public List getKotlinParameterTypes() { return kotlinParameterTypes; } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index 473600d3bb3..9be475af778 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -8,6 +8,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.search.DelegatingGlobalSearchScope; import com.intellij.psi.search.GlobalSearchScope; +import jet.typeinfo.TypeInfoVariance; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; @@ -16,6 +17,9 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.plugin.JetFileType; +import org.jetbrains.jet.rt.signature.JetSignatureExceptionsAdapter; +import org.jetbrains.jet.rt.signature.JetSignatureReader; +import org.jetbrains.jet.rt.signature.JetSignatureVisitor; import java.util.*; @@ -503,8 +507,7 @@ public class JavaDescriptorResolver { method.getName() ); methodDescriptorCache.put(method, functionDescriptorImpl); - List typeParameters = makeUninitializedTypeParameters(functionDescriptorImpl, method.getTypeParameters()); - initializeTypeParameters(method); + List typeParameters = resolveMethodTypeParameters(method, functionDescriptorImpl); functionDescriptorImpl.initialize( null, DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor), @@ -522,6 +525,70 @@ public class JavaDescriptorResolver { return substitutedFunctionDescriptor; } + private List resolveMethodTypeParameters(PsiMethod method, FunctionDescriptorImpl functionDescriptorImpl) { + for (PsiAnnotation annotation : method.getModifierList().getAnnotations()) { + if (annotation.getQualifiedName().equals(StdlibNames.JET_METHOD_CLASS)) { + PsiLiteralExpression attributeValue = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD); + if (attributeValue != null) { + String typeParametersString = (String) attributeValue.getValue(); + if (typeParametersString != null) { + return resolveMethodTypeParametersFromJetSignature(typeParametersString, functionDescriptorImpl); + } + } + } + } + + List typeParameters = makeUninitializedTypeParameters(functionDescriptorImpl, method.getTypeParameters()); + initializeTypeParameters(method); + return typeParameters; + } + + private List resolveMethodTypeParametersFromJetSignature(String jetSignature, final FunctionDescriptor functionDescriptor) { + final List r = new ArrayList(); + new JetSignatureReader(jetSignature).acceptFormalTypeParametersOnly(new JetSignatureExceptionsAdapter() { + @Override + public JetSignatureVisitor visitFormalTypeParameter(final String name, TypeInfoVariance variance) { + + return new JetSignatureExceptionsAdapter() { + int index = 0; + + @Override + public JetSignatureVisitor visitClassBound() { + return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) { + @Override + protected void done(@NotNull JetType jetType) { + // TODO + } + }; + } + + @Override + public JetSignatureVisitor visitInterfaceBound() { + return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) { + @Override + protected void done(@NotNull JetType jetType) { + // TODO + } + }; + } + + @Override + public void visitFormalTypeParameterEnd() { + TypeParameterDescriptor typeParameter = TypeParameterDescriptor.createForFurtherModification( + functionDescriptor, + Collections.emptyList(), // TODO: wrong + true, // TODO: wrong + Variance.INVARIANT, // TOOD: wrong + name, + ++index); + r.add(typeParameter); + } + }; + } + }); + return r; + } + private JetType makeReturnType(PsiType returnType, PsiMethod method) { boolean changeNullable = false; boolean nullable = true; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/StdlibNames.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/StdlibNames.java index c6223502385..6e3e8abeb34 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/StdlibNames.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/StdlibNames.java @@ -27,7 +27,8 @@ public class StdlibNames { public static final String JET_METHOD_NULLABLE_RETURN_TYPE_FIELD = "nullableReturnType"; public static final String JET_METHOD_RETURN_TYPE_FIELD = "returnType"; - + public static final String JET_METHOD_TYPE_PARAMETERS_FIELD = "typeParameters"; + public static final String JET_OBJECT_INTERNAL = "jet/JetObject"; public static final String JET_OBJECT_CLASS = "jet.JetObject"; diff --git a/stdlib/src/jet/typeinfo/JetMethod.java b/stdlib/src/jet/typeinfo/JetMethod.java index b057014caf2..8bca6f9db5a 100644 --- a/stdlib/src/jet/typeinfo/JetMethod.java +++ b/stdlib/src/jet/typeinfo/JetMethod.java @@ -22,6 +22,12 @@ public @interface JetMethod { */ JetTypeProjection[] returnTypeProjections() default {}; + /** + * Serialized method type parameters. + * @return + */ + String typeParameters() default ""; + /** * @return is this type returnTypeNullable */ diff --git a/stdlib/src/org/jetbrains/jet/rt/TypeInfoParser.java b/stdlib/src/org/jetbrains/jet/rt/TypeInfoParser.java index 1a3b67a3d2e..78fa32782e4 100644 --- a/stdlib/src/org/jetbrains/jet/rt/TypeInfoParser.java +++ b/stdlib/src/org/jetbrains/jet/rt/TypeInfoParser.java @@ -71,52 +71,56 @@ class TypeInfoParser { signature.varNames = new HashMap(); signature.superTypes = new ArrayList(); new JetSignatureReader(annotationValue).accept(new JetSignatureExceptionsAdapter() { - int varIndex = 0; @Override - public void visitFormalTypeParameter(String name, final TypeInfoVariance variance) { + public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) { - final TypeInfoVar typeInfoVar = new TypeInfoVar(signature, signature.variables.size()); - - signature.varNames.put(name, signature.variables.size()); - TypeInfoProjection typeInfoProjection = new TypeInfoProjection() { - @Override - public TypeInfoVariance getVariance() { - return variance; - } - - @Override - public TypeInfo getType() { - return typeInfoVar; - } - - @Override - public String toString() { - return typeInfoVar.toString(); - } - }; - - signature.variables.add(typeInfoProjection); - // TODO: supers // TODO: nullability - } - @Override - public JetSignatureVisitor visitClassBound() { - return new SignatureParserJetSignatureAdapter(signature.klazz.getClassLoader(), signature) { + return new JetSignatureExceptionsAdapter() { @Override - protected void done(TypeInfo typeInfo) { - // TODO + public JetSignatureVisitor visitClassBound() { + return new SignatureParserJetSignatureAdapter(signature.klazz.getClassLoader(), signature) { + @Override + protected void done(TypeInfo typeInfo) { + // TODO + } + }; } - }; - } - @Override - public JetSignatureVisitor visitInterfaceBound() { - return new SignatureParserJetSignatureAdapter(signature.klazz.getClassLoader(), signature) { @Override - protected void done(TypeInfo typeInfo) { - // TODO + public JetSignatureVisitor visitInterfaceBound() { + return new SignatureParserJetSignatureAdapter(signature.klazz.getClassLoader(), signature) { + @Override + protected void done(TypeInfo typeInfo) { + // TODO + } + }; + } + + @Override + public void visitFormalTypeParameterEnd() { + final TypeInfoVar typeInfoVar = new TypeInfoVar(signature, signature.variables.size()); + + signature.varNames.put(name, signature.variables.size()); + TypeInfoProjection typeInfoProjection = new TypeInfoProjection() { + @Override + public TypeInfoVariance getVariance() { + return variance; + } + + @Override + public TypeInfo getType() { + return typeInfoVar; + } + + @Override + public String toString() { + return typeInfoVar.toString(); + } + }; + + signature.variables.add(typeInfoProjection); } }; } diff --git a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureAdapter.java b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureAdapter.java index 3366e3b410f..5d9878b3110 100644 --- a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureAdapter.java +++ b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureAdapter.java @@ -7,7 +7,12 @@ import jet.typeinfo.TypeInfoVariance; */ public class JetSignatureAdapter implements JetSignatureVisitor { @Override - public void visitFormalTypeParameter(String name, TypeInfoVariance variance) { + public JetSignatureVisitor visitFormalTypeParameter(String name, TypeInfoVariance variance) { + return this; + } + + @Override + public void visitFormalTypeParameterEnd() { } @Override diff --git a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureExceptionsAdapter.java b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureExceptionsAdapter.java index cca55b64951..1d6be28930f 100644 --- a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureExceptionsAdapter.java +++ b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureExceptionsAdapter.java @@ -7,7 +7,12 @@ import jet.typeinfo.TypeInfoVariance; */ public class JetSignatureExceptionsAdapter implements JetSignatureVisitor { @Override - public void visitFormalTypeParameter(String name, TypeInfoVariance variance) { + public JetSignatureVisitor visitFormalTypeParameter(String name, TypeInfoVariance variance) { + throw new IllegalStateException(); + } + + @Override + public void visitFormalTypeParameterEnd() { throw new IllegalStateException(); } diff --git a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureReader.java b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureReader.java index 49624917f09..a163c8c6d4d 100644 --- a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureReader.java +++ b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureReader.java @@ -59,17 +59,19 @@ public class JetSignatureReader { if (end < 0) { throw new IllegalStateException(); } - v.visitFormalTypeParameter(signature.substring(pos, end), variance); + JetSignatureVisitor parameterVisitor = v.visitFormalTypeParameter(signature.substring(pos, end), variance); pos = end + 1; c = signature.charAt(pos); if (c == 'L' || c == '[' || c == 'T' || c == '?') { - pos = parseType(signature, pos, v.visitClassBound()); + pos = parseType(signature, pos, parameterVisitor.visitClassBound()); } while ((c = signature.charAt(pos++)) == ':') { - pos = parseType(signature, pos, v.visitInterfaceBound()); + pos = parseType(signature, pos, parameterVisitor.visitInterfaceBound()); } + + parameterVisitor.visitFormalTypeParameterEnd(); } while (c != '>'); } else { pos = 0; diff --git a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureVisitor.java b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureVisitor.java index ee7bfc3e2d1..2a16f087c1c 100644 --- a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureVisitor.java +++ b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureVisitor.java @@ -30,7 +30,9 @@ public interface JetSignatureVisitor { * * @param name the name of the formal parameter. */ - void visitFormalTypeParameter(String name, TypeInfoVariance variance); + JetSignatureVisitor visitFormalTypeParameter(String name, TypeInfoVariance variance); + + void visitFormalTypeParameterEnd(); /** * Visits the class bound of the last visited formal type parameter. diff --git a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureWriter.java b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureWriter.java index 9bd16db1c52..9db334ccefb 100644 --- a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureWriter.java +++ b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureWriter.java @@ -43,7 +43,7 @@ public class JetSignatureWriter implements JetSignatureVisitor { // ------------------------------------------------------------------------ @Override - public void visitFormalTypeParameter(final String name, TypeInfoVariance variance) { + public JetSignatureVisitor visitFormalTypeParameter(final String name, TypeInfoVariance variance) { if (!hasFormals) { hasFormals = true; buf.append('<'); @@ -62,6 +62,11 @@ public class JetSignatureWriter implements JetSignatureVisitor { } buf.append(name); buf.append(':'); + return this; + } + + @Override + public void visitFormalTypeParameterEnd() { } @Override From 5c819cb77e5d48a7fbe2b0bebdd3d3e4f1f4497e Mon Sep 17 00:00:00 2001 From: svtk Date: Thu, 15 Dec 2011 16:24:47 +0400 Subject: [PATCH 22/33] KT-816 Add std namespace in to default imports --- .../jet/lang/resolve/java/AnalyzerFacade.java | 11 +++-- .../resolve/java/JavaBridgeConfiguration.java | 14 ++++--- .../org/jetbrains/jet/lang/Configuration.java | 8 ++-- .../jet/lang/StandardConfiguration.java | 42 +++++++++++++++++++ .../jet/lang/resolve/AnalyzingUtils.java | 24 +++++------ .../jet/lang/resolve/ImportsResolver.java | 23 ++++++---- .../jet/lang/resolve/TopDownAnalyzer.java | 4 +- .../jet/checkers/JetDiagnosticsTest.java | 3 +- 8 files changed, 95 insertions(+), 34 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/StandardConfiguration.java diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacade.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacade.java index e21ac04214f..c7501b85c78 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacade.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AnalyzerFacade.java @@ -12,6 +12,8 @@ import com.intellij.psi.util.CachedValuesManager; import com.intellij.psi.util.PsiModificationTracker; import com.intellij.util.Function; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.JetSemanticServices; +import org.jetbrains.jet.lang.StandardConfiguration; import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; import org.jetbrains.jet.lang.diagnostics.Errors; @@ -80,12 +82,15 @@ public class AnalyzerFacade { public static BindingContext analyzeNamespacesWithJavaIntegration(Project project, Collection declarations, Predicate filesToAnalyzeCompletely, JetControlFlowDataTraceFactory flowDataTraceFactory) { BindingTraceContext bindingTraceContext = new BindingTraceContext(); - return AnalyzingUtils.getInstance().analyzeNamespacesWithGivenTrace( + JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(project); + return AnalyzingUtils.analyzeNamespacesWithGivenTrace( project, - JavaBridgeConfiguration.createJavaBridgeConfiguration(project, bindingTraceContext), + JavaBridgeConfiguration.createJavaBridgeConfiguration(project, bindingTraceContext, StandardConfiguration.createStandardConfiguration(project, semanticServices)), declarations, filesToAnalyzeCompletely, - flowDataTraceFactory, bindingTraceContext); + flowDataTraceFactory, + bindingTraceContext, + semanticServices); } public static BindingContext shallowAnalyzeFiles(Collection files) { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaBridgeConfiguration.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaBridgeConfiguration.java index a160b707229..d2dc2bd88fa 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaBridgeConfiguration.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaBridgeConfiguration.java @@ -14,24 +14,28 @@ import org.jetbrains.jet.lang.resolve.scopes.WritableScope; */ public class JavaBridgeConfiguration implements Configuration { - public static Configuration createJavaBridgeConfiguration(@NotNull Project project, @NotNull BindingTrace trace) { - return new JavaBridgeConfiguration(project, trace); + public static Configuration createJavaBridgeConfiguration(@NotNull Project project, @NotNull BindingTrace trace, Configuration delegateConfiguration) { + return new JavaBridgeConfiguration(project, trace, delegateConfiguration); } private final JavaSemanticServices javaSemanticServices; + private final Configuration delegateConfiguration; - private JavaBridgeConfiguration(Project project, BindingTrace trace) { + private JavaBridgeConfiguration(Project project, BindingTrace trace, Configuration delegateConfiguration) { this.javaSemanticServices = new JavaSemanticServices(project, JetSemanticServices.createSemanticServices(project), trace); + this.delegateConfiguration = delegateConfiguration; } @Override - public void addDefaultImports(BindingTrace trace, WritableScope rootScope) { + public void addDefaultImports(@NotNull BindingTrace trace, @NotNull WritableScope rootScope) { rootScope.importScope(new JavaPackageScope("", null, javaSemanticServices)); rootScope.importScope(new JavaPackageScope("java.lang", null, javaSemanticServices)); + delegateConfiguration.addDefaultImports(trace, rootScope); } @Override - public void extendNamespaceScope(BindingTrace trace, @NotNull NamespaceDescriptor namespaceDescriptor, @NotNull WritableScope namespaceMemberScope) { + public void extendNamespaceScope(@NotNull BindingTrace trace, @NotNull NamespaceDescriptor namespaceDescriptor, @NotNull WritableScope namespaceMemberScope) { namespaceMemberScope.importScope(new JavaPackageScope(DescriptorUtils.getFQName(namespaceDescriptor), namespaceDescriptor, javaSemanticServices)); + delegateConfiguration.extendNamespaceScope(trace, namespaceDescriptor, namespaceMemberScope); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/Configuration.java b/compiler/frontend/src/org/jetbrains/jet/lang/Configuration.java index e376a6ebaf6..60633836bfc 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/Configuration.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/Configuration.java @@ -11,19 +11,19 @@ import org.jetbrains.jet.lang.resolve.scopes.WritableScope; public interface Configuration { Configuration EMPTY = new Configuration() { @Override - public void addDefaultImports(BindingTrace trace, WritableScope rootScope) { + public void addDefaultImports(@NotNull BindingTrace trace, @NotNull WritableScope rootScope) { } @Override - public void extendNamespaceScope(BindingTrace trace, @NotNull NamespaceDescriptor namespaceDescriptor, @NotNull WritableScope namespaceMemberScope) { + public void extendNamespaceScope(@NotNull BindingTrace trace, @NotNull NamespaceDescriptor namespaceDescriptor, @NotNull WritableScope namespaceMemberScope) { } }; - void addDefaultImports(BindingTrace trace, WritableScope rootScope); + void addDefaultImports(@NotNull BindingTrace trace, @NotNull WritableScope rootScope); /** * * This method is called every time a namespace descriptor is created. Use it to add extra descriptors to the namespace, e.g. merge a Java package with a Kotlin one */ - void extendNamespaceScope(BindingTrace trace, @NotNull NamespaceDescriptor namespaceDescriptor, @NotNull WritableScope namespaceMemberScope); + void extendNamespaceScope(@NotNull BindingTrace trace, @NotNull NamespaceDescriptor namespaceDescriptor, @NotNull WritableScope namespaceMemberScope); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/StandardConfiguration.java b/compiler/frontend/src/org/jetbrains/jet/lang/StandardConfiguration.java new file mode 100644 index 00000000000..e4ddbd8f033 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/StandardConfiguration.java @@ -0,0 +1,42 @@ +package org.jetbrains.jet.lang; + +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.psi.JetImportDirective; +import org.jetbrains.jet.lang.psi.JetPsiFactory; +import org.jetbrains.jet.lang.resolve.BindingTrace; +import org.jetbrains.jet.lang.resolve.ImportsResolver; +import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace; +import org.jetbrains.jet.lang.resolve.scopes.WritableScope; + +/** + * @author svtk + */ +public class StandardConfiguration implements Configuration { + private Project project; + private JetSemanticServices services; + + public static StandardConfiguration createStandardConfiguration(Project project, JetSemanticServices services) { + return new StandardConfiguration(services, project); + } + + private StandardConfiguration(JetSemanticServices services, Project project) { + this.services = services; + this.project = project; + } + + @Override + public void addDefaultImports(@NotNull BindingTrace trace, @NotNull WritableScope rootScope) { + TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace); + JetImportDirective importDirective = JetPsiFactory.createImportDirective(project, "std.*"); + if (ImportsResolver.importNamespace(importDirective, rootScope, temporaryTrace, services)) { + temporaryTrace.commit(); + } + } + + @Override + public void extendNamespaceScope(@NotNull BindingTrace trace, @NotNull NamespaceDescriptor namespaceDescriptor, @NotNull WritableScope namespaceMemberScope) { + } + +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java index 7e5d791edd3..911a7d778fb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java @@ -31,12 +31,6 @@ import java.util.Map; */ public class AnalyzingUtils { - private static final AnalyzingUtils INSTANCE = new AnalyzingUtils(); - - public static AnalyzingUtils getInstance() { - return INSTANCE; - } - public static void checkForSyntacticErrors(@NotNull PsiElement root) { root.acceptChildren(new PsiElementVisitor() { @Override @@ -75,19 +69,25 @@ public class AnalyzingUtils { // -------------------------------------------------------------------------------------------------------------------------- - public BindingContext analyzeNamespaces( + public static BindingContext analyzeNamespaces( @NotNull Project project, @NotNull Configuration configuration, @NotNull Collection declarations, @NotNull Predicate filesToAnalyzeCompletely, - @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) { + @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory, + @NotNull JetSemanticServices semanticServices) { BindingTraceContext bindingTraceContext = new BindingTraceContext(); - return analyzeNamespacesWithGivenTrace(project, configuration, declarations, filesToAnalyzeCompletely, flowDataTraceFactory, bindingTraceContext); + return analyzeNamespacesWithGivenTrace(project, configuration, declarations, filesToAnalyzeCompletely, flowDataTraceFactory, bindingTraceContext, semanticServices); } - public BindingContext analyzeNamespacesWithGivenTrace(Project project, Configuration configuration, Collection declarations, Predicate filesToAnalyzeCompletely, JetControlFlowDataTraceFactory flowDataTraceFactory, BindingTraceContext bindingTraceContext) { - JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(project); - + public static BindingContext analyzeNamespacesWithGivenTrace( + @NotNull Project project, + @NotNull Configuration configuration, + @NotNull Collection declarations, + @NotNull Predicate filesToAnalyzeCompletely, + @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory, + @NotNull BindingTraceContext bindingTraceContext, + @NotNull JetSemanticServices semanticServices) { JetScope libraryScope = semanticServices.getStandardLibrary().getLibraryScope(); ModuleDescriptor owner = new ModuleDescriptor(""); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java index a96ce5d3f4a..a4c30b5fb32 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java @@ -1,6 +1,7 @@ package org.jetbrains.jet.lang.resolve; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.psi.*; @@ -40,14 +41,7 @@ public class ImportsResolver { continue; } if (importDirective.isAllUnder()) { - JetExpression importedReference = importDirective.getImportedReference(); - if (importedReference != null) { - ExpressionTypingServices typeInferrerServices = context.getSemanticServices().getTypeInferrerServices(context.getTrace()); - JetType type = typeInferrerServices.getTypeWithNamespaces(namespaceScope, importedReference); - if (type != null) { - namespaceScope.importScope(type.getMemberScope()); - } - } + importNamespace(importDirective, namespaceScope, context.getTrace(), context.getSemanticServices()); } else { ClassifierDescriptor classifierDescriptor = null; @@ -105,4 +99,17 @@ public class ImportsResolver { } } } + + public static boolean importNamespace(JetImportDirective importDirective, WritableScope namespaceScope, @NotNull BindingTrace trace, @NotNull JetSemanticServices services) { + JetExpression importedReference = importDirective.getImportedReference(); + if (importedReference != null) { + ExpressionTypingServices typeInferrerServices = services.getTypeInferrerServices(trace); + JetType type = typeInferrerServices.getTypeWithNamespaces(namespaceScope, importedReference); + if (type != null) { + namespaceScope.importScope(type.getMemberScope()); + return true; + } + } + return false; + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java index 7760ae9f44e..a47e6a7e8ae 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java @@ -91,7 +91,9 @@ public class TopDownAnalyzer { public static void processStandardLibraryNamespace( @NotNull JetSemanticServices semanticServices, @NotNull BindingTrace trace, - @NotNull WritableScope outerScope, @NotNull NamespaceDescriptorImpl standardLibraryNamespace, @NotNull JetNamespace namespace) { + @NotNull WritableScope outerScope, + @NotNull NamespaceDescriptorImpl standardLibraryNamespace, + @NotNull JetNamespace namespace) { TopDownAnalysisContext context = new TopDownAnalysisContext(semanticServices, trace, Predicates.alwaysTrue(), Configuration.EMPTY, false); context.getNamespaceScopes().put(namespace, standardLibraryNamespace.getMemberScope()); context.getNamespaceDescriptors().put(namespace, standardLibraryNamespace); diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTest.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTest.java index e661113e310..464e7e6de8b 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTest.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTest.java @@ -10,6 +10,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.JetLiteFixture; import org.jetbrains.jet.JetTestCaseBuilder; import org.jetbrains.jet.lang.Configuration; +import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; import org.jetbrains.jet.lang.psi.JetDeclaration; @@ -94,7 +95,7 @@ public class JetDiagnosticsTest extends JetLiteFixture { bindingContext = AnalyzerFacade.analyzeNamespacesWithJavaIntegration(getProject(), namespaces, Predicates.alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY); } else { - bindingContext = AnalyzingUtils.getInstance().analyzeNamespaces(getProject(), Configuration.EMPTY, namespaces, Predicates.alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY); + bindingContext = AnalyzingUtils.analyzeNamespaces(getProject(), Configuration.EMPTY, namespaces, Predicates.alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY, JetSemanticServices.createSemanticServices(getProject())); } StringBuilder actualText = new StringBuilder(); From 966fd8806542415b9919bb8617ee18002ce95a7e Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Thu, 15 Dec 2011 18:23:44 +0400 Subject: [PATCH 23/33] Patch by Sergey Ignatov: KT-841 Add constructor by default for abstract classes from Java --- .../jet/lang/resolve/java/JavaDescriptorResolver.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index 9be475af778..9a2bd50a811 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -163,7 +163,11 @@ public class JavaDescriptorResolver { PsiMethod[] psiConstructors = psiClass.getConstructors(); if (psiConstructors.length == 0) { - if (!psiClass.hasModifierProperty(PsiModifier.ABSTRACT) && !psiClass.isInterface()) { + // We need to create default constructors for classes and abstract classes. + // Example: + // class Kotlin() : Java() {} + // abstract public class Java {} + if (!psiClass.isInterface()) { ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl( classDescriptor, Collections.emptyList(), From c923d37f831a84863edf158a00045ad3a13b276a Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Thu, 15 Dec 2011 17:21:56 +0200 Subject: [PATCH 24/33] class object field access --- .../org/jetbrains/jet/codegen/ExpressionCodegen.java | 10 +++++++++- .../tests/org/jetbrains/jet/codegen/ClassGenTest.java | 6 ++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 4513595264f..39101c75e48 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1254,7 +1254,15 @@ public class ExpressionCodegen extends JetVisitor { if(descriptor instanceof ClassReceiver) { Type exprType = asmType(descriptor.getType()); ClassReceiver classReceiver = (ClassReceiver) descriptor; - generateThisOrOuter((ClassDescriptor) classReceiver.getDeclarationDescriptor()).put(exprType, v); + ClassDescriptor classReceiverDeclarationDescriptor = (ClassDescriptor) classReceiver.getDeclarationDescriptor(); + if(CodegenUtil.isClassObject(classReceiverDeclarationDescriptor)) { + ClassDescriptor containingDeclaration = (ClassDescriptor) classReceiverDeclarationDescriptor.getContainingDeclaration(); + Type classObjType = typeMapper.mapType(containingDeclaration.getDefaultType()); + v.getstatic(classObjType.getInternalName(), "$classobj", exprType.getDescriptor()); + } + else { + generateThisOrOuter(classReceiverDeclarationDescriptor).put(exprType, v); + } if(type != null) StackValue.onStack(exprType).put(type, v); } diff --git a/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java index 88e445a6bb1..9312dadc793 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java @@ -166,6 +166,12 @@ public class ClassGenTest extends CodegenTestCase { assertEquals(0xFF0000, rgbMethod.invoke(redValue)); } + public void testClassObjFields() throws Exception { + loadText("class A() { class object { val value = 10 } }\n" + + "fun box() = if(A.value == 10) \"OK\" else \"fail\""); + blackBox(); + } + public void testKt249() throws Exception { blackBoxFile("regressions/kt249.jet"); } From a687580a399489f30bcb425c247275f3abd1d98c Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Thu, 15 Dec 2011 20:15:28 +0400 Subject: [PATCH 25/33] rename @JetSignature to @JetClass, better constants in StdlibNames --- .../jet/codegen/FunctionCodegen.java | 8 ++-- .../codegen/ImplementationBodyCodegen.java | 7 ++-- .../resolve/java/JavaDescriptorResolver.java | 8 ++-- .../jet/lang/resolve/java/JvmClassName.java | 42 +++++++++++++++++++ .../jet/lang/resolve/java/StdlibNames.java | 25 +++++------ .../{JetSignature.java => JetClass.java} | 4 +- .../org/jetbrains/jet/rt/TypeInfoParser.java | 6 +-- 7 files changed, 71 insertions(+), 29 deletions(-) create mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmClassName.java rename stdlib/src/jet/typeinfo/{JetSignature.java => JetClass.java} (85%) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 001ff53bf88..befdaf21a7e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -100,12 +100,12 @@ public class FunctionCodegen { } if(kind == OwnerKind.TRAIT_IMPL) { - AnnotationVisitor av = mv.visitParameterAnnotation(start++, StdlibNames.JET_VALUE_PARAMETER_DESCRIPTOR, true); + AnnotationVisitor av = mv.visitParameterAnnotation(start++, StdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true); av.visit(StdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, "this$self"); av.visitEnd(); } if(receiverParameter.exists()) { - AnnotationVisitor av = mv.visitParameterAnnotation(start++, StdlibNames.JET_VALUE_PARAMETER_DESCRIPTOR, true); + AnnotationVisitor av = mv.visitParameterAnnotation(start++, StdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true); av.visit(StdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, "this$receiver"); if(receiverParameter.getType().isNullable()) { av.visit(StdlibNames.JET_VALUE_PARAMETER_NULLABLE_FIELD, true); @@ -113,12 +113,12 @@ public class FunctionCodegen { av.visitEnd(); } for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) { - AnnotationVisitor av = mv.visitParameterAnnotation(start++, StdlibNames.JET_TYPE_PARAMETER_DESCRIPTOR, true); + AnnotationVisitor av = mv.visitParameterAnnotation(start++, StdlibNames.JET_TYPE_PARAMETER.getDescriptor(), true); av.visit(StdlibNames.JET_TYPE_PARAMETER_NAME_FIELD, typeParameterDescriptor.getName()); av.visitEnd(); } for(int i = 0; i != paramDescrs.size(); ++i) { - AnnotationVisitor av = mv.visitParameterAnnotation(i + start, StdlibNames.JET_VALUE_PARAMETER_DESCRIPTOR, true); + AnnotationVisitor av = mv.visitParameterAnnotation(i + start, StdlibNames.JET_VALUE_PARAMETER.getDescriptor(), true); ValueParameterDescriptor parameterDescriptor = paramDescrs.get(i); av.visit(StdlibNames.JET_VALUE_PARAMETER_NAME_FIELD, parameterDescriptor.getName()); if(parameterDescriptor.hasDefaultValue()) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 1fe54ebc47f..2d36920442d 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -72,9 +72,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } if(myClass instanceof JetClass && signature.getKotlinGenericSignature() != null) { - AnnotationVisitor annotationVisitor = v.newAnnotation(myClass, "Ljet/typeinfo/JetSignature;", true); - //annotationVisitor.visit("value", SignatureUtil.classToSignature((JetClass)myClass, bindingContext, typeMapper)); - annotationVisitor.visit("value", signature.getKotlinGenericSignature()); + AnnotationVisitor annotationVisitor = v.newAnnotation(myClass, StdlibNames.JET_CLASS.getDescriptor(), true); + annotationVisitor.visit(StdlibNames.JET_CLASS_SIGNATURE, signature.getKotlinGenericSignature()); annotationVisitor.visitEnd(); } } @@ -107,7 +106,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { { // superinterfaces - superInterfacesLinkedHashSet.add(StdlibNames.JET_OBJECT_INTERNAL); + superInterfacesLinkedHashSet.add(StdlibNames.JET_OBJECT.getInternalName()); for (JetDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) { JetType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference()); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index 9be475af778..e9cba2cc458 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -377,7 +377,7 @@ public class JavaDescriptorResolver { PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes(); attributes.toString(); - if (annotation.getQualifiedName().equals(StdlibNames.JET_VALUE_PARAMETER_CLASS)) { + if (annotation.getQualifiedName().equals(StdlibNames.JET_VALUE_PARAMETER.getFqName())) { PsiLiteralExpression nameExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_VALUE_PARAMETER_NAME_FIELD); if (nameExpression != null) { name = (String) nameExpression.getValue(); @@ -396,7 +396,7 @@ public class JavaDescriptorResolver { if (signatureExpression != null) { typeFromAnnotation = (String) signatureExpression.getValue(); } - } else if (annotation.getQualifiedName().equals(StdlibNames.JET_TYPE_PARAMETER_CLASS)) { + } else if (annotation.getQualifiedName().equals(StdlibNames.JET_TYPE_PARAMETER.getFqName())) { return null; } } @@ -527,7 +527,7 @@ public class JavaDescriptorResolver { private List resolveMethodTypeParameters(PsiMethod method, FunctionDescriptorImpl functionDescriptorImpl) { for (PsiAnnotation annotation : method.getModifierList().getAnnotations()) { - if (annotation.getQualifiedName().equals(StdlibNames.JET_METHOD_CLASS)) { + if (annotation.getQualifiedName().equals(StdlibNames.JET_METHOD.getFqName())) { PsiLiteralExpression attributeValue = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD); if (attributeValue != null) { String typeParametersString = (String) attributeValue.getValue(); @@ -596,7 +596,7 @@ public class JavaDescriptorResolver { String returnTypeFromAnnotation = null; for (PsiAnnotation annotation : method.getModifierList().getAnnotations()) { - if (annotation.getQualifiedName().equals(StdlibNames.JET_METHOD_CLASS)) { + if (annotation.getQualifiedName().equals(StdlibNames.JET_METHOD.getFqName())) { PsiLiteralExpression nullableExpression = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_METHOD_NULLABLE_RETURN_TYPE_FIELD); if (nullableExpression != null) { nullable = (Boolean) nullableExpression.getValue(); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmClassName.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmClassName.java new file mode 100644 index 00000000000..db1bcac52ff --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmClassName.java @@ -0,0 +1,42 @@ +package org.jetbrains.jet.lang.resolve.java; + +import org.jetbrains.annotations.NotNull; + +/** + * @author Stepan Koltsov + */ +public class JvmClassName { + + private final String fqName; + + public JvmClassName(@NotNull String fqName) { + this.fqName = fqName; + } + + public String getFqName() { + return fqName; + } + + private String internalName; + + public String getInternalName() { + if (internalName == null) { + String descriptor = getDescriptor(); + internalName = descriptor.substring(1, descriptor.length() - 1); + } + return internalName; + } + + private String descriptor; + + public String getDescriptor() { + if (descriptor == null) { + StringBuilder sb = new StringBuilder(fqName.length() + 2); + sb.append('L'); + sb.append(fqName.replace('.', '/')); + sb.append(';'); + descriptor = sb.toString(); + } + return descriptor; + } +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/StdlibNames.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/StdlibNames.java index 6e3e8abeb34..dd071b38631 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/StdlibNames.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/StdlibNames.java @@ -7,32 +7,33 @@ import org.objectweb.asm.Type; */ public class StdlibNames { - public static final String JET_VALUE_PARAMETER_CLASS = "jet.typeinfo.JetValueParameter"; - public static final String JET_VALUE_PARAMETER_DESCRIPTOR = "Ljet/typeinfo/JetValueParameter;"; - + public static final JvmClassName JET_VALUE_PARAMETER = new JvmClassName("jet.typeinfo.JetValueParameter"); + public static final String JET_VALUE_PARAMETER_NAME_FIELD = "name"; public static final String JET_VALUE_PARAMETER_HAS_DEFAULT_VALUE_FIELD = "hasDefaultValue"; public static final String JET_VALUE_PARAMETER_NULLABLE_FIELD = "nullable"; public static final String JET_VALUE_PARAMETER_TYPE_FIELD = "type"; - public static final String JET_TYPE_PARAMETER_CLASS = "jet.typeinfo.JetTypeParameter"; - public static final String JET_TYPE_PARAMETER_DESCRIPTOR = "Ljet/typeinfo/JetTypeParameter;"; - + public static final JvmClassName JET_TYPE_PARAMETER = new JvmClassName("jet.typeinfo.JetTypeParameter"); + public static final String JET_TYPE_PARAMETER_NAME_FIELD = "name"; - public static final String JET_METHOD_CLASS = "jet.typeinfo.JetMethod"; - public static final String JET_METHOD_DESCRIPTOR = "Ljet/typeinfo/JetMethod;"; - + public static final JvmClassName JET_METHOD = new JvmClassName("jet.typeinfo.JetMethod"); + public static final String JET_METHOD_NULLABLE_RETURN_TYPE_FIELD = "nullableReturnType"; public static final String JET_METHOD_RETURN_TYPE_FIELD = "returnType"; public static final String JET_METHOD_TYPE_PARAMETERS_FIELD = "typeParameters"; - public static final String JET_OBJECT_INTERNAL = "jet/JetObject"; - public static final String JET_OBJECT_CLASS = "jet.JetObject"; - public static final String JET_OBJECT_DESCRIPTOR = "Ljet/JetObject;"; + public static final JvmClassName JET_CLASS = new JvmClassName("jet.typeinfo.JetClass"); + + public static final String JET_CLASS_SIGNATURE = "signature"; + + + public static final JvmClassName JET_OBJECT = new JvmClassName("jet.JetObject"); + private StdlibNames() { } diff --git a/stdlib/src/jet/typeinfo/JetSignature.java b/stdlib/src/jet/typeinfo/JetClass.java similarity index 85% rename from stdlib/src/jet/typeinfo/JetSignature.java rename to stdlib/src/jet/typeinfo/JetClass.java index c93f818951b..7a887134347 100644 --- a/stdlib/src/jet/typeinfo/JetSignature.java +++ b/stdlib/src/jet/typeinfo/JetClass.java @@ -11,7 +11,7 @@ import java.util.*; * @url http://confluence.jetbrains.net/display/JET/Jet+Signatures */ @Retention(RetentionPolicy.RUNTIME) -public @interface JetSignature { - String value(); +public @interface JetClass { + String signature(); } diff --git a/stdlib/src/org/jetbrains/jet/rt/TypeInfoParser.java b/stdlib/src/org/jetbrains/jet/rt/TypeInfoParser.java index 78fa32782e4..99910c810e7 100644 --- a/stdlib/src/org/jetbrains/jet/rt/TypeInfoParser.java +++ b/stdlib/src/org/jetbrains/jet/rt/TypeInfoParser.java @@ -1,6 +1,6 @@ package org.jetbrains.jet.rt; -import jet.typeinfo.JetSignature; +import jet.typeinfo.JetClass; import jet.typeinfo.TypeInfo; import jet.typeinfo.TypeInfoProjection; import jet.typeinfo.TypeInfoVariance; @@ -51,9 +51,9 @@ class TypeInfoParser { return signature; } - JetSignature annotation = (JetSignature) klass.getAnnotation(JetSignature.class); + JetClass annotation = (JetClass) klass.getAnnotation(JetClass.class); if(annotation != null) { - String value = annotation.value(); + String value = annotation.signature(); if(value != null) { Class enclosingClass = klass.getEnclosingClass(); Signature signature = new Signature(klass); From 7dfede2d7614ef9985d67dddcfc219683fb5542d Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Thu, 15 Dec 2011 20:15:32 +0400 Subject: [PATCH 26/33] parse method in/out parameters --- .../jet/codegen/BothSignatureWriter.java | 15 ++-------- .../resolve/java/JavaDescriptorResolver.java | 4 +-- .../lang/resolve/java/JetSignatureUtils.java | 28 +++++++++++++++++++ compiler/testData/readClass/FunInParam.kt | 3 ++ compiler/testData/readClass/FunOutParam.kt | 3 ++ .../org/jetbrains/jet/ReadClassDataTest.java | 11 +++++--- 6 files changed, 46 insertions(+), 18 deletions(-) create mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetSignatureUtils.java create mode 100644 compiler/testData/readClass/FunInParam.kt create mode 100644 compiler/testData/readClass/FunOutParam.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java b/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java index 440d0587873..70c66da4870 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/BothSignatureWriter.java @@ -1,8 +1,8 @@ package org.jetbrains.jet.codegen; -import jet.typeinfo.TypeInfoVariance; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.resolve.java.JetSignatureUtils; import org.jetbrains.jet.rt.signature.JetSignatureAdapter; import org.jetbrains.jet.rt.signature.JetSignatureReader; import org.jetbrains.jet.rt.signature.JetSignatureWriter; @@ -184,21 +184,12 @@ public class BothSignatureWriter { signatureVisitor().visitTypeVariable(name); jetSignatureWriter.visitTypeVariable(name, nullable); } - - private TypeInfoVariance translateVariance(Variance variance) { - switch (variance) { - case IN_VARIANCE: return TypeInfoVariance.IN; - case OUT_VARIANCE: return TypeInfoVariance.OUT; - case INVARIANT: return TypeInfoVariance.INVARIANT; - default: throw new IllegalStateException(); - } - } - + public void writeFormalTypeParameter(final String name, Variance variance) { checkTopLevel(); signatureVisitor().visitFormalTypeParameter(name); - jetSignatureWriter.visitFormalTypeParameter(name, translateVariance(variance)); + jetSignatureWriter.visitFormalTypeParameter(name, JetSignatureUtils.translateVariance(variance)); } public void writeFormalTypeParameterEnd() { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index e9cba2cc458..25b683c7d39 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -547,7 +547,7 @@ public class JavaDescriptorResolver { final List r = new ArrayList(); new JetSignatureReader(jetSignature).acceptFormalTypeParametersOnly(new JetSignatureExceptionsAdapter() { @Override - public JetSignatureVisitor visitFormalTypeParameter(final String name, TypeInfoVariance variance) { + public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) { return new JetSignatureExceptionsAdapter() { int index = 0; @@ -578,7 +578,7 @@ public class JavaDescriptorResolver { functionDescriptor, Collections.emptyList(), // TODO: wrong true, // TODO: wrong - Variance.INVARIANT, // TOOD: wrong + JetSignatureUtils.translateVariance(variance), name, ++index); r.add(typeParameter); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetSignatureUtils.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetSignatureUtils.java new file mode 100644 index 00000000000..a1207b905fe --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetSignatureUtils.java @@ -0,0 +1,28 @@ +package org.jetbrains.jet.lang.resolve.java; + +import jet.typeinfo.TypeInfoVariance; +import org.jetbrains.jet.lang.types.Variance; + +/** + * @author Stepan Koltsov + */ +public class JetSignatureUtils { + + static { + if (Variance.INVARIANT.ordinal() != TypeInfoVariance.INVARIANT.ordinal()) + throw new IllegalStateException(); + if (Variance.IN_VARIANCE.ordinal() != TypeInfoVariance.IN.ordinal()) + throw new IllegalStateException(); + if (Variance.OUT_VARIANCE.ordinal() != TypeInfoVariance.OUT.ordinal()) + throw new IllegalStateException(); + } + + public static TypeInfoVariance translateVariance(Variance variance) { + return TypeInfoVariance.values()[variance.ordinal()]; + } + + public static Variance translateVariance(TypeInfoVariance variance) { + return Variance.values()[variance.ordinal()]; + } + +} diff --git a/compiler/testData/readClass/FunInParam.kt b/compiler/testData/readClass/FunInParam.kt new file mode 100644 index 00000000000..c12eb63fc3e --- /dev/null +++ b/compiler/testData/readClass/FunInParam.kt @@ -0,0 +1,3 @@ +namespace test + +fun f() = 1 diff --git a/compiler/testData/readClass/FunOutParam.kt b/compiler/testData/readClass/FunOutParam.kt new file mode 100644 index 00000000000..7198872c6f8 --- /dev/null +++ b/compiler/testData/readClass/FunOutParam.kt @@ -0,0 +1,3 @@ +namespace test + +fun f() = 1 diff --git a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java index 03936722192..2d375655704 100644 --- a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java +++ b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java @@ -237,7 +237,12 @@ public class ReadClassDataTest extends UsefulTestCase { } private void serialize(Variance variance, StringBuilder sb) { - sb.append(variance); + if (variance == Variance.INVARIANT) { + + } else { + sb.append(variance); + sb.append(' '); + } } private void serialize(JetType type, StringBuilder sb) { @@ -318,9 +323,7 @@ public class ReadClassDataTest extends UsefulTestCase { } private void serialize(TypeParameterDescriptor param, StringBuilder sb) { - if (param.getVariance() != Variance.INVARIANT) { - serialize(param.getVariance(), sb); - } + serialize(param.getVariance(), sb); sb.append(param.getName()); // TODO: serialize bounds } From 45b4bd6785dd6c80edeba844618c1dfd6cc7eae6 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Thu, 15 Dec 2011 20:15:35 +0400 Subject: [PATCH 27/33] fix ReadClassDataTest --- .../tests/org/jetbrains/jet/ReadClassDataTest.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java index 2d375655704..7ee0f1b23e9 100644 --- a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java +++ b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java @@ -200,7 +200,6 @@ public class ReadClassDataTest extends UsefulTestCase { private static Object invoke(Method method, Object thiz, Object... args) { try { - method.setAccessible(true); return method.invoke(thiz, args); } catch (Exception e) { throw new RuntimeException("failed to invoke " + method + ": " + e, e); @@ -229,7 +228,7 @@ public class ReadClassDataTest extends UsefulTestCase { sb.append("vararg "); serialize(valueParameter.getVarargElementType()); } else { - serialize(valueParameter.getOutType()); + serialize(valueParameter.getOutType(), sb); } if (valueParameter.hasDefaultValue()) { sb.append(" = ?"); @@ -279,7 +278,7 @@ public class ReadClassDataTest extends UsefulTestCase { } } - private void serialize(Object o, StringBuilder sb) { + private Method getMethodToSerialize(Object o) { // TODO: cache for (Method method : ReadClassDataTest.class.getDeclaredMethods()) { if (!method.getName().equals("serialize")) { @@ -295,12 +294,17 @@ public class ReadClassDataTest extends UsefulTestCase { continue; } if (method.getParameterTypes()[0].isInstance(o)) { - invoke(method, this, o, sb); - return; + method.setAccessible(true); + return method; } } throw new IllegalStateException("don't know how to serialize " + o + " (of " + o.getClass() + ")"); } + + private void serialize(Object o, StringBuilder sb) { + Method method = getMethodToSerialize(o); + invoke(method, this, o, sb); + } private void serialize(ModuleDescriptor module, StringBuilder sb) { // nop From 6b66e8296f39343edf02b6f24259b6abd3906098 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Thu, 15 Dec 2011 20:15:39 +0400 Subject: [PATCH 28/33] split readClass tests into directories --- compiler/testData/readClass/{ => class}/Class.kt | 0 compiler/testData/readClass/{ => fun}/ClassFun.kt | 0 compiler/testData/readClass/{ => fun}/FunClassParamNotNull.kt | 0 compiler/testData/readClass/{ => fun}/FunClassParamNullable.kt | 0 compiler/testData/readClass/{ => fun}/FunGenericParam.kt | 0 compiler/testData/readClass/{ => fun}/FunInParam.kt | 0 compiler/testData/readClass/{ => fun}/FunOutParam.kt | 0 compiler/testData/readClass/{ => fun}/FunParamNotNull.kt | 0 compiler/testData/readClass/{ => fun}/FunParamNullable.kt | 0 compiler/testData/readClass/{ => fun}/NsFun.kt | 0 .../testData/readClass/{ => fun}/ReturnTypeClassParamNotNull.kt | 0 .../testData/readClass/{ => fun}/ReturnTypeClassParamNullable.kt | 0 compiler/testData/readClass/{ => fun}/ReturnTypeNotNull.kt | 0 compiler/testData/readClass/{ => fun}/ReturnTypeNullable.kt | 0 14 files changed, 0 insertions(+), 0 deletions(-) rename compiler/testData/readClass/{ => class}/Class.kt (100%) rename compiler/testData/readClass/{ => fun}/ClassFun.kt (100%) rename compiler/testData/readClass/{ => fun}/FunClassParamNotNull.kt (100%) rename compiler/testData/readClass/{ => fun}/FunClassParamNullable.kt (100%) rename compiler/testData/readClass/{ => fun}/FunGenericParam.kt (100%) rename compiler/testData/readClass/{ => fun}/FunInParam.kt (100%) rename compiler/testData/readClass/{ => fun}/FunOutParam.kt (100%) rename compiler/testData/readClass/{ => fun}/FunParamNotNull.kt (100%) rename compiler/testData/readClass/{ => fun}/FunParamNullable.kt (100%) rename compiler/testData/readClass/{ => fun}/NsFun.kt (100%) rename compiler/testData/readClass/{ => fun}/ReturnTypeClassParamNotNull.kt (100%) rename compiler/testData/readClass/{ => fun}/ReturnTypeClassParamNullable.kt (100%) rename compiler/testData/readClass/{ => fun}/ReturnTypeNotNull.kt (100%) rename compiler/testData/readClass/{ => fun}/ReturnTypeNullable.kt (100%) diff --git a/compiler/testData/readClass/Class.kt b/compiler/testData/readClass/class/Class.kt similarity index 100% rename from compiler/testData/readClass/Class.kt rename to compiler/testData/readClass/class/Class.kt diff --git a/compiler/testData/readClass/ClassFun.kt b/compiler/testData/readClass/fun/ClassFun.kt similarity index 100% rename from compiler/testData/readClass/ClassFun.kt rename to compiler/testData/readClass/fun/ClassFun.kt diff --git a/compiler/testData/readClass/FunClassParamNotNull.kt b/compiler/testData/readClass/fun/FunClassParamNotNull.kt similarity index 100% rename from compiler/testData/readClass/FunClassParamNotNull.kt rename to compiler/testData/readClass/fun/FunClassParamNotNull.kt diff --git a/compiler/testData/readClass/FunClassParamNullable.kt b/compiler/testData/readClass/fun/FunClassParamNullable.kt similarity index 100% rename from compiler/testData/readClass/FunClassParamNullable.kt rename to compiler/testData/readClass/fun/FunClassParamNullable.kt diff --git a/compiler/testData/readClass/FunGenericParam.kt b/compiler/testData/readClass/fun/FunGenericParam.kt similarity index 100% rename from compiler/testData/readClass/FunGenericParam.kt rename to compiler/testData/readClass/fun/FunGenericParam.kt diff --git a/compiler/testData/readClass/FunInParam.kt b/compiler/testData/readClass/fun/FunInParam.kt similarity index 100% rename from compiler/testData/readClass/FunInParam.kt rename to compiler/testData/readClass/fun/FunInParam.kt diff --git a/compiler/testData/readClass/FunOutParam.kt b/compiler/testData/readClass/fun/FunOutParam.kt similarity index 100% rename from compiler/testData/readClass/FunOutParam.kt rename to compiler/testData/readClass/fun/FunOutParam.kt diff --git a/compiler/testData/readClass/FunParamNotNull.kt b/compiler/testData/readClass/fun/FunParamNotNull.kt similarity index 100% rename from compiler/testData/readClass/FunParamNotNull.kt rename to compiler/testData/readClass/fun/FunParamNotNull.kt diff --git a/compiler/testData/readClass/FunParamNullable.kt b/compiler/testData/readClass/fun/FunParamNullable.kt similarity index 100% rename from compiler/testData/readClass/FunParamNullable.kt rename to compiler/testData/readClass/fun/FunParamNullable.kt diff --git a/compiler/testData/readClass/NsFun.kt b/compiler/testData/readClass/fun/NsFun.kt similarity index 100% rename from compiler/testData/readClass/NsFun.kt rename to compiler/testData/readClass/fun/NsFun.kt diff --git a/compiler/testData/readClass/ReturnTypeClassParamNotNull.kt b/compiler/testData/readClass/fun/ReturnTypeClassParamNotNull.kt similarity index 100% rename from compiler/testData/readClass/ReturnTypeClassParamNotNull.kt rename to compiler/testData/readClass/fun/ReturnTypeClassParamNotNull.kt diff --git a/compiler/testData/readClass/ReturnTypeClassParamNullable.kt b/compiler/testData/readClass/fun/ReturnTypeClassParamNullable.kt similarity index 100% rename from compiler/testData/readClass/ReturnTypeClassParamNullable.kt rename to compiler/testData/readClass/fun/ReturnTypeClassParamNullable.kt diff --git a/compiler/testData/readClass/ReturnTypeNotNull.kt b/compiler/testData/readClass/fun/ReturnTypeNotNull.kt similarity index 100% rename from compiler/testData/readClass/ReturnTypeNotNull.kt rename to compiler/testData/readClass/fun/ReturnTypeNotNull.kt diff --git a/compiler/testData/readClass/ReturnTypeNullable.kt b/compiler/testData/readClass/fun/ReturnTypeNullable.kt similarity index 100% rename from compiler/testData/readClass/ReturnTypeNullable.kt rename to compiler/testData/readClass/fun/ReturnTypeNullable.kt From e153d97734fa4370966542b8110c2d43096c3692 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Thu, 15 Dec 2011 20:15:44 +0400 Subject: [PATCH 29/33] reading class signature (incomplete) --- .../resolve/java/JavaDescriptorResolver.java | 93 ++++++++++++++++++- .../testData/readClass/class/ClassInParam.kt | 3 + .../testData/readClass/class/ClassOutParam.kt | 3 + .../testData/readClass/class/ClassParam.kt | 3 + .../org/jetbrains/jet/ReadClassDataTest.java | 10 +- .../jet/rt/signature/JetSignatureReader.java | 4 + 6 files changed, 109 insertions(+), 7 deletions(-) create mode 100644 compiler/testData/readClass/class/ClassInParam.kt create mode 100644 compiler/testData/readClass/class/ClassOutParam.kt create mode 100644 compiler/testData/readClass/class/ClassParam.kt diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index 25b683c7d39..b16f933e841 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -17,6 +17,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.plugin.JetFileType; +import org.jetbrains.jet.rt.signature.JetSignatureAdapter; import org.jetbrains.jet.rt.signature.JetSignatureExceptionsAdapter; import org.jetbrains.jet.rt.signature.JetSignatureReader; import org.jetbrains.jet.rt.signature.JetSignatureVisitor; @@ -124,9 +125,9 @@ public class JavaDescriptorResolver { resolveParentDescriptor(psiClass), psiClass.isInterface() ? ClassKind.TRAIT : ClassKind.CLASS ); classDescriptor.setName(name); - + List supertypes = new ArrayList(); - List typeParameters = makeUninitializedTypeParameters(classDescriptor, psiClass.getTypeParameters()); + List typeParameters = resolveClassTypeParameters(psiClass, classDescriptor); classDescriptor.setTypeConstructor(new TypeConstructorImpl( classDescriptor, Collections.emptyList(), // TODO @@ -144,8 +145,11 @@ public class JavaDescriptorResolver { classDescriptorCache.put(psiClass.getQualifiedName(), classDescriptor); classDescriptor.setUnsubstitutedMemberScope(new JavaClassMembersScope(classDescriptor, psiClass, semanticServices, false)); - // UGLY HACK - initializeTypeParameters(psiClass); + // TODO: initialize + if (psiClass.getModifierList().findAnnotation(StdlibNames.JET_CLASS.getFqName()) == null) { + // UGLY HACK (Andrey Breslav is not sure what did he mean) + initializeTypeParameters(psiClass); + } supertypes.addAll(getSupertypes(psiClass)); if (psiClass.isInterface()) { @@ -193,6 +197,82 @@ public class JavaDescriptorResolver { return classDescriptor; } + private List resolveClassTypeParameters(PsiClass psiClass, JavaClassDescriptor classDescriptor) { + for (PsiAnnotation annotation : psiClass.getModifierList().getAnnotations()) { + if (annotation.getQualifiedName().equals(StdlibNames.JET_CLASS.getFqName())) { + PsiLiteralExpression attributeValue = (PsiLiteralExpression) annotation.findAttributeValue(StdlibNames.JET_CLASS_SIGNATURE); + if (attributeValue != null) { + String typeParametersString = (String) attributeValue.getValue(); + if (typeParametersString != null) { + return resolveClassTypeParametersFromJetSignature(typeParametersString, classDescriptor); + } + } + } + } + return makeUninitializedTypeParameters(classDescriptor, psiClass.getTypeParameters()); + } + + /** + * @see #resolveMethodTypeParametersFromJetSignature(String, FunctionDescriptor) + */ + private List resolveClassTypeParametersFromJetSignature(String jetSignature, final JavaClassDescriptor classDescriptor) { + final List r = new ArrayList(); + new JetSignatureReader(jetSignature).accept(new JetSignatureExceptionsAdapter() { + @Override + public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance) { + return new JetSignatureExceptionsAdapter() { + int index = 0; + + @Override + public JetSignatureVisitor visitClassBound() { + return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) { + @Override + protected void done(@NotNull JetType jetType) { + // TODO + } + }; + } + + @Override + public JetSignatureVisitor visitInterfaceBound() { + return new JetTypeJetSignatureReader(JavaDescriptorResolver.this, semanticServices.getJetSemanticServices().getStandardLibrary()) { + @Override + protected void done(@NotNull JetType jetType) { + // TODO + } + }; + } + + @Override + public void visitFormalTypeParameterEnd() { + TypeParameterDescriptor typeParameter = TypeParameterDescriptor.createForFurtherModification( + classDescriptor, + Collections.emptyList(), // TODO: wrong + true, // TODO: wrong + JetSignatureUtils.translateVariance(variance), + name, + ++index); + r.add(typeParameter); + } + + }; + } + + @Override + public JetSignatureVisitor visitSuperclass() { + // TODO + return new JetSignatureAdapter(); + } + + @Override + public JetSignatureVisitor visitInterface() { + // TODO + return new JetSignatureAdapter(); + } + }); + return r; + } + private DeclarationDescriptor resolveParentDescriptor(PsiClass psiClass) { PsiClass containingClass = psiClass.getContainingClass(); if (containingClass != null) { @@ -542,7 +622,10 @@ public class JavaDescriptorResolver { initializeTypeParameters(method); return typeParameters; } - + + /** + * @see #resolveClassTypeParametersFromJetSignature(String, JavaClassDescriptor) + */ private List resolveMethodTypeParametersFromJetSignature(String jetSignature, final FunctionDescriptor functionDescriptor) { final List r = new ArrayList(); new JetSignatureReader(jetSignature).acceptFormalTypeParametersOnly(new JetSignatureExceptionsAdapter() { diff --git a/compiler/testData/readClass/class/ClassInParam.kt b/compiler/testData/readClass/class/ClassInParam.kt new file mode 100644 index 00000000000..a1a3ec98d39 --- /dev/null +++ b/compiler/testData/readClass/class/ClassInParam.kt @@ -0,0 +1,3 @@ +namespace test + +class Wine diff --git a/compiler/testData/readClass/class/ClassOutParam.kt b/compiler/testData/readClass/class/ClassOutParam.kt new file mode 100644 index 00000000000..83195ecae37 --- /dev/null +++ b/compiler/testData/readClass/class/ClassOutParam.kt @@ -0,0 +1,3 @@ +namespace test + +class Juice diff --git a/compiler/testData/readClass/class/ClassParam.kt b/compiler/testData/readClass/class/ClassParam.kt new file mode 100644 index 00000000000..7457e5a7ffe --- /dev/null +++ b/compiler/testData/readClass/class/ClassParam.kt @@ -0,0 +1,3 @@ +namespace test + +class Beer diff --git a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java index 7ee0f1b23e9..83e7f8d13c4 100644 --- a/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java +++ b/compiler/tests/org/jetbrains/jet/ReadClassDataTest.java @@ -153,16 +153,22 @@ public class ReadClassDataTest extends UsefulTestCase { String bs = serializeContent((ClassDescriptor) b); Assert.assertEquals(as, bs); - System.out.println(a); + System.out.println(as); } private String serializeContent(ClassDescriptor klass) { StringBuilder sb = new StringBuilder(); sb.append("class "); - + serialize(klass, sb); + if (!klass.getTypeConstructor().getParameters().isEmpty()) { + sb.append("<"); + serializeCommaSeparated(klass.getTypeConstructor().getParameters(), sb); + sb.append(">"); + } + // TODO: supers // TODO: constructors diff --git a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureReader.java b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureReader.java index a163c8c6d4d..bda1063e04c 100644 --- a/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureReader.java +++ b/stdlib/src/org/jetbrains/jet/rt/signature/JetSignatureReader.java @@ -36,6 +36,10 @@ public class JetSignatureReader { pos = parseType(signature, pos, v.visitInterface()); } } + + if (pos != signature.length()) { + throw new IllegalStateException(); + } } public int acceptFormalTypeParameters(JetSignatureVisitor v) { From 3551b44c07738f80a2fe5de81e21c23a01557e08 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Thu, 15 Dec 2011 20:54:30 +0400 Subject: [PATCH 30/33] KT-847 Allow "this" without {} in string templates --- .../lang/parsing/JetExpressionParsing.java | 36 +- .../jet/lang/resolve/calls/CallResolver.java | 2 +- .../BasicExpressionTypingVisitor.java | 2 +- .../src/org/jetbrains/jet/lexer/Jet.flex | 4 + .../org/jetbrains/jet/lexer/_JetLexer.java | 784 +++++++++--------- .../diagnostics/tests/regressions/kt847.jet | 3 + compiler/testData/psi/StringTemplates.jet | 1 + compiler/testData/psi/StringTemplates.txt | 19 + grammar/src/expressions.grm | 18 +- 9 files changed, 476 insertions(+), 393 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/regressions/kt847.jet diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java index cf8e51c37e8..8844d181e69 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java @@ -1,9 +1,11 @@ package org.jetbrains.jet.lang.parsing; +import com.google.common.collect.ImmutableMap; import com.intellij.lang.PsiBuilder; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; import org.jetbrains.jet.JetNodeType; +import org.jetbrains.jet.lexer.JetToken; import org.jetbrains.jet.lexer.JetTokens; import java.util.*; @@ -18,6 +20,16 @@ public class JetExpressionParsing extends AbstractJetParsing { private static final TokenSet WHEN_CONDITION_RECOVERY_SET = TokenSet.create(RBRACE, IN_KEYWORD, NOT_IN, IS_KEYWORD, NOT_IS, ELSE_KEYWORD); private static final TokenSet WHEN_CONDITION_RECOVERY_SET_WITH_DOUBLE_ARROW = TokenSet.create(RBRACE, IN_KEYWORD, NOT_IN, IS_KEYWORD, NOT_IS, ELSE_KEYWORD, DOUBLE_ARROW, DOT); + private static final ImmutableMap KEYWORD_TEXTS = tokenSetToMap(KEYWORDS); + + private static ImmutableMap tokenSetToMap(TokenSet tokens) { + ImmutableMap.Builder builder = ImmutableMap.builder(); + for (IElementType token : tokens.getTypes()) { + builder.put(token.toString(), (JetToken) token); + } + return builder.build(); + } + private static final TokenSet TYPE_ARGUMENT_LIST_STOPPERS = TokenSet.create( INTEGER_LITERAL, FLOAT_LITERAL, CHARACTER_LITERAL, OPEN_QUOTE, RAW_STRING_LITERAL, NAMESPACE_KEYWORD, AS_KEYWORD, TYPE_KEYWORD, TRAIT_KEYWORD, CLASS_KEYWORD, THIS_KEYWORD, VAL_KEYWORD, VAR_KEYWORD, @@ -587,7 +599,7 @@ public class JetExpressionParsing extends AbstractJetParsing { /* * stringTemplateElement * : RegularStringPart - * : ShortTemplateEntrySTART SimpleName + * : ShortTemplateEntrySTART (SimpleName | "this") * : EscapeSequence * : longTemplate * ; @@ -611,9 +623,25 @@ public class JetExpressionParsing extends AbstractJetParsing { PsiBuilder.Marker entry = mark(); advance(); // SHORT_TEMPLATE_ENTRY_START - PsiBuilder.Marker reference = mark(); - expect(IDENTIFIER, "Expecting a name"); - reference.done(REFERENCE_EXPRESSION); + if (at(THIS_KEYWORD)) { + PsiBuilder.Marker thisExpression = mark(); + PsiBuilder.Marker reference = mark(); + advance(); // THIS_KEYWORD + reference.done(REFERENCE_EXPRESSION); + thisExpression.done(THIS_EXPRESSION); + } + else { + JetToken keyword = KEYWORD_TEXTS.get(myBuilder.getTokenText()); + if (keyword != null) { + myBuilder.remapCurrentToken(keyword); + errorAndAdvance("Keyword cannot be used as a reference"); + } + else { + PsiBuilder.Marker reference = mark(); + expect(IDENTIFIER, "Expecting a name"); + reference.done(REFERENCE_EXPRESSION); + } + } entry.done(SHORT_STRING_TEMPLATE_ENTRY); } 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 989710ce480..18524d28943 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 @@ -59,7 +59,7 @@ public class CallResolver { JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) calleeExpression; String referencedName = nameExpression.getReferencedName(); if (referencedName == null) { - return null; + return OverloadResolutionResultsImpl.nameNotFound(); } TaskPrioritizer task_prioritizer; if (nameExpression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java index 94096c3e154..6d9869adc44 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -916,7 +916,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { public void visitStringTemplateEntryWithExpression(JetStringTemplateEntryWithExpression entry) { JetExpression entryExpression = entry.getExpression(); if (entryExpression != null) { - facade.getType(entryExpression, context.replaceScope(context.scope)); + facade.getType(entryExpression, context); } value[0] = CompileTimeConstantResolver.OUT_OF_RANGE; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lexer/Jet.flex b/compiler/frontend/src/org/jetbrains/jet/lexer/Jet.flex index 8e6d524b28b..a6136493b42 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lexer/Jet.flex +++ b/compiler/frontend/src/org/jetbrains/jet/lexer/Jet.flex @@ -121,6 +121,10 @@ LONG_TEMPLATE_ENTRY_END=\} yypushback(yylength() - 1); return JetTokens.SHORT_TEMPLATE_ENTRY_START; } +// Only *this* keyword is itself an expression valid in this position +// *null*, *true* and *false* are also keywords and expression, but it does not make sense to put them +// in a string template for it'd be easier to just type them in without a dollar + "this" { popState(); return JetTokens.THIS_KEYWORD; } {IDENTIFIER} { popState(); return JetTokens.IDENTIFIER; } {LONELY_DOLLAR} { return JetTokens.REGULAR_STRING_PART; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lexer/_JetLexer.java b/compiler/frontend/src/org/jetbrains/jet/lexer/_JetLexer.java index 85d40f6a1a1..444c9e4fbdf 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lexer/_JetLexer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lexer/_JetLexer.java @@ -1,4 +1,4 @@ -/* The following code was generated by JFlex 1.4.3 on 11/12/11 11:48 AM */ +/* The following code was generated by JFlex 1.4.3 on 12/15/11 8:19 PM */ package org.jetbrains.jet.lexer; @@ -13,8 +13,8 @@ import org.jetbrains.jet.lexer.JetTokens; /** * This class is a scanner generated by * JFlex 1.4.3 - * on 11/12/11 11:48 AM from the specification file - * /Users/abreslav/work/jet/compiler/frontend/src/org/jetbrains/jet/lexer/Jet.flex + * on 12/15/11 8:19 PM from the specification file + * /Users/abreslav/work/jet-clean/compiler/frontend/src/org/jetbrains/jet/lexer/Jet.flex */ class _JetLexer implements FlexLexer { /** initial size of the lookahead buffer */ @@ -44,10 +44,10 @@ class _JetLexer implements FlexLexer { "\1\10\1\67\1\65\1\23\1\72\1\73\1\13\1\62\1\76\1\21"+ "\1\17\1\12\1\14\11\1\1\74\1\75\1\63\1\60\1\64\1\61"+ "\1\11\1\2\1\16\2\2\1\20\1\2\11\4\1\22\3\4\1\54"+ - "\3\4\1\15\2\4\1\70\1\24\1\71\1\0\1\4\1\6\1\32"+ - "\1\44\1\37\1\56\1\34\1\52\1\4\1\47\1\42\1\45\1\51"+ - "\1\50\1\33\1\31\1\40\1\36\1\4\1\43\1\35\1\41\1\26"+ - "\1\55\1\46\1\15\1\53\1\4\1\27\1\66\1\30\54\0\1\4"+ + "\3\4\1\15\2\4\1\70\1\24\1\71\1\0\1\4\1\6\1\36"+ + "\1\45\1\42\1\56\1\40\1\52\1\4\1\32\1\33\1\46\1\51"+ + "\1\50\1\37\1\35\1\43\1\41\1\4\1\44\1\34\1\31\1\26"+ + "\1\55\1\47\1\15\1\53\1\4\1\27\1\66\1\30\54\0\1\4"+ "\12\0\1\4\4\0\1\4\5\0\27\4\1\0\37\4\1\0\u013f\4"+ "\31\0\162\4\4\0\14\4\16\0\5\4\11\0\1\4\213\0\1\4"+ "\13\0\1\4\1\0\3\4\1\0\1\4\1\0\24\4\1\0\54\4"+ @@ -124,24 +124,24 @@ class _JetLexer implements FlexLexer { "\17\3\1\16\1\17\1\20\1\21\1\22\1\23\2\1"+ "\1\24\1\25\1\26\1\27\1\30\1\31\1\32\1\33"+ "\1\34\1\35\1\36\1\35\1\0\1\37\1\40\1\0"+ - "\1\41\1\42\1\0\1\43\1\0\1\44\1\0\1\45"+ - "\1\0\1\46\1\47\1\50\1\51\1\52\1\43\2\2"+ - "\1\43\1\53\1\54\1\55\1\56\2\12\1\0\2\3"+ - "\1\57\10\3\1\60\1\61\1\62\10\3\1\63\1\0"+ - "\1\64\1\65\1\66\1\67\1\70\1\71\1\72\1\73"+ - "\1\74\1\75\1\76\1\0\1\77\2\100\1\0\1\101"+ - "\1\43\1\3\2\0\1\50\1\102\4\0\1\103\2\3"+ - "\1\104\7\3\1\105\7\3\1\106\1\3\1\107\1\3"+ - "\1\110\1\111\1\112\1\113\1\114\1\115\2\0\1\40"+ - "\1\44\1\45\1\0\2\102\1\43\2\0\1\116\1\3"+ - "\1\117\4\3\1\120\1\3\1\121\1\3\1\122\2\3"+ - "\1\123\2\3\1\124\1\125\1\76\1\0\1\50\2\0"+ - "\1\3\1\126\1\3\1\127\1\3\1\130\1\131\1\3"+ - "\1\132\1\133\1\134\1\0\1\103\2\3\1\135\1\136"+ - "\3\3\1\137\1\140"; + "\1\40\1\41\1\42\1\0\1\43\1\0\1\44\1\0"+ + "\1\45\1\0\1\46\1\47\1\50\1\51\1\52\1\43"+ + "\2\2\1\43\1\53\1\54\1\55\1\56\2\12\1\0"+ + "\3\3\1\57\1\60\1\61\3\3\1\62\14\3\1\63"+ + "\1\0\1\64\1\65\1\66\1\67\1\70\1\71\1\72"+ + "\1\73\1\74\1\75\1\76\1\0\1\77\2\100\1\0"+ + "\1\40\1\101\1\43\1\3\2\0\1\50\1\102\4\0"+ + "\1\103\4\3\1\104\4\3\1\105\10\3\1\106\1\3"+ + "\1\107\1\3\1\110\1\111\1\112\1\113\1\114\1\115"+ + "\2\0\2\40\1\44\1\45\1\0\2\102\1\43\2\0"+ + "\1\116\1\3\1\117\1\3\1\120\1\3\1\121\1\3"+ + "\1\122\6\3\1\123\1\3\1\124\1\125\1\76\1\0"+ + "\1\126\1\50\2\0\1\127\1\130\1\131\2\3\1\132"+ + "\2\3\1\133\1\134\1\135\1\0\1\103\2\3\1\136"+ + "\1\137\3\3\1\140\1\141"; private static int [] zzUnpackAction() { - int [] result = new int[221]; + int [] result = new int[225]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; @@ -173,30 +173,31 @@ class _JetLexer implements FlexLexer { "\0\u0780\0\u07c0\0\u0800\0\u0840\0\u0880\0\u0100\0\u08c0\0\u0900"+ "\0\u0940\0\u0980\0\u09c0\0\u0a00\0\u0100\0\u0100\0\u0100\0\u0100"+ "\0\u0100\0\u0100\0\u0100\0\u0100\0\u0a40\0\u0100\0\u0a80\0\u0ac0"+ - "\0\u0100\0\u0b00\0\u0b40\0\u0100\0\u0100\0\u0b80\0\u0bc0\0\u0c00"+ - "\0\u0c40\0\u0c80\0\u0cc0\0\u0d00\0\u0100\0\u0d40\0\u0d80\0\u0100"+ - "\0\u0100\0\u0dc0\0\u0e00\0\u0e40\0\u0e80\0\u0100\0\u0100\0\u0100"+ - "\0\u0100\0\u0100\0\u0ec0\0\u0f00\0\u0f40\0\u0f80\0\u0fc0\0\u1000"+ - "\0\u1040\0\u1080\0\u10c0\0\u1100\0\u1140\0\u1180\0\u11c0\0\u0180"+ - "\0\u0180\0\u0180\0\u1200\0\u1240\0\u1280\0\u12c0\0\u1300\0\u1340"+ - "\0\u1380\0\u13c0\0\u0180\0\u1400\0\u1440\0\u1480\0\u0100\0\u0100"+ - "\0\u0100\0\u0100\0\u0100\0\u0100\0\u0100\0\u0100\0\u14c0\0\u1500"+ - "\0\u0100\0\u0100\0\u1540\0\u1580\0\u0100\0\u15c0\0\u0100\0\u1600"+ - "\0\u1640\0\u1680\0\u16c0\0\u1700\0\u1740\0\u1780\0\u17c0\0\u1800"+ - "\0\u1840\0\u1880\0\u0100\0\u18c0\0\u1900\0\u1940\0\u1980\0\u19c0"+ - "\0\u1a00\0\u1a40\0\u0180\0\u1a80\0\u1ac0\0\u1b00\0\u1b40\0\u1b80"+ - "\0\u1bc0\0\u1c00\0\u0180\0\u1c40\0\u0180\0\u1c80\0\u0180\0\u0180"+ - "\0\u1cc0\0\u1cc0\0\u0100\0\u0100\0\u1d00\0\u1d40\0\u0100\0\u0100"+ - "\0\u0100\0\u1d80\0\u1dc0\0\u0100\0\u1e00\0\u15c0\0\u1e40\0\u0180"+ - "\0\u1e80\0\u0180\0\u1ec0\0\u1f00\0\u1f40\0\u1f80\0\u0180\0\u1fc0"+ - "\0\u0180\0\u2000\0\u0180\0\u2040\0\u2080\0\u0180\0\u20c0\0\u2100"+ - "\0\u0180\0\u0100\0\u0100\0\u2140\0\u0100\0\u2180\0\u21c0\0\u2200"+ - "\0\u0180\0\u2240\0\u0180\0\u2280\0\u0180\0\u0180\0\u22c0\0\u0180"+ - "\0\u0180\0\u0180\0\u2300\0\u0100\0\u2340\0\u2380\0\u0180\0\u0180"+ - "\0\u23c0\0\u2400\0\u2440\0\u0180\0\u0180"; + "\0\u0100\0\u0b00\0\u0b40\0\u0b80\0\u0100\0\u0100\0\u0bc0\0\u0c00"+ + "\0\u0c40\0\u0c80\0\u0cc0\0\u0d00\0\u0d40\0\u0100\0\u0d80\0\u0dc0"+ + "\0\u0100\0\u0100\0\u0e00\0\u0e40\0\u0e80\0\u0ec0\0\u0100\0\u0100"+ + "\0\u0100\0\u0100\0\u0100\0\u0f00\0\u0f40\0\u0f80\0\u0fc0\0\u1000"+ + "\0\u0180\0\u0180\0\u0180\0\u1040\0\u1080\0\u10c0\0\u1100\0\u1140"+ + "\0\u1180\0\u11c0\0\u1200\0\u1240\0\u1280\0\u12c0\0\u1300\0\u1340"+ + "\0\u1380\0\u13c0\0\u1400\0\u0180\0\u1440\0\u1480\0\u14c0\0\u0100"+ + "\0\u0100\0\u0100\0\u0100\0\u0100\0\u0100\0\u0100\0\u0100\0\u1500"+ + "\0\u1540\0\u0100\0\u0100\0\u1580\0\u15c0\0\u1600\0\u0100\0\u1640"+ + "\0\u0100\0\u1680\0\u16c0\0\u1700\0\u1740\0\u1780\0\u17c0\0\u1800"+ + "\0\u1840\0\u1880\0\u18c0\0\u1900\0\u1940\0\u1980\0\u0180\0\u19c0"+ + "\0\u1a00\0\u1a40\0\u1a80\0\u0100\0\u1ac0\0\u1b00\0\u1b40\0\u1b80"+ + "\0\u1bc0\0\u1c00\0\u1c40\0\u1c80\0\u0180\0\u1cc0\0\u0180\0\u1d00"+ + "\0\u0180\0\u0180\0\u1d40\0\u1d40\0\u0100\0\u0100\0\u1d80\0\u1dc0"+ + "\0\u0100\0\u1e00\0\u0100\0\u0100\0\u1e40\0\u1e80\0\u0100\0\u1ec0"+ + "\0\u1640\0\u1f00\0\u0180\0\u1f40\0\u0180\0\u1f80\0\u0180\0\u1fc0"+ + "\0\u0180\0\u2000\0\u0180\0\u2040\0\u2080\0\u20c0\0\u2100\0\u2140"+ + "\0\u2180\0\u0180\0\u21c0\0\u0180\0\u0100\0\u0100\0\u2200\0\u0b00"+ + "\0\u0100\0\u2240\0\u2280\0\u0180\0\u0180\0\u0180\0\u22c0\0\u2300"+ + "\0\u0180\0\u2340\0\u2380\0\u0180\0\u0180\0\u0180\0\u23c0\0\u0100"+ + "\0\u2400\0\u2440\0\u0180\0\u0180\0\u2480\0\u24c0\0\u2500\0\u0180"+ + "\0\u0180"; private static int [] zzUnpackRowMap() { - int [] result = new int[221]; + int [] result = new int[225]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; @@ -222,234 +223,241 @@ class _JetLexer implements FlexLexer { "\1\5\1\6\1\7\1\10\1\7\1\5\1\11\1\10"+ "\1\12\1\13\1\14\1\15\1\16\2\7\1\17\1\7"+ "\1\20\1\7\1\21\1\5\1\22\1\7\1\23\1\24"+ - "\1\25\1\26\1\7\1\27\1\30\1\7\1\31\1\32"+ - "\1\33\1\34\1\35\1\36\1\7\1\37\3\7\1\40"+ + "\1\25\1\7\1\26\1\27\1\30\1\31\1\7\1\32"+ + "\1\7\1\33\1\34\1\35\1\36\1\7\1\37\2\7"+ + "\1\40\1\7\1\41\1\42\1\43\1\44\1\45\1\46"+ + "\1\47\1\50\1\51\1\52\1\53\1\54\1\55\1\56"+ + "\1\57\1\60\1\61\1\62\1\63\1\64\7\65\1\66"+ + "\1\67\13\65\1\70\1\71\52\65\2\0\1\72\1\0"+ + "\1\72\1\0\1\73\6\0\2\72\1\0\1\72\1\0"+ + "\1\72\3\0\1\72\2\0\1\74\25\72\21\0\1\5"+ + "\1\6\1\7\1\10\1\7\1\5\1\11\1\10\1\12"+ + "\1\13\1\14\1\15\1\16\2\7\1\17\1\7\1\20"+ + "\1\7\1\21\1\5\1\22\1\7\1\75\1\76\1\25"+ + "\1\7\1\26\1\27\1\30\1\31\1\7\1\32\1\7"+ + "\1\33\1\34\1\35\1\36\1\7\1\37\2\7\1\40"+ "\1\7\1\41\1\42\1\43\1\44\1\45\1\46\1\47"+ "\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57"+ - "\1\60\1\61\1\62\1\63\1\64\7\65\1\66\1\67"+ - "\13\65\1\70\1\71\52\65\2\0\1\72\1\0\1\72"+ - "\1\0\1\73\6\0\2\72\1\0\1\72\1\0\1\72"+ - "\3\0\1\72\2\0\26\72\21\0\1\5\1\6\1\7"+ - "\1\10\1\7\1\5\1\11\1\10\1\12\1\13\1\14"+ - "\1\15\1\16\2\7\1\17\1\7\1\20\1\7\1\21"+ - "\1\5\1\22\1\7\1\74\1\75\1\25\1\26\1\7"+ - "\1\27\1\30\1\7\1\31\1\32\1\33\1\34\1\35"+ - "\1\36\1\7\1\37\3\7\1\40\1\7\1\41\1\42"+ - "\1\43\1\44\1\45\1\46\1\47\1\50\1\51\1\52"+ - "\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62"+ - "\1\63\1\64\101\0\1\6\12\0\1\6\2\0\1\76"+ - "\1\77\13\0\1\77\44\0\2\7\1\0\2\7\6\0"+ - "\3\7\1\0\1\7\1\0\1\7\3\0\1\7\2\0"+ - "\26\7\24\0\1\10\3\0\1\10\70\0\6\100\2\0"+ - "\70\100\2\0\1\101\1\0\1\101\1\0\1\102\6\0"+ - "\2\101\1\0\1\101\1\0\1\101\3\0\1\101\2\0"+ - "\26\101\23\0\1\103\1\0\1\103\1\0\1\104\2\0"+ - "\1\105\3\0\2\103\1\0\1\103\1\0\1\103\3\0"+ - "\1\103\2\0\26\103\33\0\1\106\1\107\44\0\1\110"+ - "\77\0\1\111\20\0\1\112\12\0\1\112\1\113\1\114"+ - "\1\76\1\77\13\0\1\77\7\0\1\114\34\0\1\115"+ - "\12\0\1\115\2\0\1\116\101\0\1\117\36\0\1\120"+ - "\3\0\1\121\13\0\7\21\1\0\13\21\1\122\1\123"+ - "\53\21\25\0\1\124\53\0\2\7\1\0\2\7\6\0"+ - "\3\7\1\0\1\7\1\0\1\7\3\0\1\125\2\0"+ - "\1\7\1\126\24\7\22\0\2\7\1\0\2\7\6\0"+ - "\3\7\1\0\1\7\1\0\1\7\3\0\1\7\2\0"+ - "\4\7\1\127\21\7\22\0\2\7\1\0\2\7\6\0"+ - "\3\7\1\0\1\7\1\0\1\7\3\0\1\7\2\0"+ - "\17\7\1\130\6\7\22\0\2\7\1\0\2\7\6\0"+ - "\3\7\1\0\1\7\1\0\1\7\3\0\1\131\2\0"+ - "\26\7\22\0\2\7\1\0\2\7\6\0\3\7\1\0"+ - "\1\7\1\0\1\7\3\0\1\7\2\0\7\7\1\132"+ - "\7\7\1\133\6\7\22\0\2\7\1\0\2\7\6\0"+ - "\3\7\1\0\1\7\1\0\1\7\3\0\1\7\2\0"+ - "\13\7\1\134\12\7\22\0\2\7\1\0\2\7\6\0"+ - "\3\7\1\0\1\7\1\0\1\7\3\0\1\7\2\0"+ - "\12\7\1\135\3\7\1\136\3\7\1\137\3\7\22\0"+ - "\2\7\1\0\2\7\6\0\3\7\1\0\1\7\1\0"+ - "\1\7\3\0\1\7\2\0\1\140\3\7\1\141\14\7"+ - "\1\142\4\7\22\0\2\7\1\0\2\7\6\0\3\7"+ + "\1\60\1\61\1\62\1\63\1\64\101\0\1\6\12\0"+ + "\1\6\2\0\1\77\1\100\17\0\1\100\40\0\2\7"+ + "\1\0\2\7\6\0\3\7\1\0\1\7\1\0\1\7"+ + "\3\0\1\7\2\0\26\7\24\0\1\10\3\0\1\10"+ + "\70\0\6\101\2\0\70\101\2\0\1\102\1\0\1\102"+ + "\1\0\1\103\6\0\2\102\1\0\1\102\1\0\1\102"+ + "\3\0\1\102\2\0\26\102\23\0\1\104\1\0\1\104"+ + "\1\0\1\105\2\0\1\106\3\0\2\104\1\0\1\104"+ + "\1\0\1\104\3\0\1\104\2\0\26\104\33\0\1\107"+ + "\1\110\44\0\1\111\77\0\1\112\20\0\1\113\12\0"+ + "\1\113\1\114\1\115\1\77\1\100\17\0\1\100\4\0"+ + "\1\115\33\0\1\116\12\0\1\116\2\0\1\117\101\0"+ + "\1\120\36\0\1\121\3\0\1\122\13\0\7\21\1\0"+ + "\13\21\1\123\1\124\53\21\25\0\1\125\53\0\2\7"+ + "\1\0\2\7\6\0\3\7\1\0\1\7\1\0\1\7"+ + "\3\0\1\7\2\0\1\7\1\126\11\7\1\127\6\7"+ + "\1\130\3\7\22\0\2\7\1\0\2\7\6\0\3\7"+ "\1\0\1\7\1\0\1\7\3\0\1\7\2\0\3\7"+ - "\1\143\22\7\22\0\2\7\1\0\2\7\6\0\3\7"+ - "\1\0\1\7\1\0\1\7\3\0\1\7\2\0\12\7"+ - "\1\144\13\7\22\0\2\7\1\0\2\7\6\0\3\7"+ - "\1\0\1\7\1\0\1\7\3\0\1\7\2\0\16\7"+ - "\1\145\7\7\22\0\2\7\1\0\2\7\6\0\3\7"+ - "\1\0\1\7\1\0\1\7\3\0\1\146\2\0\1\7"+ - "\1\147\5\7\1\150\16\7\22\0\2\7\1\0\2\7"+ - "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ - "\2\0\16\7\1\151\7\7\22\0\2\7\1\0\2\7"+ - "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ - "\2\0\1\7\1\152\24\7\22\0\2\7\1\0\2\7"+ - "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ - "\2\0\7\7\1\153\16\7\63\0\1\154\15\0\1\155"+ - "\77\0\1\156\3\0\1\157\73\0\1\160\1\0\1\161"+ - "\75\0\1\162\77\0\1\163\104\0\1\164\100\0\1\165"+ - "\71\0\1\166\17\0\7\65\2\0\13\65\2\0\52\65"+ - "\2\0\1\167\1\0\1\167\1\0\1\170\6\0\2\167"+ - "\1\0\1\167\1\0\1\167\3\0\1\167\1\171\1\0"+ - "\26\167\21\0\7\172\1\0\16\172\1\173\51\172\1\0"+ - "\2\72\1\0\2\72\6\0\3\72\1\0\1\72\1\0"+ - "\1\72\3\0\1\72\2\0\26\72\21\0\6\174\2\0"+ - "\70\174\1\0\1\115\12\0\1\115\2\0\1\175\61\0"+ - "\1\176\12\0\1\176\4\0\1\176\40\0\1\176\15\0"+ - "\6\100\1\177\1\0\70\100\1\0\2\101\1\0\2\101"+ - "\6\0\3\101\1\0\1\101\1\0\1\101\3\0\1\101"+ - "\2\0\26\101\21\0\6\200\2\0\70\200\1\0\2\103"+ - "\1\0\2\103\6\0\3\103\1\0\1\103\1\0\1\103"+ - "\3\0\1\103\2\0\26\103\21\0\6\201\2\0\70\201"+ - "\7\106\1\0\70\106\13\202\1\203\64\202\1\0\1\112"+ - "\12\0\1\112\2\0\1\204\1\77\13\0\1\77\44\0"+ - "\2\113\11\0\1\113\1\0\1\113\1\205\1\113\1\0"+ - "\1\206\7\0\1\113\1\0\1\113\1\0\1\206\1\113"+ - "\4\0\1\113\5\0\1\113\3\0\1\113\22\0\1\114"+ - "\12\0\1\114\2\0\1\207\61\0\1\115\12\0\1\115"+ - "\3\0\1\77\13\0\1\77\43\0\7\21\1\0\70\21"+ - "\25\0\1\210\53\0\2\7\1\0\2\7\6\0\3\7"+ - "\1\0\1\7\1\0\1\7\3\0\1\7\2\0\17\7"+ - "\1\211\6\7\22\0\2\7\1\0\2\7\6\0\3\7"+ - "\1\0\1\7\1\0\1\7\3\0\1\7\2\0\2\7"+ - "\1\212\23\7\22\0\2\7\1\0\2\7\6\0\3\7"+ - "\1\0\1\7\1\0\1\7\3\0\1\7\2\0\26\7"+ - "\2\0\1\213\17\0\2\7\1\0\2\7\6\0\3\7"+ - "\1\0\1\7\1\0\1\7\3\0\1\7\2\0\4\7"+ - "\1\214\21\7\22\0\2\7\1\0\2\7\6\0\3\7"+ - "\1\0\1\7\1\0\1\7\3\0\1\7\2\0\5\7"+ - "\1\215\20\7\22\0\2\7\1\0\2\7\6\0\3\7"+ - "\1\0\1\7\1\0\1\7\3\0\1\7\2\0\1\216"+ - "\25\7\22\0\2\7\1\0\2\7\6\0\3\7\1\0"+ - "\1\7\1\0\1\7\3\0\1\7\2\0\1\7\1\217"+ - "\24\7\22\0\2\7\1\0\2\7\6\0\3\7\1\0"+ - "\1\7\1\0\1\7\3\0\1\7\2\0\14\7\1\220"+ - "\11\7\22\0\2\7\1\0\2\7\6\0\3\7\1\0"+ - "\1\7\1\0\1\7\3\0\1\221\2\0\1\7\1\222"+ - "\20\7\1\223\3\7\22\0\2\7\1\0\2\7\6\0"+ + "\1\131\1\132\14\7\1\133\4\7\22\0\2\7\1\0"+ + "\2\7\6\0\3\7\1\0\1\7\1\0\1\7\3\0"+ + "\1\134\2\0\26\7\22\0\2\7\1\0\2\7\6\0"+ + "\3\7\1\0\1\7\1\0\1\7\3\0\1\135\2\0"+ + "\5\7\1\136\20\7\22\0\2\7\1\0\2\7\6\0"+ "\3\7\1\0\1\7\1\0\1\7\3\0\1\7\2\0"+ - "\11\7\1\224\1\225\13\7\22\0\2\7\1\0\2\7"+ + "\3\7\1\137\22\7\22\0\2\7\1\0\2\7\6\0"+ + "\3\7\1\0\1\7\1\0\1\7\3\0\1\7\2\0"+ + "\17\7\1\140\6\7\22\0\2\7\1\0\2\7\6\0"+ + "\3\7\1\0\1\7\1\0\1\7\3\0\1\7\2\0"+ + "\12\7\1\141\4\7\1\142\6\7\22\0\2\7\1\0"+ + "\2\7\6\0\3\7\1\0\1\7\1\0\1\7\3\0"+ + "\1\7\2\0\14\7\1\143\11\7\22\0\2\7\1\0"+ + "\2\7\6\0\3\7\1\0\1\7\1\0\1\7\3\0"+ + "\1\7\2\0\7\7\1\144\16\7\22\0\2\7\1\0"+ + "\2\7\6\0\3\7\1\0\1\7\1\0\1\7\3\0"+ + "\1\7\2\0\13\7\1\145\12\7\22\0\2\7\1\0"+ + "\2\7\6\0\3\7\1\0\1\7\1\0\1\7\3\0"+ + "\1\7\2\0\1\7\1\146\24\7\22\0\2\7\1\0"+ + "\2\7\6\0\3\7\1\0\1\7\1\0\1\7\3\0"+ + "\1\147\2\0\5\7\1\150\4\7\1\151\13\7\22\0"+ + "\2\7\1\0\2\7\6\0\3\7\1\0\1\7\1\0"+ + "\1\7\3\0\1\7\2\0\1\7\1\152\24\7\22\0"+ + "\2\7\1\0\2\7\6\0\3\7\1\0\1\7\1\0"+ + "\1\7\3\0\1\7\2\0\5\7\1\153\20\7\22\0"+ + "\2\7\1\0\2\7\6\0\3\7\1\0\1\7\1\0"+ + "\1\7\3\0\1\7\2\0\12\7\1\154\13\7\54\0"+ + "\1\155\24\0\1\156\77\0\1\157\3\0\1\160\73\0"+ + "\1\161\1\0\1\162\75\0\1\163\77\0\1\164\104\0"+ + "\1\165\100\0\1\166\71\0\1\167\17\0\7\65\2\0"+ + "\13\65\2\0\52\65\2\0\1\170\1\0\1\170\1\0"+ + "\1\171\6\0\2\170\1\0\1\170\1\0\1\170\3\0"+ + "\1\170\1\172\1\0\26\170\21\0\7\173\1\0\16\173"+ + "\1\174\51\173\1\0\2\72\1\0\2\72\6\0\3\72"+ + "\1\0\1\72\1\0\1\72\3\0\1\72\2\0\26\72"+ + "\21\0\6\175\2\0\70\175\1\0\2\72\1\0\2\72"+ + "\6\0\3\72\1\0\1\72\1\0\1\72\3\0\1\72"+ + "\2\0\1\72\1\176\24\72\22\0\1\116\12\0\1\116"+ + "\2\0\1\177\61\0\1\200\12\0\1\200\4\0\1\200"+ + "\40\0\1\200\15\0\6\101\1\201\1\0\70\101\1\0"+ + "\2\102\1\0\2\102\6\0\3\102\1\0\1\102\1\0"+ + "\1\102\3\0\1\102\2\0\26\102\21\0\6\202\2\0"+ + "\70\202\1\0\2\104\1\0\2\104\6\0\3\104\1\0"+ + "\1\104\1\0\1\104\3\0\1\104\2\0\26\104\21\0"+ + "\6\203\2\0\70\203\7\107\1\0\70\107\13\204\1\205"+ + "\64\204\1\0\1\113\12\0\1\113\2\0\1\206\1\100"+ + "\17\0\1\100\40\0\2\114\11\0\1\114\1\0\1\114"+ + "\1\207\1\114\1\0\1\210\13\0\1\114\1\0\1\114"+ + "\1\210\1\114\2\0\1\114\4\0\1\114\3\0\1\114"+ + "\22\0\1\115\12\0\1\115\2\0\1\211\61\0\1\116"+ + "\12\0\1\116\3\0\1\100\17\0\1\100\37\0\7\21"+ + "\1\0\70\21\25\0\1\212\53\0\2\7\1\0\2\7"+ "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ - "\2\0\5\7\1\226\20\7\22\0\2\7\1\0\2\7"+ - "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ - "\2\0\10\7\1\227\15\7\22\0\2\7\1\0\2\7"+ - "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ - "\2\0\3\7\1\230\22\7\22\0\2\7\1\0\2\7"+ - "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ - "\2\0\3\7\1\231\5\7\1\232\14\7\22\0\2\7"+ + "\2\0\2\7\1\213\10\7\1\214\12\7\22\0\2\7"+ "\1\0\2\7\6\0\3\7\1\0\1\7\1\0\1\7"+ - "\3\0\1\7\2\0\1\233\25\7\22\0\2\7\1\0"+ - "\2\7\6\0\3\7\1\0\1\7\1\0\1\7\3\0"+ - "\1\7\2\0\17\7\1\234\6\7\22\0\2\7\1\0"+ - "\2\7\6\0\3\7\1\0\1\7\1\0\1\7\3\0"+ - "\1\7\2\0\12\7\1\235\13\7\22\0\2\7\1\0"+ - "\2\7\6\0\3\7\1\0\1\7\1\0\1\7\3\0"+ - "\1\7\2\0\11\7\1\236\14\7\22\0\2\7\1\0"+ - "\2\7\6\0\3\7\1\0\1\7\1\0\1\7\3\0"+ - "\1\7\2\0\12\7\1\237\4\7\1\240\6\7\52\0"+ - "\1\241\3\0\1\242\122\0\1\243\77\0\1\244\20\0"+ - "\2\167\1\0\2\167\6\0\3\167\1\0\1\167\1\0"+ - "\1\167\3\0\1\167\2\0\26\167\21\0\6\245\2\0"+ - "\70\245\1\0\2\246\11\0\1\246\1\0\1\246\1\0"+ - "\1\246\11\0\1\246\1\0\1\246\2\0\1\246\4\0"+ - "\1\246\5\0\1\246\3\0\1\246\21\0\6\174\1\247"+ - "\1\0\70\174\1\0\1\176\12\0\1\176\63\0\6\200"+ - "\1\250\1\0\70\200\6\201\1\251\1\0\70\201\13\202"+ - "\1\252\64\202\12\253\1\254\1\203\64\253\1\0\1\115"+ - "\12\0\1\115\64\0\2\255\11\0\1\255\1\0\1\255"+ - "\1\175\1\255\11\0\1\255\1\0\1\255\2\0\1\255"+ - "\4\0\1\255\5\0\1\255\3\0\1\255\22\0\1\176"+ - "\12\0\1\176\4\0\1\256\40\0\1\256\34\0\1\175"+ - "\60\0\25\210\1\257\52\210\1\0\2\7\1\0\2\7"+ - "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ - "\2\0\17\7\1\260\6\7\22\0\2\7\1\0\2\7"+ - "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ - "\2\0\3\7\1\261\22\7\22\0\2\7\1\0\2\7"+ - "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ - "\2\0\3\7\1\262\22\7\22\0\2\7\1\0\2\7"+ - "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ - "\2\0\3\7\1\263\22\7\22\0\2\7\1\0\2\7"+ - "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ - "\2\0\10\7\1\264\15\7\22\0\2\7\1\0\2\7"+ - "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ - "\2\0\4\7\1\265\21\7\22\0\2\7\1\0\2\7"+ - "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ - "\2\0\3\7\1\266\22\7\22\0\2\7\1\0\2\7"+ - "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ - "\2\0\3\7\1\267\22\7\22\0\2\7\1\0\2\7"+ - "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ - "\2\0\11\7\1\270\14\7\22\0\2\7\1\0\2\7"+ - "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ - "\2\0\4\7\1\271\21\7\22\0\2\7\1\0\2\7"+ - "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ - "\2\0\7\7\1\272\16\7\22\0\2\7\1\0\2\7"+ - "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ - "\2\0\3\7\1\273\22\7\22\0\2\7\1\0\2\7"+ - "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\274"+ - "\2\0\26\7\22\0\2\7\1\0\2\7\6\0\3\7"+ - "\1\0\1\7\1\0\1\7\3\0\1\7\2\0\1\7"+ - "\1\275\24\7\22\0\2\7\1\0\2\7\6\0\3\7"+ - "\1\0\1\7\1\0\1\7\3\0\1\7\2\0\1\276"+ - "\25\7\22\0\2\7\1\0\2\7\6\0\3\7\1\0"+ - "\1\7\1\0\1\7\3\0\1\7\2\0\17\7\1\277"+ - "\6\7\22\0\2\7\1\0\2\7\6\0\3\7\1\0"+ - "\1\7\1\0\1\7\3\0\1\7\2\0\4\7\1\300"+ + "\3\0\1\215\2\0\5\7\1\216\14\7\1\217\3\7"+ + "\22\0\2\7\1\0\2\7\6\0\3\7\1\0\1\7"+ + "\1\0\1\7\3\0\1\7\2\0\10\7\1\220\15\7"+ + "\22\0\2\7\1\0\2\7\6\0\3\7\1\0\1\7"+ + "\1\0\1\7\3\0\1\7\2\0\10\7\1\221\15\7"+ + "\22\0\2\7\1\0\2\7\6\0\3\7\1\0\1\7"+ + "\1\0\1\7\3\0\1\7\2\0\17\7\1\222\6\7"+ + "\22\0\2\7\1\0\2\7\6\0\3\7\1\0\1\7"+ + "\1\0\1\7\3\0\1\7\2\0\6\7\1\223\17\7"+ + "\22\0\2\7\1\0\2\7\6\0\3\7\1\0\1\7"+ + "\1\0\1\7\3\0\1\7\2\0\26\7\2\0\1\224"+ + "\17\0\2\7\1\0\2\7\6\0\3\7\1\0\1\7"+ + "\1\0\1\7\3\0\1\7\2\0\3\7\1\225\22\7"+ + "\22\0\2\7\1\0\2\7\6\0\3\7\1\0\1\7"+ + "\1\0\1\7\3\0\1\7\2\0\4\7\1\226\21\7"+ + "\22\0\2\7\1\0\2\7\6\0\3\7\1\0\1\7"+ + "\1\0\1\7\3\0\1\7\2\0\5\7\1\227\20\7"+ + "\22\0\2\7\1\0\2\7\6\0\3\7\1\0\1\7"+ + "\1\0\1\7\3\0\1\7\2\0\15\7\1\230\10\7"+ + "\22\0\2\7\1\0\2\7\6\0\3\7\1\0\1\7"+ + "\1\0\1\7\3\0\1\7\2\0\1\231\25\7\22\0"+ + "\2\7\1\0\2\7\6\0\3\7\1\0\1\7\1\0"+ + "\1\7\3\0\1\7\2\0\7\7\1\232\16\7\22\0"+ + "\2\7\1\0\2\7\6\0\3\7\1\0\1\7\1\0"+ + "\1\7\3\0\1\7\2\0\2\7\1\233\4\7\1\234"+ + "\16\7\22\0\2\7\1\0\2\7\6\0\3\7\1\0"+ + "\1\7\1\0\1\7\3\0\1\7\2\0\4\7\1\235"+ "\21\7\22\0\2\7\1\0\2\7\6\0\3\7\1\0"+ - "\1\7\1\0\1\7\3\0\1\7\2\0\4\7\1\301"+ - "\21\7\22\0\2\302\1\0\2\302\6\0\3\302\1\0"+ - "\1\302\1\0\1\302\3\0\1\302\2\0\26\302\21\0"+ - "\6\245\1\303\1\0\70\245\1\0\2\304\11\0\1\304"+ - "\1\0\1\304\1\0\1\304\11\0\1\304\1\0\1\304"+ - "\2\0\1\304\4\0\1\304\5\0\1\304\3\0\1\304"+ - "\21\0\12\202\1\305\1\252\64\202\13\253\1\306\64\253"+ - "\1\0\2\255\11\0\1\255\1\0\1\255\1\0\1\255"+ - "\1\0\1\206\7\0\1\255\1\0\1\255\1\0\1\206"+ - "\1\255\4\0\1\255\5\0\1\255\3\0\1\255\21\0"+ - "\25\210\1\307\52\210\1\0\2\7\1\0\2\7\6\0"+ - "\3\7\1\0\1\7\1\0\1\7\3\0\1\7\2\0"+ - "\4\7\1\310\21\7\22\0\2\7\1\0\2\7\6\0"+ - "\3\7\1\0\1\7\1\0\1\7\3\0\1\7\2\0"+ - "\12\7\1\311\13\7\22\0\2\7\1\0\2\7\6\0"+ - "\3\7\1\0\1\7\1\0\1\7\3\0\1\7\2\0"+ - "\11\7\1\312\14\7\22\0\2\7\1\0\2\7\6\0"+ - "\3\7\1\0\1\7\1\0\1\7\3\0\1\7\2\0"+ - "\4\7\1\313\21\7\22\0\2\7\1\0\2\7\6\0"+ - "\3\7\1\0\1\7\1\0\1\7\3\0\1\7\2\0"+ - "\6\7\1\314\17\7\22\0\2\7\1\0\2\7\6\0"+ - "\3\7\1\0\1\7\1\0\1\7\3\0\1\7\2\0"+ - "\10\7\1\315\15\7\22\0\2\7\1\0\2\7\6\0"+ - "\3\7\1\0\1\7\1\0\1\7\3\0\1\7\2\0"+ - "\15\7\1\316\10\7\22\0\2\7\1\0\2\7\6\0"+ - "\3\7\1\0\1\7\1\0\1\7\3\0\1\7\2\0"+ - "\12\7\1\317\13\7\22\0\2\7\1\0\2\7\6\0"+ - "\3\7\1\0\1\7\1\0\1\7\3\0\1\7\2\0"+ - "\20\7\1\320\5\7\22\0\2\7\1\0\2\7\6\0"+ - "\3\7\1\0\1\7\1\0\1\7\3\0\1\7\2\0"+ - "\3\7\1\321\22\7\22\0\2\7\1\0\2\7\6\0"+ - "\3\7\1\0\1\7\1\0\1\7\3\0\1\7\2\0"+ - "\3\7\1\322\22\7\22\0\2\323\11\0\1\323\1\0"+ - "\1\323\1\0\1\323\11\0\1\323\1\0\1\323\2\0"+ - "\1\323\4\0\1\323\5\0\1\323\3\0\1\323\21\0"+ - "\12\253\1\254\1\306\64\253\25\210\1\324\52\210\1\0"+ + "\1\7\1\0\1\7\3\0\1\7\2\0\17\7\1\236"+ + "\6\7\22\0\2\7\1\0\2\7\6\0\3\7\1\0"+ + "\1\7\1\0\1\7\3\0\1\7\2\0\13\7\1\237"+ + "\12\7\22\0\2\7\1\0\2\7\6\0\3\7\1\0"+ + "\1\7\1\0\1\7\3\0\1\7\2\0\2\7\1\240"+ + "\23\7\22\0\2\7\1\0\2\7\6\0\3\7\1\0"+ + "\1\7\1\0\1\7\3\0\1\7\2\0\13\7\1\241"+ + "\3\7\1\242\6\7\55\0\1\243\1\244\122\0\1\245"+ + "\77\0\1\246\20\0\2\170\1\0\2\170\6\0\3\170"+ + "\1\0\1\170\1\0\1\170\3\0\1\170\2\0\26\170"+ + "\21\0\6\247\2\0\70\247\1\0\2\250\11\0\1\250"+ + "\1\0\1\250\1\0\1\250\15\0\1\250\1\0\1\250"+ + "\1\0\1\250\2\0\1\250\4\0\1\250\3\0\1\250"+ + "\21\0\6\175\1\251\1\0\70\175\1\0\2\72\1\0"+ + "\2\72\6\0\3\72\1\0\1\72\1\0\1\72\3\0"+ + "\1\72\2\0\2\72\1\252\23\72\22\0\1\200\12\0"+ + "\1\200\63\0\6\202\1\253\1\0\70\202\6\203\1\254"+ + "\1\0\70\203\13\204\1\255\64\204\12\256\1\257\1\205"+ + "\64\256\1\0\1\116\12\0\1\116\64\0\2\260\11\0"+ + "\1\260\1\0\1\260\1\177\1\260\15\0\1\260\1\0"+ + "\1\260\1\0\1\260\2\0\1\260\4\0\1\260\3\0"+ + "\1\260\22\0\1\200\12\0\1\200\4\0\1\261\40\0"+ + "\1\261\34\0\1\177\60\0\25\212\1\262\52\212\1\0"+ "\2\7\1\0\2\7\6\0\3\7\1\0\1\7\1\0"+ - "\1\7\3\0\1\7\2\0\5\7\1\325\20\7\22\0"+ + "\1\7\3\0\1\7\2\0\3\7\1\263\22\7\22\0"+ "\2\7\1\0\2\7\6\0\3\7\1\0\1\7\1\0"+ - "\1\7\3\0\1\7\2\0\1\326\25\7\22\0\2\7"+ + "\1\7\3\0\1\7\2\0\12\7\1\264\13\7\22\0"+ + "\2\7\1\0\2\7\6\0\3\7\1\0\1\7\1\0"+ + "\1\7\3\0\1\7\2\0\7\7\1\265\16\7\22\0"+ + "\2\7\1\0\2\7\6\0\3\7\1\0\1\7\1\0"+ + "\1\7\3\0\1\7\2\0\2\7\1\266\23\7\22\0"+ + "\2\7\1\0\2\7\6\0\3\7\1\0\1\7\1\0"+ + "\1\7\3\0\1\7\2\0\7\7\1\267\16\7\22\0"+ + "\2\7\1\0\2\7\6\0\3\7\1\0\1\7\1\0"+ + "\1\7\3\0\1\7\2\0\7\7\1\270\16\7\22\0"+ + "\2\7\1\0\2\7\6\0\3\7\1\0\1\7\1\0"+ + "\1\7\3\0\1\7\2\0\17\7\1\271\6\7\22\0"+ + "\2\7\1\0\2\7\6\0\3\7\1\0\1\7\1\0"+ + "\1\7\3\0\1\7\2\0\7\7\1\272\16\7\22\0"+ + "\2\7\1\0\2\7\6\0\3\7\1\0\1\7\1\0"+ + "\1\7\3\0\1\7\2\0\7\7\1\273\16\7\22\0"+ + "\2\7\1\0\2\7\6\0\3\7\1\0\1\7\1\0"+ + "\1\7\3\0\1\7\2\0\1\274\25\7\22\0\2\7"+ "\1\0\2\7\6\0\3\7\1\0\1\7\1\0\1\7"+ - "\3\0\1\7\2\0\10\7\1\327\15\7\22\0\2\7"+ + "\3\0\1\7\2\0\3\7\1\275\22\7\22\0\2\7"+ "\1\0\2\7\6\0\3\7\1\0\1\7\1\0\1\7"+ - "\3\0\1\7\2\0\1\330\25\7\22\0\2\172\11\0"+ - "\1\172\1\0\1\172\1\0\1\172\11\0\1\172\1\0"+ - "\1\172\2\0\1\172\4\0\1\172\5\0\1\172\3\0"+ - "\1\172\22\0\2\7\1\0\2\7\6\0\3\7\1\0"+ - "\1\7\1\0\1\7\3\0\1\7\2\0\1\7\1\331"+ - "\24\7\22\0\2\7\1\0\2\7\6\0\3\7\1\0"+ - "\1\7\1\0\1\7\3\0\1\332\2\0\26\7\22\0"+ + "\3\0\1\7\2\0\7\7\1\276\16\7\22\0\2\7"+ + "\1\0\2\7\6\0\3\7\1\0\1\7\1\0\1\7"+ + "\3\0\1\277\2\0\26\7\22\0\2\7\1\0\2\7"+ + "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ + "\2\0\5\7\1\300\20\7\22\0\2\7\1\0\2\7"+ + "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ + "\2\0\17\7\1\301\6\7\22\0\2\7\1\0\2\7"+ + "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ + "\2\0\4\7\1\302\21\7\22\0\2\7\1\0\2\7"+ + "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ + "\2\0\3\7\1\303\22\7\22\0\2\7\1\0\2\7"+ + "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ + "\2\0\3\7\1\304\22\7\22\0\2\305\1\0\2\305"+ + "\6\0\3\305\1\0\1\305\1\0\1\305\3\0\1\305"+ + "\2\0\26\305\21\0\6\247\1\306\1\0\70\247\1\0"+ + "\2\307\11\0\1\307\1\0\1\307\1\0\1\307\15\0"+ + "\1\307\1\0\1\307\1\0\1\307\2\0\1\307\4\0"+ + "\1\307\3\0\1\307\22\0\2\72\1\0\2\72\6\0"+ + "\3\72\1\0\1\72\1\0\1\72\3\0\1\72\2\0"+ + "\3\72\1\310\22\72\21\0\12\204\1\311\1\255\64\204"+ + "\13\256\1\312\64\256\1\0\2\260\11\0\1\260\1\0"+ + "\1\260\1\0\1\260\1\0\1\210\13\0\1\260\1\0"+ + "\1\260\1\210\1\260\2\0\1\260\4\0\1\260\3\0"+ + "\1\260\21\0\25\212\1\313\52\212\1\0\2\7\1\0"+ + "\2\7\6\0\3\7\1\0\1\7\1\0\1\7\3\0"+ + "\1\7\2\0\16\7\1\314\7\7\22\0\2\7\1\0"+ + "\2\7\6\0\3\7\1\0\1\7\1\0\1\7\3\0"+ + "\1\7\2\0\1\315\25\7\22\0\2\7\1\0\2\7"+ + "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ + "\2\0\13\7\1\316\12\7\22\0\2\7\1\0\2\7"+ + "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ + "\2\0\3\7\1\317\22\7\22\0\2\7\1\0\2\7"+ + "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ + "\2\0\2\7\1\320\23\7\22\0\2\7\1\0\2\7"+ + "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ + "\2\0\3\7\1\321\22\7\22\0\2\7\1\0\2\7"+ + "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ + "\2\0\11\7\1\322\14\7\22\0\2\7\1\0\2\7"+ + "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ + "\2\0\13\7\1\323\12\7\22\0\2\7\1\0\2\7"+ + "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ + "\2\0\20\7\1\324\5\7\22\0\2\7\1\0\2\7"+ + "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ + "\2\0\7\7\1\325\16\7\22\0\2\7\1\0\2\7"+ + "\6\0\3\7\1\0\1\7\1\0\1\7\3\0\1\7"+ + "\2\0\7\7\1\326\16\7\22\0\2\327\11\0\1\327"+ + "\1\0\1\327\1\0\1\327\15\0\1\327\1\0\1\327"+ + "\1\0\1\327\2\0\1\327\4\0\1\327\3\0\1\327"+ + "\21\0\12\256\1\257\1\312\64\256\25\212\1\330\52\212"+ + "\1\0\2\7\1\0\2\7\6\0\3\7\1\0\1\7"+ + "\1\0\1\7\3\0\1\7\2\0\10\7\1\331\15\7"+ + "\22\0\2\7\1\0\2\7\6\0\3\7\1\0\1\7"+ + "\1\0\1\7\3\0\1\7\2\0\4\7\1\332\21\7"+ + "\22\0\2\7\1\0\2\7\6\0\3\7\1\0\1\7"+ + "\1\0\1\7\3\0\1\7\2\0\1\333\25\7\22\0"+ "\2\7\1\0\2\7\6\0\3\7\1\0\1\7\1\0"+ - "\1\7\3\0\1\7\2\0\6\7\1\333\17\7\22\0"+ - "\2\7\1\0\2\7\6\0\3\7\1\0\1\7\1\0"+ - "\1\7\3\0\1\7\2\0\3\7\1\334\22\7\22\0"+ - "\2\7\1\0\2\7\6\0\3\7\1\0\1\7\1\0"+ - "\1\7\3\0\1\7\2\0\3\7\1\335\22\7\21\0"; + "\1\7\3\0\1\7\2\0\4\7\1\334\21\7\22\0"+ + "\2\173\11\0\1\173\1\0\1\173\1\0\1\173\15\0"+ + "\1\173\1\0\1\173\1\0\1\173\2\0\1\173\4\0"+ + "\1\173\3\0\1\173\22\0\2\7\1\0\2\7\6\0"+ + "\3\7\1\0\1\7\1\0\1\7\3\0\1\7\2\0"+ + "\5\7\1\335\20\7\22\0\2\7\1\0\2\7\6\0"+ + "\3\7\1\0\1\7\1\0\1\7\3\0\1\336\2\0"+ + "\26\7\22\0\2\7\1\0\2\7\6\0\3\7\1\0"+ + "\1\7\1\0\1\7\3\0\1\7\2\0\11\7\1\337"+ + "\14\7\22\0\2\7\1\0\2\7\6\0\3\7\1\0"+ + "\1\7\1\0\1\7\3\0\1\7\2\0\7\7\1\340"+ + "\16\7\22\0\2\7\1\0\2\7\6\0\3\7\1\0"+ + "\1\7\1\0\1\7\3\0\1\7\2\0\7\7\1\341"+ + "\16\7\21\0"; private static int [] zzUnpackTrans() { - int [] result = new int[9344]; + int [] result = new int[9536]; int offset = 0; offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); return result; @@ -491,17 +499,17 @@ class _JetLexer implements FlexLexer { private static final String ZZ_ATTRIBUTE_PACKED_0 = "\4\0\1\11\15\1\2\11\21\1\1\11\6\1\10\11"+ - "\1\1\1\11\1\1\1\0\1\11\1\1\1\0\2\11"+ - "\1\0\1\1\1\0\1\1\1\0\1\1\1\0\1\11"+ - "\2\1\2\11\4\1\5\11\1\1\1\0\27\1\1\0"+ - "\2\1\10\11\1\1\1\0\2\11\1\1\1\0\1\11"+ - "\1\1\1\11\2\0\2\1\4\0\3\1\1\11\27\1"+ - "\2\11\2\0\3\11\1\0\1\1\1\11\1\1\2\0"+ - "\22\1\2\11\1\0\1\11\2\0\13\1\1\0\1\11"+ - "\11\1"; + "\1\1\1\11\1\1\1\0\1\11\1\1\1\0\1\1"+ + "\2\11\1\0\1\1\1\0\1\1\1\0\1\1\1\0"+ + "\1\11\2\1\2\11\4\1\5\11\1\1\1\0\27\1"+ + "\1\0\2\1\10\11\1\1\1\0\2\11\1\1\1\0"+ + "\1\1\1\11\1\1\1\11\2\0\2\1\4\0\12\1"+ + "\1\11\20\1\2\11\2\0\1\11\1\1\2\11\1\0"+ + "\1\1\1\11\1\1\2\0\22\1\2\11\1\0\1\1"+ + "\1\11\2\0\13\1\1\0\1\11\11\1"; private static int [] zzUnpackAttribute() { - int [] result = new int[221]; + int [] result = new int[225]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; @@ -835,23 +843,23 @@ class _JetLexer implements FlexLexer { case 3: { return JetTokens.IDENTIFIER; } - case 97: break; + case 98: break; case 11: { pushState(STRING); return JetTokens.OPEN_QUOTE; } - case 98: break; + case 99: break; case 71: { return JetTokens.FOR_KEYWORD ; } - case 99: break; - case 94: + case 100: break; + case 95: { return JetTokens.RETURN_KEYWORD ; } - case 100: break; - case 78: + case 101: break; + case 81: { return JetTokens.NULL_KEYWORD ; } - case 101: break; + case 102: break; case 34: { if (lBraceCount == 0) { popState(); @@ -860,369 +868,373 @@ class _JetLexer implements FlexLexer { lBraceCount--; return JetTokens.RBRACE; } - case 102: break; + case 103: break; case 18: { return JetTokens.LT ; } - case 103: break; + case 104: break; case 51: { return JetTokens.DO_KEYWORD ; } - case 104: break; + case 105: break; case 17: { return JetTokens.PLUS ; } - case 105: break; + case 106: break; case 67: { return JetTokens.RAW_STRING_LITERAL; } - case 106: break; + case 107: break; case 55: { return JetTokens.PLUSEQ ; } - case 107: break; + case 108: break; + case 86: + { popState(); return JetTokens.THIS_KEYWORD; + } + case 109: break; case 27: { return JetTokens.COMMA ; } - case 108: break; + case 110: break; case 19: { return JetTokens.GT ; } - case 109: break; + case 111: break; case 4: { return JetTokens.WHITE_SPACE; } - case 110: break; + case 112: break; case 24: { return JetTokens.RPAR ; } - case 111: break; + case 113: break; case 54: { return JetTokens.DOUBLE_ARROW; } - case 112: break; - case 80: + case 114: break; + case 79: { return JetTokens.TRUE_KEYWORD ; } - case 113: break; + case 115: break; case 36: { return JetTokens.FIELD_IDENTIFIER; } - case 114: break; + case 116: break; case 59: { return JetTokens.ANDAND ; } - case 115: break; + case 117: break; case 63: { pushState(LONG_TEMPLATE_ENTRY); return JetTokens.LONG_TEMPLATE_ENTRY_START; } - case 116: break; + case 118: break; case 66: { return JetTokens.DOC_COMMENT; } - case 117: break; + case 119: break; case 35: { return JetTokens.FLOAT_LITERAL; } - case 118: break; + case 120: break; case 39: { return JetTokens.EOL_COMMENT; } - case 119: break; + case 121: break; case 83: { return JetTokens.WHEN_KEYWORD ; } - case 120: break; + case 122: break; case 25: { return JetTokens.COLON ; } - case 121: break; + case 123: break; case 57: { return JetTokens.LTEQ ; } - case 122: break; + case 124: break; case 46: { return JetTokens.ARROW ; } - case 123: break; + case 125: break; case 32: { popState(); return JetTokens.IDENTIFIER; } - case 124: break; + case 126: break; case 21: { return JetTokens.LBRACKET ; } - case 125: break; + case 127: break; case 65: { yypushback(2); return JetTokens.INTEGER_LITERAL; } - case 126: break; + case 128: break; case 10: { return JetTokens.CHARACTER_LITERAL; } - case 127: break; + case 129: break; case 72: { return JetTokens.VAR_KEYWORD ; } - case 128: break; + case 130: break; case 58: { return JetTokens.GTEQ ; } - case 129: break; + case 131: break; case 2: { return JetTokens.INTEGER_LITERAL; } - case 130: break; + case 132: break; case 13: { return JetTokens.RBRACE ; } - case 131: break; - case 87: + case 133: break; + case 90: { return JetTokens.CLASS_KEYWORD ; } - case 132: break; + case 134: break; case 14: { return JetTokens.EXCL ; } - case 133: break; - case 69: + case 135: break; + case 68: { return JetTokens.TRY_KEYWORD ; } - case 134: break; + case 136: break; case 52: { return JetTokens.EXCLEQ ; } - case 135: break; + case 137: break; case 45: { return JetTokens.MINUSEQ ; } - case 136: break; - case 89: + case 138: break; + case 87: { return JetTokens.THROW_KEYWORD ; } - case 137: break; - case 86: + case 139: break; + case 89: { return JetTokens.SUPER_KEYWORD ; } - case 138: break; - case 91: + case 140: break; + case 92: { return JetTokens.WHILE_KEYWORD ; } - case 139: break; + case 141: break; case 44: { return JetTokens.MINUSMINUS; } - case 140: break; - case 95: + case 142: break; + case 96: { return JetTokens.CONTINUE_KEYWORD ; } - case 141: break; - case 74: + case 143: break; + case 75: { return JetTokens.NOT_IN; } - case 142: break; + case 144: break; case 38: { return JetTokens.ATAT ; } - case 143: break; + case 145: break; case 6: { return JetTokens.DIV ; } - case 144: break; + case 146: break; case 37: { return JetTokens.LABEL_IDENTIFIER; } - case 145: break; + case 147: break; case 29: { return JetTokens.REGULAR_STRING_PART; } - case 146: break; + case 148: break; case 16: { return JetTokens.QUEST ; } - case 147: break; + case 149: break; case 60: { return JetTokens.OROR ; } - case 148: break; + case 150: break; case 20: { return JetTokens.PERC ; } - case 149: break; + case 151: break; case 76: { return JetTokens.EXCLEQEQEQ; } - case 150: break; + case 152: break; case 61: { return JetTokens.PERCEQ ; } - case 151: break; + case 153: break; case 43: { return JetTokens.RANGE ; } - case 152: break; + case 154: break; case 1: { return TokenType.BAD_CHARACTER; } - case 153: break; - case 96: + case 155: break; + case 97: { return JetTokens.NAMESPACE_KEYWORD ; } - case 154: break; - case 75: + case 156: break; + case 74: { return JetTokens.NOT_IS; } - case 155: break; + case 157: break; case 7: { return JetTokens.MUL ; } - case 156: break; + case 158: break; case 22: { return JetTokens.RBRACKET ; } - case 157: break; + case 159: break; case 56: { return JetTokens.PLUSPLUS ; } - case 158: break; - case 81: + case 160: break; + case 78: { return JetTokens.THIS_KEYWORD ; } - case 159: break; + case 161: break; case 8: { return JetTokens.DOT ; } - case 160: break; + case 162: break; case 26: { return JetTokens.SEMICOLON ; } - case 161: break; - case 50: + case 163: break; + case 49: { return JetTokens.IF_KEYWORD ; } - case 162: break; + case 164: break; case 64: { return JetTokens.ESCAPE_SEQUENCE; } - case 163: break; + case 165: break; case 31: { popState(); return JetTokens.CLOSING_QUOTE; } - case 164: break; + case 166: break; case 15: { return JetTokens.EQ ; } - case 165: break; + case 167: break; case 5: { return JetTokens.AT ; } - case 166: break; - case 68: + case 168: break; + case 69: { return JetTokens.AS_SAFE; } - case 167: break; + case 169: break; case 23: { return JetTokens.LPAR ; } - case 168: break; + case 170: break; case 9: { return JetTokens.MINUS ; } - case 169: break; - case 92: + case 171: break; + case 93: { return JetTokens.FALSE_KEYWORD ; } - case 170: break; - case 82: + case 172: break; + case 80: { return JetTokens.TYPE_KEYWORD ; } - case 171: break; + case 173: break; case 70: { return JetTokens.FUN_KEYWORD ; } - case 172: break; - case 49: + case 174: break; + case 47: { return JetTokens.IS_KEYWORD ; } - case 173: break; + case 175: break; case 30: { popState(); yypushback(1); return JetTokens.DANGLING_NEWLINE; } - case 174: break; + case 176: break; case 33: { lBraceCount++; return JetTokens.LBRACE; } - case 175: break; + case 177: break; case 85: { yypushback(3); return JetTokens.EXCL; } - case 176: break; + case 178: break; case 41: { return JetTokens.DIVEQ ; } - case 177: break; - case 79: + case 179: break; + case 82: { return JetTokens.ELSE_KEYWORD ; } - case 178: break; - case 47: + case 180: break; + case 50: { return JetTokens.AS_KEYWORD ; } - case 179: break; + case 181: break; case 48: { return JetTokens.IN_KEYWORD ; } - case 180: break; + case 182: break; case 53: { return JetTokens.EQEQ ; } - case 181: break; + case 183: break; case 77: { return JetTokens.EQEQEQ ; } - case 182: break; + case 184: break; case 73: { return JetTokens.VAL_KEYWORD ; } - case 183: break; + case 185: break; case 84: { return JetTokens.CAPITALIZED_THIS_KEYWORD ; } - case 184: break; + case 186: break; case 42: { return JetTokens.MULTEQ ; } - case 185: break; + case 187: break; case 62: { pushState(SHORT_TEMPLATE_ENTRY); yypushback(yylength() - 1); return JetTokens.SHORT_TEMPLATE_ENTRY_START; } - case 186: break; + case 188: break; case 12: { return JetTokens.LBRACE ; } - case 187: break; - case 93: + case 189: break; + case 94: { return JetTokens.OBJECT_KEYWORD ; } - case 188: break; - case 90: + case 190: break; + case 91: { return JetTokens.BREAK_KEYWORD ; } - case 189: break; + case 191: break; case 40: { return JetTokens.BLOCK_COMMENT; } - case 190: break; + case 192: break; case 88: { return JetTokens.TRAIT_KEYWORD ; } - case 191: break; + case 193: break; case 28: { return JetTokens.HASH ; } - case 192: break; + case 194: break; default: if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { zzAtEOF = true; diff --git a/compiler/testData/diagnostics/tests/regressions/kt847.jet b/compiler/testData/diagnostics/tests/regressions/kt847.jet new file mode 100644 index 00000000000..4d696af9910 --- /dev/null +++ b/compiler/testData/diagnostics/tests/regressions/kt847.jet @@ -0,0 +1,3 @@ +fun T.mustBe(t : T) { + "$this must be$as$t" +} \ No newline at end of file diff --git a/compiler/testData/psi/StringTemplates.jet b/compiler/testData/psi/StringTemplates.jet index 6b628c0b435..8bdec253be9 100644 --- a/compiler/testData/psi/StringTemplates.jet +++ b/compiler/testData/psi/StringTemplates.jet @@ -7,6 +7,7 @@ fun demo() { fun buzz(f : fun () : Any?) : Int = 1 val sdf = 1 val foo = 3; + "$this must be$as$t" "$abc" "$abc\" "$" diff --git a/compiler/testData/psi/StringTemplates.txt b/compiler/testData/psi/StringTemplates.txt index 1fc2653edcb..07ea659f400 100644 --- a/compiler/testData/psi/StringTemplates.txt +++ b/compiler/testData/psi/StringTemplates.txt @@ -157,6 +157,25 @@ JetFile: StringTemplates.jet PsiElement(INTEGER_LITERAL)('3') PsiElement(SEMICOLON)(';') PsiWhiteSpace('\n ') + STRING_TEMPLATE + PsiElement(OPEN_QUOTE)('"') + SHORT_STRING_TEMPLATE_ENTRY + PsiElement(SHORT_TEMPLATE_ENTRY_START)('$') + THIS_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(this)('this') + LITERAL_STRING_TEMPLATE_ENTRY + PsiElement(REGULAR_STRING_PART)(' must be') + SHORT_STRING_TEMPLATE_ENTRY + PsiElement(SHORT_TEMPLATE_ENTRY_START)('$') + PsiErrorElement:Keyword cannot be used as a reference + PsiElement(as)('as') + SHORT_STRING_TEMPLATE_ENTRY + PsiElement(SHORT_TEMPLATE_ENTRY_START)('$') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('t') + PsiElement(CLOSING_QUOTE)('"') + PsiWhiteSpace('\n ') STRING_TEMPLATE PsiElement(OPEN_QUOTE)('"') SHORT_STRING_TEMPLATE_ENTRY diff --git a/grammar/src/expressions.grm b/grammar/src/expressions.grm index af07f14c2e9..28f3de35070 100644 --- a/grammar/src/expressions.grm +++ b/grammar/src/expressions.grm @@ -134,7 +134,7 @@ label literalConstant : "true" | "false" - : StringWithTemplates + : stringTemplate : NoEscapeString : IntegerLiteral : HexadecimalLiteral @@ -143,6 +143,22 @@ literalConstant : "null" ; +stringTemplate + : "\"" stringTemplateElement* "\"" + ; + +stringTemplateElement + : RegularStringPart + : ShortTemplateEntrySTART (SimpleName | "this") + : EscapeSequence + : longTemplate + ; + +longTemplate + : "${" expression "}" + ; + + isRHS : pattern ; From 337d804ab7919eaa1875c2f4a7bd585c7844809c Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Fri, 16 Dec 2011 09:24:24 +0200 Subject: [PATCH 31/33] some methods from Arrays added to stdlib --- stdlib/ktSrc/Arrays.kt | 73 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/stdlib/ktSrc/Arrays.kt b/stdlib/ktSrc/Arrays.kt index 197cd1c236c..0c55b8f2406 100644 --- a/stdlib/ktSrc/Arrays.kt +++ b/stdlib/ktSrc/Arrays.kt @@ -2,6 +2,8 @@ namespace std import java.io.ByteArrayInputStream +import java.util.Arrays + // Array "constructor" inline fun array(vararg t : T) : Array = t @@ -22,6 +24,77 @@ inline fun byteArray(vararg content : Byte) = content inline fun booleanArray(vararg content : Boolean) = content +inline fun ByteArray.binarySearch(key: Byte) = Arrays.binarySearch(this, key) +inline fun ShortArray.binarySearch(key: Short) = Arrays.binarySearch(this, key) +inline fun IntArray.binarySearch(key: Int) = Arrays.binarySearch(this, key) +inline fun LongArray.binarySearch(key: Long) = Arrays.binarySearch(this, key) +inline fun FloatArray.binarySearch(key: Float) = Arrays.binarySearch(this, key) +inline fun DoubleArray.binarySearch(key: Double) = Arrays.binarySearch(this, key) +inline fun CharArray.binarySearch(key: Char) = Arrays.binarySearch(this, key) + +inline fun ByteArray.binarySearch(fromIndex: Int, toIndex: Int, key: Byte) = Arrays.binarySearch(this, fromIndex, toIndex, key) +inline fun ShortArray.binarySearch(fromIndex: Int, toIndex: Int, key: Short) = Arrays.binarySearch(this, fromIndex, toIndex, key) +inline fun IntArray.binarySearch(fromIndex: Int, toIndex: Int, key: Int) = Arrays.binarySearch(this, fromIndex, toIndex, key) +inline fun LongArray.binarySearch(fromIndex: Int, toIndex: Int, key: Long) = Arrays.binarySearch(this, fromIndex, toIndex, key) +inline fun FloatArray.binarySearch(fromIndex: Int, toIndex: Int, key: Float) = Arrays.binarySearch(this, fromIndex, toIndex, key) +inline fun DoubleArray.binarySearch(fromIndex: Int, toIndex: Int, key: Double) = Arrays.binarySearch(this, fromIndex, toIndex, key) +inline fun CharArray.binarySearch(fromIndex: Int, toIndex: Int, key: Char) = Arrays.binarySearch(this, fromIndex, toIndex, key) + +inline fun Array.binarySearch(key: T, comparator: fun(T,T):Int) = Arrays.binarySearch(this, key, object: java.util.Comparator { + override fun compare(a: T, b: T) = comparator(a, b) + + override fun equals(obj: Any?) = obj.identityEquals(this) +}) + +inline fun BooleanArray.fill(value: Boolean) = Arrays.fill(this, value) +inline fun ByteArray.fill(value: Byte) = Arrays.fill(this, value) +inline fun ShortArray.fill(value: Short) = Arrays.fill(this, value) +inline fun IntArray.fill(value: Int) = Arrays.fill(this, value) +inline fun LongArray.fill(value: Long) = Arrays.fill(this, value) +inline fun FloatArray.fill(value: Float) = Arrays.fill(this, value) +inline fun DoubleArray.fill(value: Double) = Arrays.fill(this, value) +inline fun CharArray.fill(value: Char) = Arrays.fill(this, value) + +inline fun Array.fill(value: T) = Arrays.fill(this as Array, value) + +inline fun ByteArray.sort() = Arrays.sort(this) +inline fun ShortArray.sort() = Arrays.sort(this) +inline fun IntArray.sort() = Arrays.sort(this) +inline fun LongArray.sort() = Arrays.sort(this) +inline fun FloatArray.sort() = Arrays.sort(this) +inline fun DoubleArray.sort() = Arrays.sort(this) +inline fun CharArray.sort() = Arrays.sort(this) + +inline fun ByteArray.sort(fromIndex: Int, toIndex: Int) = Arrays.sort(this, fromIndex, toIndex) +inline fun ShortArray.sort(fromIndex: Int, toIndex: Int) = Arrays.sort(this, fromIndex, toIndex) +inline fun IntArray.sort(fromIndex: Int, toIndex: Int) = Arrays.sort(this, fromIndex, toIndex) +inline fun LongArray.sort(fromIndex: Int, toIndex: Int) = Arrays.sort(this, fromIndex, toIndex) +inline fun FloatArray.sort(fromIndex: Int, toIndex: Int) = Arrays.sort(this, fromIndex, toIndex) +inline fun DoubleArray.sort(fromIndex: Int, toIndex: Int) = Arrays.sort(this, fromIndex, toIndex) +inline fun CharArray.sort(fromIndex: Int, toIndex: Int) = Arrays.sort(this, fromIndex, toIndex) + +inline fun BooleanArray.copyOf(newLength: Int = this.size) = Arrays.copyOf(this, newLength) +inline fun ByteArray.copyOf(newLength: Int = this.size) = Arrays.copyOf(this, newLength) +inline fun ShortArray.copyOf(newLength: Int = this.size) = Arrays.copyOf(this, newLength) +inline fun IntArray.copyOf(newLength: Int = this.size) = Arrays.copyOf(this, newLength) +inline fun LongArray.copyOf(newLength: Int = this.size) = Arrays.copyOf(this, newLength) +inline fun FloatArray.copyOf(newLength: Int = this.size) = Arrays.copyOf(this, newLength) +inline fun DoubleArray.copyOf(newLength: Int = this.size) = Arrays.copyOf(this, newLength) +inline fun CharArray.copyOf(newLength: Int = this.size) = Arrays.copyOf(this, newLength) + +inline fun Array.copyOf(newLength: Int = this.size) : Array = Arrays.copyOf(this, newLength).sure() + +inline fun BooleanArray.copyOfRange(from: Int, to: Int) = Arrays.copyOfRange(this, from, to) +inline fun ByteArray.copyOfRange(from: Int, to: Int) = Arrays.copyOfRange(this, from, to) +inline fun ShortArray.copyOfRange(from: Int, to: Int) = Arrays.copyOfRange(this, from, to) +inline fun IntArray.copyOfRange(from: Int, to: Int) = Arrays.copyOfRange(this, from, to) +inline fun LongArray.copyOfRange(from: Int, to: Int) = Arrays.copyOfRange(this, from, to) +inline fun FloatArray.copyOfRange(from: Int, to: Int) = Arrays.copyOfRange(this, from, to) +inline fun DoubleArray.copyOfRange(from: Int, to: Int) = Arrays.copyOfRange(this, from, to) +inline fun CharArray.copyOfRange(from: Int, to: Int) = Arrays.copyOfRange(this, from, to) + +inline fun Array.copyOfRange(from: Int, to: Int) : Array = Arrays.copyOfRange(this, from, to).sure() + inline val ByteArray.inputStream : ByteArrayInputStream get() = ByteArrayInputStream(this) From 12a890508fac2d7af30ebda65c3f0c2ad652dfe6 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Fri, 16 Dec 2011 12:27:40 +0400 Subject: [PATCH 32/33] Debug highlighting for error types --- .../jetbrains/jet/lang/types/ErrorUtils.java | 21 +++++++++++++++---- .../annotations/DebugInfoAnnotator.java | 4 +++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java index 2025559fc74..191e0bfba70 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java @@ -1,6 +1,7 @@ package org.jetbrains.jet.lang.types; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; @@ -196,10 +197,22 @@ public class ErrorUtils { } public static boolean isErrorType(@NotNull JetType type) { - return type != TypeUtils.NO_EXPECTED_TYPE &&( - (type instanceof DeferredType && ((DeferredType) type).getActualType() == null) || - type instanceof ErrorTypeImpl || - isError(type.getConstructor())); + return type != TypeUtils.NO_EXPECTED_TYPE && !(type instanceof NamespaceType) && + ( + (type instanceof DeferredType && ((DeferredType) type).getActualType() == null) || + type instanceof ErrorTypeImpl || + isError(type.getConstructor()) + ); + } + + public static boolean containsErrorType(@Nullable JetType type) { + if (type == null) return false; + if (type instanceof NamespaceType) return false; + if (isErrorType(type)) return true; + for (TypeProjection projection : type.getArguments()) { + if (containsErrorType(projection.getType())) return true; + } + return false; } public static boolean isError(@NotNull DeclarationDescriptor candidate) { diff --git a/idea/src/org/jetbrains/jet/plugin/annotations/DebugInfoAnnotator.java b/idea/src/org/jetbrains/jet/plugin/annotations/DebugInfoAnnotator.java index 8d87ba88ef5..68aae0586f1 100644 --- a/idea/src/org/jetbrains/jet/plugin/annotations/DebugInfoAnnotator.java +++ b/idea/src/org/jetbrains/jet/plugin/annotations/DebugInfoAnnotator.java @@ -17,6 +17,7 @@ import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl; import org.jetbrains.jet.lang.types.ErrorUtils; +import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.plugin.JetHighlighter; import org.jetbrains.jet.plugin.compiler.WholeProjectAnalyzerFacade; @@ -102,7 +103,8 @@ public class DebugInfoAnnotator implements Annotator { } boolean resolved = target != null; boolean unresolved = unresolvedReferences.contains(expression); - if (declarationDescriptor != null && !ApplicationManager.getApplication().isUnitTestMode() && ErrorUtils.isError(declarationDescriptor)) { + JetType expressionType = bindingContext.get(EXPRESSION_TYPE, expression); + if (declarationDescriptor != null && !ApplicationManager.getApplication().isUnitTestMode() && (ErrorUtils.isError(declarationDescriptor) || ErrorUtils.containsErrorType(expressionType))) { holder.createErrorAnnotation(expression, "[DEBUG] Resolved to error element").setTextAttributes(JetHighlighter.JET_RESOLVED_TO_ERROR); } if (resolved && unresolved) { From 076768b4751ab6c2ddfb9219eb1277479248d094 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Fri, 16 Dec 2011 10:45:46 +0200 Subject: [PATCH 33/33] KT-846: better (and correct) names for shared vars --- .../org/jetbrains/jet/codegen/ClosureCodegen.java | 7 ++++++- .../jet/codegen/ImplementationBodyCodegen.java | 2 +- .../jet/codegen/ObjectOrClosureCodegen.java | 2 +- .../testData/codegen/extensionFunctions/shared.kt | 13 +++++++++++++ compiler/testData/codegen/regressions/kt344.jet | 9 +++------ .../jet/codegen/ExtensionFunctionsTest.java | 5 +++++ stdlib/ktSrc/Arrays.kt | 3 ++- 7 files changed, 31 insertions(+), 10 deletions(-) create mode 100644 compiler/testData/codegen/extensionFunctions/shared.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java index 6ace88a728b..feced45f382 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java @@ -23,6 +23,7 @@ import org.objectweb.asm.commons.InstructionAdapter; import org.objectweb.asm.commons.Method; import org.objectweb.asm.signature.SignatureWriter; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -213,9 +214,12 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { int argCount = captureThis ? 1 : 0; argCount += (captureReceiver != null ? 1 : 0); + ArrayList variableDescriptors = new ArrayList(); + for (DeclarationDescriptor descriptor : closure.keySet()) { if(descriptor instanceof VariableDescriptor && !(descriptor instanceof PropertyDescriptor)) { argCount++; + variableDescriptors.add((VariableDescriptor) descriptor); } else if(descriptor instanceof FunctionDescriptor) { assert captureReceiver != null; @@ -271,7 +275,8 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { k++; } else { - fieldName = "$" + (i-k); + VariableDescriptor removed = variableDescriptors.remove(0); + fieldName = "$" + removed.getName(); i++; } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 2d36920442d..77c65e1c4d4 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -494,7 +494,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { iv.load(0, JetTypeMapper.TYPE_OBJECT); iv.load(k, StackValue.refType(sharedVarType)); k += StackValue.refType(sharedVarType).getSize(); - iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "$" + (l+1), sharedVarType.getDescriptor()); + iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "$" + varDescr.getName(), sharedVarType.getDescriptor()); l++; } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ObjectOrClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ObjectOrClosureCodegen.java index c1982e6167d..4259f9ee41e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ObjectOrClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ObjectOrClosureCodegen.java @@ -45,7 +45,7 @@ public class ObjectOrClosureCodegen { final Type type = sharedVarType != null ? sharedVarType : localType; StackValue outerValue = StackValue.local(idx, type); - final String fieldName = "$" + (closure.size() + 1); // + "$" + vd.getName(); + final String fieldName = "$" + vd.getName(); StackValue innerValue = sharedVarType != null ? StackValue.fieldForSharedVar(localType, name, fieldName) : StackValue.field(type, name, fieldName, false); cv.newField(null, Opcodes.ACC_PUBLIC, fieldName, type.getDescriptor(), null, null); diff --git a/compiler/testData/codegen/extensionFunctions/shared.kt b/compiler/testData/codegen/extensionFunctions/shared.kt new file mode 100644 index 00000000000..216ba549ba3 --- /dev/null +++ b/compiler/testData/codegen/extensionFunctions/shared.kt @@ -0,0 +1,13 @@ +fun T.mustBe(t : T) { + assert("$this must be $t") {this == t} +} + +inline fun assert(message : String, condition : fun() : Boolean) { + if (!condition()) + throw AssertionError(message) +} + +fun box() : String { + "lala" mustBe "lala" + return "OK" +} diff --git a/compiler/testData/codegen/regressions/kt344.jet b/compiler/testData/codegen/regressions/kt344.jet index db228754a3e..39a8f550b74 100644 --- a/compiler/testData/codegen/regressions/kt344.jet +++ b/compiler/testData/codegen/regressions/kt344.jet @@ -1,4 +1,3 @@ -/* fun s0() : Boolean { val y = "222" val foo = { @@ -127,7 +126,7 @@ fun t8() : Boolean { return x == 30.sht } -fun t9(x: Int) : Boolean { +fun t9(var x: Int) : Boolean { while(x < 100) { x++ } @@ -146,7 +145,7 @@ fun t10() : Boolean { return y == 2 } -fun t11(x: Int) : Int { +fun t11(var x: Int) : Int { val foo = { x = x + 1 val bar = { @@ -160,7 +159,7 @@ fun t11(x: Int) : Int { } return x } -*/ + fun t12(x: Int) : Int { var y = x val runnable = object : Runnable { @@ -175,7 +174,6 @@ fun t12(x: Int) : Int { } fun box(): String { -/* if (!s0()) return "s0 fail" if (!s1()) return "s1 fail" if (!t1()) return "t1 fail" @@ -189,7 +187,6 @@ fun box(): String { if (!t9(0)) return "t9 fail" if (!t10()) return "t10 fail" if (t11(1) != 104) return "t11 fail" -*/ if (t12(0) != 100) return "t12 fail" return "OK" diff --git a/compiler/tests/org/jetbrains/jet/codegen/ExtensionFunctionsTest.java b/compiler/tests/org/jetbrains/jet/codegen/ExtensionFunctionsTest.java index fc63c1de423..e26bd1b88ae 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ExtensionFunctionsTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ExtensionFunctionsTest.java @@ -34,6 +34,11 @@ public class ExtensionFunctionsTest extends CodegenTestCase { blackBoxFile("extensionFunctions/virtual.jet"); } + public void testShared() throws Exception { + blackBoxFile("extensionFunctions/shared.kt"); + System.out.println(generateToText()); + } + public void testKt475() throws Exception { blackBoxFile("regressions/kt475.jet"); } diff --git a/stdlib/ktSrc/Arrays.kt b/stdlib/ktSrc/Arrays.kt index 0c55b8f2406..68f2234c716 100644 --- a/stdlib/ktSrc/Arrays.kt +++ b/stdlib/ktSrc/Arrays.kt @@ -40,12 +40,13 @@ inline fun FloatArray.binarySearch(fromIndex: Int, toIndex: Int, key: Float) = inline fun DoubleArray.binarySearch(fromIndex: Int, toIndex: Int, key: Double) = Arrays.binarySearch(this, fromIndex, toIndex, key) inline fun CharArray.binarySearch(fromIndex: Int, toIndex: Int, key: Char) = Arrays.binarySearch(this, fromIndex, toIndex, key) +/* inline fun Array.binarySearch(key: T, comparator: fun(T,T):Int) = Arrays.binarySearch(this, key, object: java.util.Comparator { override fun compare(a: T, b: T) = comparator(a, b) override fun equals(obj: Any?) = obj.identityEquals(this) }) - +*/ inline fun BooleanArray.fill(value: Boolean) = Arrays.fill(this, value) inline fun ByteArray.fill(value: Byte) = Arrays.fill(this, value) inline fun ShortArray.fill(value: Short) = Arrays.fill(this, value)