diff --git a/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java b/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java index 8c33cba5061..11ca1bf714d 100644 --- a/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java +++ b/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java @@ -595,22 +595,6 @@ public class JetControlFlowProcessor { builder.read(expression); } - @Override - public void visitObjectLiteralExpression(JetObjectLiteralExpression expression) { - List delegationSpecifiers = expression.getObjectDeclaration().getDelegationSpecifiers(); - for (JetDelegationSpecifier delegationSpecifier : delegationSpecifiers) { - if (delegationSpecifier instanceof JetDelegatorByExpressionSpecifier) { - JetDelegatorByExpressionSpecifier specifier = (JetDelegatorByExpressionSpecifier) delegationSpecifier; - JetExpression delegateExpression = specifier.getDelegateExpression(); - if (delegateExpression != null) { - value(delegateExpression, false, false); - } - } - } - builder.read(expression); - } - - @Override public void visitIsExpression(JetIsExpression expression) { value(expression.getLeftHandSide(), false, inCondition); @@ -720,6 +704,32 @@ public class JetControlFlowProcessor { builder.bindLabel(doneLabel); } + @Override + public void visitObjectLiteralExpression(JetObjectLiteralExpression expression) { +// List delegationSpecifiers = expression.getObjectDeclaration().getDelegationSpecifiers(); +// for (JetDelegationSpecifier delegationSpecifier : delegationSpecifiers) { +// if (delegationSpecifier instanceof JetDelegatorByExpressionSpecifier) { +// JetDelegatorByExpressionSpecifier specifier = (JetDelegatorByExpressionSpecifier) delegationSpecifier; +// JetExpression delegateExpression = specifier.getDelegateExpression(); +// if (delegateExpression != null) { +// value(delegateExpression, false, false); +// } +// } +// } + value(expression.getObjectDeclaration(), false, inCondition); + builder.read(expression); + } + + @Override + public void visitObjectDeclaration(JetObjectDeclaration declaration) { + for (JetDelegationSpecifier delegationSpecifier : declaration.getDelegationSpecifiers()) { + value(delegationSpecifier, false, inCondition); + } + for (JetDeclaration jetDeclaration : declaration.getDeclarations()) { + FOR_LOCAL_CLASSES.value(jetDeclaration, false, false); + } + } + @Override public void visitTypeProjection(JetTypeProjection typeProjection) { // TODO : Support Type Arguments. Class object may be initialized at this point"); @@ -730,4 +740,11 @@ public class JetControlFlowProcessor { builder.unsupported(element); } } + + private final CFPVisitor FOR_LOCAL_CLASSES = new CFPVisitor(false, false) { + @Override + public void visitFunction(JetFunction function) { + // Nothing + } + }; } \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/lang/descriptors/DeclarationDescriptorImpl.java b/idea/src/org/jetbrains/jet/lang/descriptors/DeclarationDescriptorImpl.java index fe649f3d5a3..e6a9e98d648 100644 --- a/idea/src/org/jetbrains/jet/lang/descriptors/DeclarationDescriptorImpl.java +++ b/idea/src/org/jetbrains/jet/lang/descriptors/DeclarationDescriptorImpl.java @@ -44,6 +44,6 @@ public abstract class DeclarationDescriptorImpl extends AnnotatedImpl implements @Override public String toString() { - return DescriptorRenderer.TEXT.render(this) + "[" + getClass().getCanonicalName() + "@" + System.identityHashCode(this) + "]"; + return DescriptorRenderer.TEXT_FOR_DEBUG.render(this) + "[" + getClass().getCanonicalName() + "@" + System.identityHashCode(this) + "]"; } } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/BindingContext.java b/idea/src/org/jetbrains/jet/lang/resolve/BindingContext.java index ddd753afb7c..910f0c60e76 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/BindingContext.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/BindingContext.java @@ -25,6 +25,7 @@ public interface BindingContext { VariableDescriptor getVariableDescriptor(JetParameter declaration); PropertyDescriptor getPropertyDescriptor(JetParameter primaryConstructorParameter); + PropertyDescriptor getPropertyDescriptor(JetObjectDeclarationName objectDeclarationName); JetType getExpressionType(JetExpression expression); diff --git a/idea/src/org/jetbrains/jet/lang/resolve/BindingTraceContext.java b/idea/src/org/jetbrains/jet/lang/resolve/BindingTraceContext.java index 120f284f37e..d170dd17fcc 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/BindingTraceContext.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/BindingTraceContext.java @@ -194,6 +194,11 @@ public class BindingTraceContext implements BindingContext, BindingTrace { return primaryConstructorParameterDeclarationsToPropertyDescriptors.get(primaryConstructorParameter); } + @Override + public PropertyDescriptor getPropertyDescriptor(JetObjectDeclarationName objectDeclarationName) { + return (PropertyDescriptor) declarationsToDescriptors.get(objectDeclarationName); + } + @Nullable @Override public ConstructorDescriptor getConstructorDescriptor(@NotNull JetElement declaration) { diff --git a/idea/src/org/jetbrains/jet/lang/types/DeferredType.java b/idea/src/org/jetbrains/jet/lang/types/DeferredType.java index 565703c0f49..1101c8917b4 100644 --- a/idea/src/org/jetbrains/jet/lang/types/DeferredType.java +++ b/idea/src/org/jetbrains/jet/lang/types/DeferredType.java @@ -16,6 +16,10 @@ public class DeferredType implements JetType { this.lazyValue = lazyValue; } + public boolean isComputed() { + return lazyValue.isComputed(); + } + public JetType getActualType() { return lazyValue.get(); } diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java index bbbe6269c2b..afe851e3b6c 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java @@ -1870,6 +1870,17 @@ public class JetTypeInferrer { this.scope = scope; } + @Override + public void visitObjectDeclaration(JetObjectDeclaration declaration) { + TopDownAnalyzer topDownAnalyzer = new TopDownAnalyzer(semanticServices, trace); + topDownAnalyzer.processObject(scope, scope.getContainingDeclaration(), declaration); + ClassDescriptor classDescriptor = trace.getBindingContext().getClassDescriptor(declaration); + if (classDescriptor != null) { + PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolveObjectDeclarationAsPropertyDescriptor(scope.getContainingDeclaration(), declaration, classDescriptor); + scope.addVariableDescriptor(propertyDescriptor); + } + } + @Override public void visitProperty(JetProperty property) { diff --git a/idea/src/org/jetbrains/jet/lang/types/LazyValue.java b/idea/src/org/jetbrains/jet/lang/types/LazyValue.java index 75dd977d7ac..482df0533c3 100644 --- a/idea/src/org/jetbrains/jet/lang/types/LazyValue.java +++ b/idea/src/org/jetbrains/jet/lang/types/LazyValue.java @@ -1,7 +1,5 @@ package org.jetbrains.jet.lang.types; -import org.jetbrains.annotations.NotNull; - /** * @author abreslav */ @@ -19,8 +17,8 @@ public abstract class LazyValue { protected abstract T compute(); - public State getState() { - return state; + public boolean isComputed() { + return state == State.ERROR || state == State.COMPUTED; } public final T get() { diff --git a/idea/src/org/jetbrains/jet/resolve/DescriptorRenderer.java b/idea/src/org/jetbrains/jet/resolve/DescriptorRenderer.java index cdd21b45eea..7b25f7fd893 100644 --- a/idea/src/org/jetbrains/jet/resolve/DescriptorRenderer.java +++ b/idea/src/org/jetbrains/jet/resolve/DescriptorRenderer.java @@ -26,6 +26,16 @@ public class DescriptorRenderer { } public static final DescriptorRenderer TEXT = new DescriptorRenderer(); + public static final DescriptorRenderer TEXT_FOR_DEBUG = new DescriptorRenderer() { + @Override + public String renderType(JetType type) { + if (type instanceof DeferredType) { + DeferredType deferredType = (DeferredType) type; + if (!deferredType.isComputed()) return ""; + } + return "" + type; + } + }; public static final DescriptorRenderer HTML = new DescriptorRenderer() { @Override @@ -68,6 +78,10 @@ public class DescriptorRenderer { return keyword; } + public String renderType(JetType type) { + return "" + type; + } + protected String escape(String s) { return s; } @@ -139,25 +153,25 @@ public class DescriptorRenderer { if (inType != null && outType != null) { builder.append(renderKeyword("var")).append(" "); if (inType.equals(outType)) { - typeString = outType.toString(); + typeString = renderType(outType); } else { - typeString = "<" + renderKeyword("in") + ": " + inType + " " + renderKeyword("out") + ": " + outType + ">"; + typeString = "<" + renderKeyword("in") + ": " + renderType(inType) + " " + renderKeyword("out") + ": " + renderType(outType) + ">"; } } else if (outType != null) { builder.append(renderKeyword("val")).append(" "); - typeString = outType.toString(); + typeString = renderType(outType); } else if (inType != null) { builder.append(lt()).append("write-only> "); - typeString = inType.toString(); + typeString = renderType(inType); } renderTypeParameters(typeParameters, builder); if (receiverType != null) { - builder.append(escape(receiverType.toString())).append("."); + builder.append(escape(renderType(receiverType))).append("."); } return typeString; @@ -183,7 +197,7 @@ public class DescriptorRenderer { JetType receiverType = descriptor.getReceiverType(); if (receiverType != null) { - builder.append(escape(receiverType.toString())).append("."); + builder.append(escape(renderType(receiverType))).append("."); } renderName(descriptor, builder); @@ -195,7 +209,7 @@ public class DescriptorRenderer { builder.append(", "); } } - builder.append(") : ").append(escape(descriptor.getUnsubstitutedReturnType().toString())); + builder.append(") : ").append(escape(renderType(descriptor.getUnsubstitutedReturnType()))); return super.visitFunctionDescriptor(descriptor, builder); } @@ -244,7 +258,7 @@ public class DescriptorRenderer { builder.append(" : "); for (Iterator iterator = supertypes.iterator(); iterator.hasNext(); ) { JetType supertype = iterator.next(); - builder.append(supertype); + builder.append(renderType(supertype)); if (iterator.hasNext()) { builder.append(", "); } @@ -261,7 +275,7 @@ public class DescriptorRenderer { if (!descriptor.getUpperBounds().isEmpty()) { JetType bound = descriptor.getUpperBounds().iterator().next(); if (bound != JetStandardClasses.getAnyType()) { - builder.append(" : ").append(bound); + builder.append(" : ").append(renderType(bound)); if (descriptor.getUpperBounds().size() > 1) { builder.append(" (...)"); } diff --git a/idea/testData/checker/Objects.jet b/idea/testData/checker/Objects.jet index 145260bcb84..4837a57408e 100644 --- a/idea/testData/checker/Objects.jet +++ b/idea/testData/checker/Objects.jet @@ -57,3 +57,27 @@ namespace nestedObejcts { val d = A.B.A val e = B.A.B } + +namespace localObjects { + object A { + val x : Int + } + + class Foo { + fun foo() : Int + } + + fun test() { + A.x + val b = object : Foo { + } + b.foo() + + object B { + fun foo() {} + } + B.foo() + } + + val bb = B.foo() +} diff --git a/idea/testData/resolve/LocalObjects.jet b/idea/testData/resolve/LocalObjects.jet new file mode 100644 index 00000000000..e46a6abb22e --- /dev/null +++ b/idea/testData/resolve/LocalObjects.jet @@ -0,0 +1,23 @@ +namespace localObjects { + object ~A~A { + ~x~val x : Int + } + + class Foo { + ~foo()~fun foo() : Int + } + + fun test() { + `A`A.`x`x + val b = object : Foo { + } + b.`foo()`foo() + + object ~B~B { + ~B.foo()~fun foo() {} + } + `B`B.`B.foo()`foo() + } + + val bb = `!`B.foo() +} diff --git a/idea/tests/org/jetbrains/jet/JetTestUtils.java b/idea/tests/org/jetbrains/jet/JetTestUtils.java index 2d25eb2326c..9944801a755 100644 --- a/idea/tests/org/jetbrains/jet/JetTestUtils.java +++ b/idea/tests/org/jetbrains/jet/JetTestUtils.java @@ -128,6 +128,11 @@ public class JetTestUtils { throw new UnsupportedOperationException(); // TODO } + @Override + public PropertyDescriptor getPropertyDescriptor(JetObjectDeclarationName objectDeclarationName) { + throw new UnsupportedOperationException(); // TODO + } + @Override public JetType getExpressionType(JetExpression expression) { throw new UnsupportedOperationException(); // TODO