JET-76 Support object declarations

JET-62 Support object-expressions
No tests yet
This commit is contained in:
Andrey Breslav
2011-06-02 20:56:01 +04:00
parent efd417e043
commit ed16a29a5f
14 changed files with 261 additions and 46 deletions
@@ -17,6 +17,7 @@ public interface JetNodeTypes {
JetNodeType EXTENSION = new JetNodeType("EXTENSION", JetExtension.class);
JetNodeType TYPEDEF = new JetNodeType("TYPEDEF", JetTypedef.class);
JetNodeType OBJECT_DECLARATION = new JetNodeType("OBJECT_DECLARATION", JetObjectDeclaration.class);
JetNodeType OBJECT_DECLARATION_NAME = new JetNodeType("OBJECT_DECLARATION_NAME", JetObjectDeclarationName.class);
JetNodeType CLASS_OBJECT = new JetNodeType("CLASS_OBJECT", JetClassObject.class);
JetNodeType CONSTRUCTOR = new JetNodeType("CONSTRUCTOR", JetConstructor.class);
@@ -172,6 +172,26 @@ public class JetLineMarkerProvider implements LineMarkerProvider {
}
);
}
if (element instanceof JetObjectDeclaration) {
JetObjectDeclaration jetObjectDeclaration = (JetObjectDeclaration) element;
return new LineMarkerInfo<JetObjectDeclaration>(
jetObjectDeclaration, jetObjectDeclaration.getTextOffset(), Icons.ANONYMOUS_CLASS_ICON, Pass.UPDATE_ALL,
new Function<JetObjectDeclaration, String>() {
@Override
public String fun(JetObjectDeclaration jetObjectDeclaration) {
ClassDescriptor classDescriptor = bindingContext.getClassDescriptor(jetObjectDeclaration);
return DescriptorRenderer.HTML.renderAsObject(classDescriptor);
}
},
new GutterIconNavigationHandler<JetObjectDeclaration>() {
@Override
public void navigate(MouseEvent e, JetObjectDeclaration elt) {
}
}
);
}
return null;
}
@@ -607,7 +607,9 @@ public class JetParsing extends AbstractJetParsing {
advance(); // OBJECT_KEYWORD
if (declaration) {
PsiBuilder.Marker propertyDeclaration = mark();
expect(IDENTIFIER, "Expecting object name", TokenSet.create(LBRACE));
propertyDeclaration.done(OBJECT_DECLARATION_NAME);
}
else {
if (at(IDENTIFIER)) {
@@ -16,4 +16,13 @@ public interface JetClassOrObject {
@NotNull
List<JetDelegationSpecifier> getDelegationSpecifiers();
@NotNull
List<JetClassInitializer> getAnonymousInitializers();
// Objects always "have" a primary constructor
boolean hasPrimaryConstructor();
@Nullable
String getName();
}
@@ -1,6 +1,9 @@
package org.jetbrains.jet.lang.psi;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.JetNodeTypes;
@@ -16,6 +19,29 @@ public class JetObjectDeclaration extends JetNamedDeclaration implements JetClas
super(node);
}
@Override
public String getName() {
JetObjectDeclarationName nameAsDeclaration = getNameAsDeclaration();
return nameAsDeclaration == null ? "<Anonymous>" : nameAsDeclaration.getName();
}
@Override
public PsiElement getNameIdentifier() {
JetObjectDeclarationName nameAsDeclaration = getNameAsDeclaration();
return nameAsDeclaration == null ? null : nameAsDeclaration.getNameIdentifier();
}
@Override
public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException {
JetObjectDeclarationName nameAsDeclaration = getNameAsDeclaration();
return nameAsDeclaration == null ? null : nameAsDeclaration.setName(name);
}
@Nullable
public JetObjectDeclarationName getNameAsDeclaration() {
return (JetObjectDeclarationName) findChildByType(JetNodeTypes.OBJECT_DECLARATION_NAME);
}
@Override
@Nullable
public JetDelegationSpecifierList getDelegationSpecifierList() {
@@ -29,6 +55,20 @@ public class JetObjectDeclaration extends JetNamedDeclaration implements JetClas
return list != null ? list.getDelegationSpecifiers() : Collections.<JetDelegationSpecifier>emptyList();
}
@Override
@NotNull
public List<JetClassInitializer> getAnonymousInitializers() {
JetClassBody body = (JetClassBody) findChildByType(JetNodeTypes.CLASS_BODY);
if (body == null) return Collections.emptyList();
return body.getAnonymousInitializers();
}
@Override
public boolean hasPrimaryConstructor() {
return true;
}
@Override
@NotNull
public List<JetDeclaration> getDeclarations() {
@@ -37,4 +77,9 @@ public class JetObjectDeclaration extends JetNamedDeclaration implements JetClas
return body.getDeclarations();
}
@Override
public void accept(JetVisitor visitor) {
visitor.visitObjectDeclaration(this);
}
}
@@ -0,0 +1,14 @@
package org.jetbrains.jet.lang.psi;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
/**
* @author abreslav
*/
public class JetObjectDeclarationName extends JetNamedDeclaration {
public JetObjectDeclarationName(@NotNull ASTNode node) {
super(node);
}
}
@@ -393,4 +393,8 @@ public class JetVisitor extends PsiElementVisitor {
public void visitDecomposerPattern(JetDecomposerPattern pattern) {
visitPattern(pattern);
}
public void visitObjectDeclaration(JetObjectDeclaration declaration) {
visitNamedDeclaration(declaration);
}
}
@@ -1,11 +1,10 @@
package org.jetbrains.jet.lang.resolve;
import com.intellij.psi.PsiElement;
import org.jetbrains.jet.codegen.ClassCodegen;
import org.jetbrains.jet.lang.JetDiagnostic;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.JetType;
import java.util.Collection;
@@ -17,7 +16,7 @@ public interface BindingContext {
DeclarationDescriptor getDeclarationDescriptor(PsiElement declaration);
NamespaceDescriptor getNamespaceDescriptor(JetNamespace declaration);
ClassDescriptor getClassDescriptor(JetClass declaration);
ClassDescriptor getClassDescriptor(JetClassOrObject declaration);
TypeParameterDescriptor getTypeParameterDescriptor(JetTypeParameter declaration);
FunctionDescriptor getFunctionDescriptor(JetFunction declaration);
ConstructorDescriptor getConstructorDescriptor(JetElement declaration);
@@ -165,8 +165,8 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
}
@Override
public ClassDescriptor getClassDescriptor(JetClass declaration) {
return (ClassDescriptor) declarationsToDescriptors.get(declaration);
public ClassDescriptor getClassDescriptor(JetClassOrObject declaration) {
return (ClassDescriptor) declarationsToDescriptors.get((JetDeclaration) declaration);
}
@Override
@@ -148,7 +148,7 @@ public class ClassDescriptorResolver {
// TODO : Bounds from with
}
public void resolveSupertypes(@NotNull JetClass jetClass, @NotNull MutableClassDescriptor descriptor) {
public void resolveSupertypes(@NotNull JetClassOrObject jetClass, @NotNull MutableClassDescriptor descriptor) {
List<JetDelegationSpecifier> delegationSpecifiers = jetClass.getDelegationSpecifiers();
// TODO : assuming that the hierarchy is acyclic
Collection<? extends JetType> superclasses = delegationSpecifiers.isEmpty()
@@ -355,6 +355,30 @@ public class ClassDescriptorResolver {
return variableDescriptor;
}
public PropertyDescriptor resolveObjectDeclarationAsPropertyDescriptor(@NotNull DeclarationDescriptor containingDeclaration, JetObjectDeclaration objectDeclaration, @NotNull ClassDescriptor classDescriptor) {
JetModifierList modifierList = objectDeclaration.getModifierList();
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
containingDeclaration,
AnnotationResolver.INSTANCE.resolveAnnotations(modifierList),
resolveModifiers(modifierList, DEFAULT_MODIFIERS), // TODO : default modifiers differ in different contexts
false,
null,
JetPsiUtil.safeName(objectDeclaration.getName()),
null,
classDescriptor.getDefaultType());
propertyDescriptor.initialize(
Collections.<TypeParameterDescriptor>emptyList(),
null, // TODO : is it really OK?
null);
JetObjectDeclarationName nameAsDeclaration = objectDeclaration.getNameAsDeclaration();
if (nameAsDeclaration != null) {
trace.recordDeclarationResolution(nameAsDeclaration, propertyDescriptor);
}
return propertyDescriptor;
}
@NotNull
public PropertyDescriptor resolvePropertyDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope scope, JetProperty property) {
@@ -24,6 +24,7 @@ import java.util.*;
public class TopDownAnalyzer {
private final Map<JetClass, MutableClassDescriptor> classes = Maps.newLinkedHashMap();
private final Map<JetObjectDeclaration, MutableClassDescriptor> objects = Maps.newLinkedHashMap();
private final Map<JetNamespace, WritableScope> namespaceScopes = Maps.newHashMap();
private final Map<JetNamespace, NamespaceDescriptorImpl> namespaceDescriptors = Maps.newHashMap();
@@ -36,11 +37,11 @@ public class TopDownAnalyzer {
private final JetSemanticServices semanticServices;
private final ClassDescriptorResolver classDescriptorResolver;
private final BindingTraceContext trace;
private final BindingTrace trace;
private final BindingTraceAdapter traceForConstructors;
private final BindingTraceAdapter traceForMembers;
public TopDownAnalyzer(JetSemanticServices semanticServices, @NotNull BindingTraceContext bindingTrace) {
public TopDownAnalyzer(JetSemanticServices semanticServices, @NotNull BindingTrace bindingTrace) {
this.semanticServices = semanticServices;
this.classDescriptorResolver = semanticServices.getClassDescriptorResolver(bindingTrace);
this.trace = bindingTrace;
@@ -53,7 +54,7 @@ public class TopDownAnalyzer {
if (expression instanceof JetSimpleNameExpression) {
JetSimpleNameExpression simpleNameExpression = (JetSimpleNameExpression) expression;
if (simpleNameExpression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER) {
if (!trace.hasBackingField((PropertyDescriptor) descriptor)) {
if (!trace.getBindingContext().hasBackingField((PropertyDescriptor) descriptor)) {
TopDownAnalyzer.this.trace.getErrorHandler().genericError(expression.getNode(), "This property does not have a backing field");
}
}
@@ -83,14 +84,46 @@ public class TopDownAnalyzer {
process(outerScope, standardLibraryNamespace, namespace.getDeclarations());
}
public void process(@NotNull WritableScope outerScope, NamespaceLike owner, @NotNull List<JetDeclaration> declarations) {
public void processObject(@NotNull JetScope outerScope, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetObjectDeclaration object) {
// objects.put(object, mutableClassDescriptor);
// WritableScopeImpl writableScope = new WritableScopeImpl(outerScope, outerScope.getContainingDeclaration(), trace.getErrorHandler());
process(outerScope, new NamespaceLike.Adapter(containingDeclaration) {
@Override
public NamespaceDescriptorImpl getNamespace(String name) {
throw new UnsupportedOperationException();
}
@Override
public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) {
throw new UnsupportedOperationException();
}
@Override
public void addClassifierDescriptor(@NotNull MutableClassDescriptor classDescriptor) {
}
@Override
public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) {
throw new UnsupportedOperationException();
}
@Override
public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
}
}, Collections.<JetDeclaration>singletonList(object));
}
public void process(@NotNull JetScope outerScope, NamespaceLike owner, @NotNull List<JetDeclaration> declarations) {
collectNamespacesAndClassifiers(outerScope, owner, declarations); // namespaceScopes, classes
createTypeConstructors(); // create type constructors for classes and generic parameters
resolveTypesInClassHeaders(); // Generic bounds and types in supertype lists (no expressions or constructor resolution)
checkGenericBoundsInClassHeaders(); // For the types resolved so far
resolveFunctionAndPropertyHeaders(declarations); // Constructor headers are resolved as well
resolveFunctionAndPropertyHeaders(); // Constructor headers are resolved as well
resolveBehaviorDeclarationBodies();
}
@@ -131,16 +164,32 @@ public class TopDownAnalyzer {
@Override
public void visitClass(JetClass klass) {
visitClassOrObject(klass, (Map) classes, owner, outerScope);
}
@Override
public void visitObjectDeclaration(JetObjectDeclaration declaration) {
MutableClassDescriptor mutableClassDescriptor = visitClassOrObject(declaration, (Map) objects, owner, outerScope);
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(mutableClassDescriptor, Collections.<Annotation>emptyList(), true);
constructorDescriptor.initialize(Collections.<ValueParameterDescriptor>emptyList());
// TODO : make the constructor private?
mutableClassDescriptor.setPrimaryConstructor(constructorDescriptor);
trace.recordDeclarationResolution(declaration, mutableClassDescriptor);
}
private MutableClassDescriptor visitClassOrObject(JetClassOrObject declaration, Map<JetClassOrObject, MutableClassDescriptor> map, NamespaceLike owner, JetScope outerScope) {
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(trace, owner, outerScope);
mutableClassDescriptor.setName(JetPsiUtil.safeName(klass.getName()));
mutableClassDescriptor.setName(JetPsiUtil.safeName(declaration.getName()));
owner.addClassifierDescriptor(mutableClassDescriptor);
classes.put(klass, mutableClassDescriptor);
declaringScopes.put(klass, outerScope);
map.put(declaration, mutableClassDescriptor);
declaringScopes.put((JetDeclaration) declaration, outerScope);
JetScope classScope = mutableClassDescriptor.getScopeForMemberResolution();
collectNamespacesAndClassifiers(classScope, mutableClassDescriptor, klass.getDeclarations());
collectNamespacesAndClassifiers(classScope, mutableClassDescriptor, declaration.getDeclarations());
return mutableClassDescriptor;
}
@Override
@@ -156,6 +205,7 @@ public class TopDownAnalyzer {
}
}
private void processImports(@NotNull JetNamespace namespace, @NotNull WriteThroughScope namespaceScope, @NotNull JetScope outerScope) {
List<JetImportDirective> importDirectives = namespace.getImportDirectives();
for (JetImportDirective importDirective : importDirectives) {
@@ -223,6 +273,11 @@ public class TopDownAnalyzer {
classDescriptorResolver.resolveGenericBounds(jetClass, descriptor);
classDescriptorResolver.resolveSupertypes(jetClass, descriptor);
}
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : objects.entrySet()) {
JetClassOrObject jetClass = entry.getKey();
MutableClassDescriptor descriptor = entry.getValue();
classDescriptorResolver.resolveSupertypes(jetClass, descriptor);
}
}
private void checkGenericBoundsInClassHeaders() {
@@ -230,14 +285,14 @@ public class TopDownAnalyzer {
JetClass jetClass = entry.getKey();
for (JetDelegationSpecifier delegationSpecifier : jetClass.getDelegationSpecifiers()) {
JetType type = trace.resolveTypeReference(delegationSpecifier.getTypeReference());
JetType type = trace.getBindingContext().resolveTypeReference(delegationSpecifier.getTypeReference());
classDescriptorResolver.checkBounds(delegationSpecifier.getTypeReference(), type);
}
for (JetTypeParameter jetTypeParameter : jetClass.getTypeParameters()) {
JetTypeReference extendsBound = jetTypeParameter.getExtendsBound();
if (extendsBound != null) {
JetType type = trace.resolveTypeReference(extendsBound);
JetType type = trace.getBindingContext().resolveTypeReference(extendsBound);
classDescriptorResolver.checkBounds(extendsBound, type);
}
}
@@ -247,17 +302,17 @@ public class TopDownAnalyzer {
}
private void resolveFunctionAndPropertyHeaders(@NotNull List<JetDeclaration> declarations) {
private void resolveFunctionAndPropertyHeaders() {
for (Map.Entry<JetNamespace, WritableScope> entry : namespaceScopes.entrySet()) {
JetNamespace namespace = entry.getKey();
final WritableScope namespaceScope = entry.getValue();
final NamespaceLike namespaceDescriptor = namespaceDescriptors.get(namespace);
WritableScope namespaceScope = entry.getValue();
NamespaceLike namespaceDescriptor = namespaceDescriptors.get(namespace);
resolveFunctionAndPropertyHeaders(namespace.getDeclarations(), namespaceScope, namespaceDescriptor);
}
for (Map.Entry<JetClass, MutableClassDescriptor> entry : classes.entrySet()) {
JetClass jetClass = entry.getKey();
final MutableClassDescriptor classDescriptor = entry.getValue();
MutableClassDescriptor classDescriptor = entry.getValue();
resolveFunctionAndPropertyHeaders(jetClass.getDeclarations(), classDescriptor.getScopeForMemberResolution(), classDescriptor);
processPrimaryConstructor(classDescriptor, jetClass);
@@ -267,6 +322,12 @@ public class TopDownAnalyzer {
// TODO : Constructors
}
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : objects.entrySet()) {
JetObjectDeclaration object = entry.getKey();
MutableClassDescriptor classDescriptor = entry.getValue();
resolveFunctionAndPropertyHeaders(object.getDeclarations(), classDescriptor.getScopeForMemberResolution(), classDescriptor);
}
// TODO : Extensions
}
@@ -289,6 +350,12 @@ public class TopDownAnalyzer {
properties.put(property, propertyDescriptor);
declaringScopes.put(property, scope);
}
@Override
public void visitObjectDeclaration(JetObjectDeclaration declaration) {
PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolveObjectDeclarationAsPropertyDescriptor(namespaceLike, declaration, objects.get(declaration));
namespaceLike.addPropertyDescriptor(propertyDescriptor);
}
});
}
}
@@ -374,7 +441,7 @@ public class TopDownAnalyzer {
JetClass jetClass = entry.getKey();
if (!jetClass.hasPrimaryConstructor()) {
for (PropertyDescriptor propertyDescriptor : classDescriptor.getProperties()) {
if (trace.hasBackingField(propertyDescriptor)) {
if (trace.getBindingContext().hasBackingField(propertyDescriptor)) {
PsiElement nameIdentifier = jetClass.getNameIdentifier();
if (nameIdentifier != null) {
trace.getErrorHandler().genericError(nameIdentifier.getNode(),
@@ -406,7 +473,7 @@ public class TopDownAnalyzer {
if (delegateExpression != null) {
JetScope scope = scopeForConstructor == null ? descriptor.getScopeForMemberResolution() : scopeForConstructor;
JetType type = typeInferrer.getType(scope, delegateExpression, false);
JetType supertype = trace.resolveTypeReference(specifier.getTypeReference());
JetType supertype = trace.getBindingContext().resolveTypeReference(specifier.getTypeReference());
if (type != null && !semanticServices.getTypeChecker().isSubtypeOf(type, supertype)) { // TODO : Convertible?
trace.getErrorHandler().typeMismatch(delegateExpression, supertype, type);
}
@@ -431,7 +498,7 @@ public class TopDownAnalyzer {
@Override
public void visitDelegationToSuperClassSpecifier(JetDelegatorToSuperClass specifier) {
JetType supertype = trace.resolveTypeReference(specifier.getTypeReference());
JetType supertype = trace.getBindingContext().resolveTypeReference(specifier.getTypeReference());
if (supertype != null) {
DeclarationDescriptor declarationDescriptor = supertype.getConstructor().getDeclarationDescriptor();
if (declarationDescriptor instanceof ClassDescriptor) {
@@ -463,23 +530,27 @@ public class TopDownAnalyzer {
private void resolveAnonymousInitializers() {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : classes.entrySet()) {
JetClass jetClass = entry.getKey();
MutableClassDescriptor classDescriptor = entry.getValue();
resolveAnonymousInitializers(entry.getKey(), entry.getValue());
}
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : objects.entrySet()) {
resolveAnonymousInitializers(entry.getKey(), entry.getValue());
}
}
List<JetClassInitializer> anonymousInitializers = jetClass.getAnonymousInitializers();
if (jetClass.hasPrimaryConstructor()) {
ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
assert primaryConstructor != null;
final JetScope scopeForConstructor = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution(), true);
JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(traceForConstructors, JetFlowInformationProvider.NONE); // TODO : flow
for (JetClassInitializer anonymousInitializer : anonymousInitializers) {
typeInferrer.getType(scopeForConstructor, anonymousInitializer.getBody(), true);
}
private void resolveAnonymousInitializers(JetClassOrObject jetClassOrObject, MutableClassDescriptor classDescriptor) {
List<JetClassInitializer> anonymousInitializers = jetClassOrObject.getAnonymousInitializers();
if (jetClassOrObject.hasPrimaryConstructor()) {
ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
assert primaryConstructor != null;
final JetScope scopeForConstructor = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution(), true);
JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(traceForConstructors, JetFlowInformationProvider.NONE); // TODO : flow
for (JetClassInitializer anonymousInitializer : anonymousInitializers) {
typeInferrer.getType(scopeForConstructor, anonymousInitializer.getBody(), true);
}
else {
for (JetClassInitializer anonymousInitializer : anonymousInitializers) {
trace.getErrorHandler().genericError(anonymousInitializer.getNode(), "Anonymous initializers are only allowed in the presence of a primary constructor");
}
}
else {
for (JetClassInitializer anonymousInitializer : anonymousInitializers) {
trace.getErrorHandler().genericError(anonymousInitializer.getNode(), "Anonymous initializers are only allowed in the presence of a primary constructor");
}
}
}
@@ -574,7 +645,7 @@ public class TopDownAnalyzer {
constructorScope.setThisType(descriptor.getContainingDeclaration().getDefaultType());
for (ValueParameterDescriptor valueParameterDescriptor : descriptor.getUnsubstitutedValueParameters()) {
JetParameter parameter = (JetParameter) trace.getDeclarationPsiElement(valueParameterDescriptor);
JetParameter parameter = (JetParameter) trace.getBindingContext().getDeclarationPsiElement(valueParameterDescriptor);
if (parameter.getValOrVarNode() == null || !primary) {
constructorScope.addVariableDescriptor(valueParameterDescriptor);
}
@@ -664,7 +735,7 @@ public class TopDownAnalyzer {
}
JetExpression initializer = property.getInitializer();
if (!property.isVar() && initializer != null && !trace.hasBackingField(propertyDescriptor)) {
if (!property.isVar() && initializer != null && !trace.getBindingContext().hasBackingField(propertyDescriptor)) {
trace.getErrorHandler().genericError(initializer.getNode(), "Initializer is not allowed here because this property has no setter and no backing field either");
}
}
@@ -731,6 +731,16 @@ public class JetTypeInferrer {
return namespace.getNamespaceType();
}
@Override
public void visitObjectLiteralExpression(JetObjectLiteralExpression expression) {
TopDownAnalyzer topDownAnalyzer = new TopDownAnalyzer(semanticServices, trace);
topDownAnalyzer.processObject(scope, scope.getContainingDeclaration(), expression.getObjectDeclaration());
ClassDescriptor classDescriptor = trace.getBindingContext().getClassDescriptor(expression.getObjectDeclaration());
if (classDescriptor != null) {
result = classDescriptor.getDefaultType();
}
}
@Override
public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) {
if (preferBlock && !expression.hasParameterSpecification()) {
@@ -47,7 +47,7 @@ public class DescriptorRenderer {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private final DeclarationDescriptorVisitor<Void, StringBuilder> rootVisitor = new RenderDeclarationDescriptorVisitor();
private final RenderDeclarationDescriptorVisitor rootVisitor = new RenderDeclarationDescriptorVisitor();
private final DeclarationDescriptorVisitor<Void, StringBuilder> subVisitor = new RenderDeclarationDescriptorVisitor() {
@Override
@@ -80,12 +80,23 @@ public class DescriptorRenderer {
if (declarationDescriptor == null) return lt() + "null>";
StringBuilder stringBuilder = new StringBuilder();
declarationDescriptor.accept(rootVisitor, stringBuilder);
stringBuilder.append(" " + renderMessage("defined in") + " ");
appendDefinedIn(declarationDescriptor, stringBuilder);
return stringBuilder.toString();
}
private void appendDefinedIn(DeclarationDescriptor declarationDescriptor, StringBuilder stringBuilder) {
stringBuilder.append(" ").append(renderMessage("defined in")).append(" ");
final DeclarationDescriptor containingDeclaration = declarationDescriptor.getContainingDeclaration();
if (containingDeclaration != null) {
renderFullyQualifiedName(containingDeclaration, stringBuilder);
}
}
public String renderAsObject(@NotNull ClassDescriptor classDescriptor) {
StringBuilder stringBuilder = new StringBuilder();
rootVisitor.renderClassDescriptor(classDescriptor, stringBuilder, "object");
appendDefinedIn(classDescriptor, stringBuilder);
return stringBuilder.toString();
}
@@ -219,7 +230,13 @@ public class DescriptorRenderer {
@Override
public Void visitClassDescriptor(ClassDescriptor descriptor, StringBuilder builder) {
builder.append(renderKeyword("class")).append(" ");
String keyword = "class";
renderClassDescriptor(descriptor, builder, keyword);
return super.visitClassDescriptor(descriptor, builder);
}
public void renderClassDescriptor(ClassDescriptor descriptor, StringBuilder builder, String keyword) {
builder.append(renderKeyword(keyword)).append(" ");
renderName(descriptor, builder);
renderTypeParameters(descriptor.getTypeConstructor().getParameters(), builder);
Collection<? extends JetType> supertypes = descriptor.getTypeConstructor().getSupertypes();
@@ -233,7 +250,6 @@ public class DescriptorRenderer {
}
}
}
return super.visitClassDescriptor(descriptor, builder);
}
protected void renderName(DeclarationDescriptor descriptor, StringBuilder stringBuilder) {
@@ -94,7 +94,7 @@ public class JetTestUtils {
}
@Override
public ClassDescriptor getClassDescriptor(JetClass declaration) {
public ClassDescriptor getClassDescriptor(JetClassOrObject declaration) {
throw new UnsupportedOperationException(); // TODO
}