JET-76 Support object declarations
JET-62 Support object-expressions No tests yet
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user