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 EXTENSION = new JetNodeType("EXTENSION", JetExtension.class);
|
||||||
JetNodeType TYPEDEF = new JetNodeType("TYPEDEF", JetTypedef.class);
|
JetNodeType TYPEDEF = new JetNodeType("TYPEDEF", JetTypedef.class);
|
||||||
JetNodeType OBJECT_DECLARATION = new JetNodeType("OBJECT_DECLARATION", JetObjectDeclaration.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 CLASS_OBJECT = new JetNodeType("CLASS_OBJECT", JetClassObject.class);
|
||||||
JetNodeType CONSTRUCTOR = new JetNodeType("CONSTRUCTOR", JetConstructor.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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -607,7 +607,9 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
advance(); // OBJECT_KEYWORD
|
advance(); // OBJECT_KEYWORD
|
||||||
|
|
||||||
if (declaration) {
|
if (declaration) {
|
||||||
|
PsiBuilder.Marker propertyDeclaration = mark();
|
||||||
expect(IDENTIFIER, "Expecting object name", TokenSet.create(LBRACE));
|
expect(IDENTIFIER, "Expecting object name", TokenSet.create(LBRACE));
|
||||||
|
propertyDeclaration.done(OBJECT_DECLARATION_NAME);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (at(IDENTIFIER)) {
|
if (at(IDENTIFIER)) {
|
||||||
|
|||||||
@@ -16,4 +16,13 @@ public interface JetClassOrObject {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
List<JetDelegationSpecifier> getDelegationSpecifiers();
|
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;
|
package org.jetbrains.jet.lang.psi;
|
||||||
|
|
||||||
import com.intellij.lang.ASTNode;
|
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.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.JetNodeTypes;
|
import org.jetbrains.jet.JetNodeTypes;
|
||||||
@@ -16,6 +19,29 @@ public class JetObjectDeclaration extends JetNamedDeclaration implements JetClas
|
|||||||
super(node);
|
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
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public JetDelegationSpecifierList getDelegationSpecifierList() {
|
public JetDelegationSpecifierList getDelegationSpecifierList() {
|
||||||
@@ -29,6 +55,20 @@ public class JetObjectDeclaration extends JetNamedDeclaration implements JetClas
|
|||||||
return list != null ? list.getDelegationSpecifiers() : Collections.<JetDelegationSpecifier>emptyList();
|
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
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public List<JetDeclaration> getDeclarations() {
|
public List<JetDeclaration> getDeclarations() {
|
||||||
@@ -37,4 +77,9 @@ public class JetObjectDeclaration extends JetNamedDeclaration implements JetClas
|
|||||||
|
|
||||||
return body.getDeclarations();
|
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) {
|
public void visitDecomposerPattern(JetDecomposerPattern pattern) {
|
||||||
visitPattern(pattern);
|
visitPattern(pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void visitObjectDeclaration(JetObjectDeclaration declaration) {
|
||||||
|
visitNamedDeclaration(declaration);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
package org.jetbrains.jet.lang.resolve;
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.jet.codegen.ClassCodegen;
|
|
||||||
import org.jetbrains.jet.lang.JetDiagnostic;
|
import org.jetbrains.jet.lang.JetDiagnostic;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
@@ -17,7 +16,7 @@ public interface BindingContext {
|
|||||||
DeclarationDescriptor getDeclarationDescriptor(PsiElement declaration);
|
DeclarationDescriptor getDeclarationDescriptor(PsiElement declaration);
|
||||||
|
|
||||||
NamespaceDescriptor getNamespaceDescriptor(JetNamespace declaration);
|
NamespaceDescriptor getNamespaceDescriptor(JetNamespace declaration);
|
||||||
ClassDescriptor getClassDescriptor(JetClass declaration);
|
ClassDescriptor getClassDescriptor(JetClassOrObject declaration);
|
||||||
TypeParameterDescriptor getTypeParameterDescriptor(JetTypeParameter declaration);
|
TypeParameterDescriptor getTypeParameterDescriptor(JetTypeParameter declaration);
|
||||||
FunctionDescriptor getFunctionDescriptor(JetFunction declaration);
|
FunctionDescriptor getFunctionDescriptor(JetFunction declaration);
|
||||||
ConstructorDescriptor getConstructorDescriptor(JetElement declaration);
|
ConstructorDescriptor getConstructorDescriptor(JetElement declaration);
|
||||||
|
|||||||
@@ -165,8 +165,8 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassDescriptor getClassDescriptor(JetClass declaration) {
|
public ClassDescriptor getClassDescriptor(JetClassOrObject declaration) {
|
||||||
return (ClassDescriptor) declarationsToDescriptors.get(declaration);
|
return (ClassDescriptor) declarationsToDescriptors.get((JetDeclaration) declaration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ public class ClassDescriptorResolver {
|
|||||||
// TODO : Bounds from with
|
// 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();
|
List<JetDelegationSpecifier> delegationSpecifiers = jetClass.getDelegationSpecifiers();
|
||||||
// TODO : assuming that the hierarchy is acyclic
|
// TODO : assuming that the hierarchy is acyclic
|
||||||
Collection<? extends JetType> superclasses = delegationSpecifiers.isEmpty()
|
Collection<? extends JetType> superclasses = delegationSpecifiers.isEmpty()
|
||||||
@@ -355,6 +355,30 @@ public class ClassDescriptorResolver {
|
|||||||
return variableDescriptor;
|
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
|
@NotNull
|
||||||
public PropertyDescriptor resolvePropertyDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope scope, JetProperty property) {
|
public PropertyDescriptor resolvePropertyDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope scope, JetProperty property) {
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import java.util.*;
|
|||||||
public class TopDownAnalyzer {
|
public class TopDownAnalyzer {
|
||||||
|
|
||||||
private final Map<JetClass, MutableClassDescriptor> classes = Maps.newLinkedHashMap();
|
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, WritableScope> namespaceScopes = Maps.newHashMap();
|
||||||
private final Map<JetNamespace, NamespaceDescriptorImpl> namespaceDescriptors = Maps.newHashMap();
|
private final Map<JetNamespace, NamespaceDescriptorImpl> namespaceDescriptors = Maps.newHashMap();
|
||||||
|
|
||||||
@@ -36,11 +37,11 @@ public class TopDownAnalyzer {
|
|||||||
|
|
||||||
private final JetSemanticServices semanticServices;
|
private final JetSemanticServices semanticServices;
|
||||||
private final ClassDescriptorResolver classDescriptorResolver;
|
private final ClassDescriptorResolver classDescriptorResolver;
|
||||||
private final BindingTraceContext trace;
|
private final BindingTrace trace;
|
||||||
private final BindingTraceAdapter traceForConstructors;
|
private final BindingTraceAdapter traceForConstructors;
|
||||||
private final BindingTraceAdapter traceForMembers;
|
private final BindingTraceAdapter traceForMembers;
|
||||||
|
|
||||||
public TopDownAnalyzer(JetSemanticServices semanticServices, @NotNull BindingTraceContext bindingTrace) {
|
public TopDownAnalyzer(JetSemanticServices semanticServices, @NotNull BindingTrace bindingTrace) {
|
||||||
this.semanticServices = semanticServices;
|
this.semanticServices = semanticServices;
|
||||||
this.classDescriptorResolver = semanticServices.getClassDescriptorResolver(bindingTrace);
|
this.classDescriptorResolver = semanticServices.getClassDescriptorResolver(bindingTrace);
|
||||||
this.trace = bindingTrace;
|
this.trace = bindingTrace;
|
||||||
@@ -53,7 +54,7 @@ public class TopDownAnalyzer {
|
|||||||
if (expression instanceof JetSimpleNameExpression) {
|
if (expression instanceof JetSimpleNameExpression) {
|
||||||
JetSimpleNameExpression simpleNameExpression = (JetSimpleNameExpression) expression;
|
JetSimpleNameExpression simpleNameExpression = (JetSimpleNameExpression) expression;
|
||||||
if (simpleNameExpression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER) {
|
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");
|
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());
|
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
|
collectNamespacesAndClassifiers(outerScope, owner, declarations); // namespaceScopes, classes
|
||||||
|
|
||||||
createTypeConstructors(); // create type constructors for classes and generic parameters
|
createTypeConstructors(); // create type constructors for classes and generic parameters
|
||||||
resolveTypesInClassHeaders(); // Generic bounds and types in supertype lists (no expressions or constructor resolution)
|
resolveTypesInClassHeaders(); // Generic bounds and types in supertype lists (no expressions or constructor resolution)
|
||||||
checkGenericBoundsInClassHeaders(); // For the types resolved so far
|
checkGenericBoundsInClassHeaders(); // For the types resolved so far
|
||||||
|
|
||||||
resolveFunctionAndPropertyHeaders(declarations); // Constructor headers are resolved as well
|
resolveFunctionAndPropertyHeaders(); // Constructor headers are resolved as well
|
||||||
|
|
||||||
resolveBehaviorDeclarationBodies();
|
resolveBehaviorDeclarationBodies();
|
||||||
}
|
}
|
||||||
@@ -131,16 +164,32 @@ public class TopDownAnalyzer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitClass(JetClass klass) {
|
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 mutableClassDescriptor = new MutableClassDescriptor(trace, owner, outerScope);
|
||||||
mutableClassDescriptor.setName(JetPsiUtil.safeName(klass.getName()));
|
mutableClassDescriptor.setName(JetPsiUtil.safeName(declaration.getName()));
|
||||||
|
|
||||||
owner.addClassifierDescriptor(mutableClassDescriptor);
|
owner.addClassifierDescriptor(mutableClassDescriptor);
|
||||||
|
|
||||||
classes.put(klass, mutableClassDescriptor);
|
map.put(declaration, mutableClassDescriptor);
|
||||||
declaringScopes.put(klass, outerScope);
|
declaringScopes.put((JetDeclaration) declaration, outerScope);
|
||||||
|
|
||||||
JetScope classScope = mutableClassDescriptor.getScopeForMemberResolution();
|
JetScope classScope = mutableClassDescriptor.getScopeForMemberResolution();
|
||||||
collectNamespacesAndClassifiers(classScope, mutableClassDescriptor, klass.getDeclarations());
|
collectNamespacesAndClassifiers(classScope, mutableClassDescriptor, declaration.getDeclarations());
|
||||||
|
|
||||||
|
return mutableClassDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -156,6 +205,7 @@ public class TopDownAnalyzer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void processImports(@NotNull JetNamespace namespace, @NotNull WriteThroughScope namespaceScope, @NotNull JetScope outerScope) {
|
private void processImports(@NotNull JetNamespace namespace, @NotNull WriteThroughScope namespaceScope, @NotNull JetScope outerScope) {
|
||||||
List<JetImportDirective> importDirectives = namespace.getImportDirectives();
|
List<JetImportDirective> importDirectives = namespace.getImportDirectives();
|
||||||
for (JetImportDirective importDirective : importDirectives) {
|
for (JetImportDirective importDirective : importDirectives) {
|
||||||
@@ -223,6 +273,11 @@ public class TopDownAnalyzer {
|
|||||||
classDescriptorResolver.resolveGenericBounds(jetClass, descriptor);
|
classDescriptorResolver.resolveGenericBounds(jetClass, descriptor);
|
||||||
classDescriptorResolver.resolveSupertypes(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() {
|
private void checkGenericBoundsInClassHeaders() {
|
||||||
@@ -230,14 +285,14 @@ public class TopDownAnalyzer {
|
|||||||
JetClass jetClass = entry.getKey();
|
JetClass jetClass = entry.getKey();
|
||||||
|
|
||||||
for (JetDelegationSpecifier delegationSpecifier : jetClass.getDelegationSpecifiers()) {
|
for (JetDelegationSpecifier delegationSpecifier : jetClass.getDelegationSpecifiers()) {
|
||||||
JetType type = trace.resolveTypeReference(delegationSpecifier.getTypeReference());
|
JetType type = trace.getBindingContext().resolveTypeReference(delegationSpecifier.getTypeReference());
|
||||||
classDescriptorResolver.checkBounds(delegationSpecifier.getTypeReference(), type);
|
classDescriptorResolver.checkBounds(delegationSpecifier.getTypeReference(), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (JetTypeParameter jetTypeParameter : jetClass.getTypeParameters()) {
|
for (JetTypeParameter jetTypeParameter : jetClass.getTypeParameters()) {
|
||||||
JetTypeReference extendsBound = jetTypeParameter.getExtendsBound();
|
JetTypeReference extendsBound = jetTypeParameter.getExtendsBound();
|
||||||
if (extendsBound != null) {
|
if (extendsBound != null) {
|
||||||
JetType type = trace.resolveTypeReference(extendsBound);
|
JetType type = trace.getBindingContext().resolveTypeReference(extendsBound);
|
||||||
classDescriptorResolver.checkBounds(extendsBound, type);
|
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()) {
|
for (Map.Entry<JetNamespace, WritableScope> entry : namespaceScopes.entrySet()) {
|
||||||
JetNamespace namespace = entry.getKey();
|
JetNamespace namespace = entry.getKey();
|
||||||
final WritableScope namespaceScope = entry.getValue();
|
WritableScope namespaceScope = entry.getValue();
|
||||||
final NamespaceLike namespaceDescriptor = namespaceDescriptors.get(namespace);
|
NamespaceLike namespaceDescriptor = namespaceDescriptors.get(namespace);
|
||||||
|
|
||||||
resolveFunctionAndPropertyHeaders(namespace.getDeclarations(), namespaceScope, namespaceDescriptor);
|
resolveFunctionAndPropertyHeaders(namespace.getDeclarations(), namespaceScope, namespaceDescriptor);
|
||||||
}
|
}
|
||||||
for (Map.Entry<JetClass, MutableClassDescriptor> entry : classes.entrySet()) {
|
for (Map.Entry<JetClass, MutableClassDescriptor> entry : classes.entrySet()) {
|
||||||
JetClass jetClass = entry.getKey();
|
JetClass jetClass = entry.getKey();
|
||||||
final MutableClassDescriptor classDescriptor = entry.getValue();
|
MutableClassDescriptor classDescriptor = entry.getValue();
|
||||||
|
|
||||||
resolveFunctionAndPropertyHeaders(jetClass.getDeclarations(), classDescriptor.getScopeForMemberResolution(), classDescriptor);
|
resolveFunctionAndPropertyHeaders(jetClass.getDeclarations(), classDescriptor.getScopeForMemberResolution(), classDescriptor);
|
||||||
processPrimaryConstructor(classDescriptor, jetClass);
|
processPrimaryConstructor(classDescriptor, jetClass);
|
||||||
@@ -267,6 +322,12 @@ public class TopDownAnalyzer {
|
|||||||
|
|
||||||
// TODO : Constructors
|
// 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
|
// TODO : Extensions
|
||||||
}
|
}
|
||||||
@@ -289,6 +350,12 @@ public class TopDownAnalyzer {
|
|||||||
properties.put(property, propertyDescriptor);
|
properties.put(property, propertyDescriptor);
|
||||||
declaringScopes.put(property, scope);
|
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();
|
JetClass jetClass = entry.getKey();
|
||||||
if (!jetClass.hasPrimaryConstructor()) {
|
if (!jetClass.hasPrimaryConstructor()) {
|
||||||
for (PropertyDescriptor propertyDescriptor : classDescriptor.getProperties()) {
|
for (PropertyDescriptor propertyDescriptor : classDescriptor.getProperties()) {
|
||||||
if (trace.hasBackingField(propertyDescriptor)) {
|
if (trace.getBindingContext().hasBackingField(propertyDescriptor)) {
|
||||||
PsiElement nameIdentifier = jetClass.getNameIdentifier();
|
PsiElement nameIdentifier = jetClass.getNameIdentifier();
|
||||||
if (nameIdentifier != null) {
|
if (nameIdentifier != null) {
|
||||||
trace.getErrorHandler().genericError(nameIdentifier.getNode(),
|
trace.getErrorHandler().genericError(nameIdentifier.getNode(),
|
||||||
@@ -406,7 +473,7 @@ public class TopDownAnalyzer {
|
|||||||
if (delegateExpression != null) {
|
if (delegateExpression != null) {
|
||||||
JetScope scope = scopeForConstructor == null ? descriptor.getScopeForMemberResolution() : scopeForConstructor;
|
JetScope scope = scopeForConstructor == null ? descriptor.getScopeForMemberResolution() : scopeForConstructor;
|
||||||
JetType type = typeInferrer.getType(scope, delegateExpression, false);
|
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?
|
if (type != null && !semanticServices.getTypeChecker().isSubtypeOf(type, supertype)) { // TODO : Convertible?
|
||||||
trace.getErrorHandler().typeMismatch(delegateExpression, supertype, type);
|
trace.getErrorHandler().typeMismatch(delegateExpression, supertype, type);
|
||||||
}
|
}
|
||||||
@@ -431,7 +498,7 @@ public class TopDownAnalyzer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitDelegationToSuperClassSpecifier(JetDelegatorToSuperClass specifier) {
|
public void visitDelegationToSuperClassSpecifier(JetDelegatorToSuperClass specifier) {
|
||||||
JetType supertype = trace.resolveTypeReference(specifier.getTypeReference());
|
JetType supertype = trace.getBindingContext().resolveTypeReference(specifier.getTypeReference());
|
||||||
if (supertype != null) {
|
if (supertype != null) {
|
||||||
DeclarationDescriptor declarationDescriptor = supertype.getConstructor().getDeclarationDescriptor();
|
DeclarationDescriptor declarationDescriptor = supertype.getConstructor().getDeclarationDescriptor();
|
||||||
if (declarationDescriptor instanceof ClassDescriptor) {
|
if (declarationDescriptor instanceof ClassDescriptor) {
|
||||||
@@ -463,23 +530,27 @@ public class TopDownAnalyzer {
|
|||||||
|
|
||||||
private void resolveAnonymousInitializers() {
|
private void resolveAnonymousInitializers() {
|
||||||
for (Map.Entry<JetClass, MutableClassDescriptor> entry : classes.entrySet()) {
|
for (Map.Entry<JetClass, MutableClassDescriptor> entry : classes.entrySet()) {
|
||||||
JetClass jetClass = entry.getKey();
|
resolveAnonymousInitializers(entry.getKey(), entry.getValue());
|
||||||
MutableClassDescriptor classDescriptor = entry.getValue();
|
}
|
||||||
|
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : objects.entrySet()) {
|
||||||
|
resolveAnonymousInitializers(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
List<JetClassInitializer> anonymousInitializers = jetClass.getAnonymousInitializers();
|
private void resolveAnonymousInitializers(JetClassOrObject jetClassOrObject, MutableClassDescriptor classDescriptor) {
|
||||||
if (jetClass.hasPrimaryConstructor()) {
|
List<JetClassInitializer> anonymousInitializers = jetClassOrObject.getAnonymousInitializers();
|
||||||
ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
|
if (jetClassOrObject.hasPrimaryConstructor()) {
|
||||||
assert primaryConstructor != null;
|
ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
|
||||||
final JetScope scopeForConstructor = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution(), true);
|
assert primaryConstructor != null;
|
||||||
JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(traceForConstructors, JetFlowInformationProvider.NONE); // TODO : flow
|
final JetScope scopeForConstructor = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution(), true);
|
||||||
for (JetClassInitializer anonymousInitializer : anonymousInitializers) {
|
JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(traceForConstructors, JetFlowInformationProvider.NONE); // TODO : flow
|
||||||
typeInferrer.getType(scopeForConstructor, anonymousInitializer.getBody(), true);
|
for (JetClassInitializer anonymousInitializer : anonymousInitializers) {
|
||||||
}
|
typeInferrer.getType(scopeForConstructor, anonymousInitializer.getBody(), true);
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
for (JetClassInitializer anonymousInitializer : anonymousInitializers) {
|
else {
|
||||||
trace.getErrorHandler().genericError(anonymousInitializer.getNode(), "Anonymous initializers are only allowed in the presence of a primary constructor");
|
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());
|
constructorScope.setThisType(descriptor.getContainingDeclaration().getDefaultType());
|
||||||
|
|
||||||
for (ValueParameterDescriptor valueParameterDescriptor : descriptor.getUnsubstitutedValueParameters()) {
|
for (ValueParameterDescriptor valueParameterDescriptor : descriptor.getUnsubstitutedValueParameters()) {
|
||||||
JetParameter parameter = (JetParameter) trace.getDeclarationPsiElement(valueParameterDescriptor);
|
JetParameter parameter = (JetParameter) trace.getBindingContext().getDeclarationPsiElement(valueParameterDescriptor);
|
||||||
if (parameter.getValOrVarNode() == null || !primary) {
|
if (parameter.getValOrVarNode() == null || !primary) {
|
||||||
constructorScope.addVariableDescriptor(valueParameterDescriptor);
|
constructorScope.addVariableDescriptor(valueParameterDescriptor);
|
||||||
}
|
}
|
||||||
@@ -664,7 +735,7 @@ public class TopDownAnalyzer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JetExpression initializer = property.getInitializer();
|
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");
|
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();
|
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
|
@Override
|
||||||
public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) {
|
public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) {
|
||||||
if (preferBlock && !expression.hasParameterSpecification()) {
|
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() {
|
private final DeclarationDescriptorVisitor<Void, StringBuilder> subVisitor = new RenderDeclarationDescriptorVisitor() {
|
||||||
@Override
|
@Override
|
||||||
@@ -80,12 +80,23 @@ public class DescriptorRenderer {
|
|||||||
if (declarationDescriptor == null) return lt() + "null>";
|
if (declarationDescriptor == null) return lt() + "null>";
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
declarationDescriptor.accept(rootVisitor, 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();
|
final DeclarationDescriptor containingDeclaration = declarationDescriptor.getContainingDeclaration();
|
||||||
if (containingDeclaration != null) {
|
if (containingDeclaration != null) {
|
||||||
renderFullyQualifiedName(containingDeclaration, stringBuilder);
|
renderFullyQualifiedName(containingDeclaration, stringBuilder);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String renderAsObject(@NotNull ClassDescriptor classDescriptor) {
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
rootVisitor.renderClassDescriptor(classDescriptor, stringBuilder, "object");
|
||||||
|
appendDefinedIn(classDescriptor, stringBuilder);
|
||||||
return stringBuilder.toString();
|
return stringBuilder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,7 +230,13 @@ public class DescriptorRenderer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visitClassDescriptor(ClassDescriptor descriptor, StringBuilder builder) {
|
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);
|
renderName(descriptor, builder);
|
||||||
renderTypeParameters(descriptor.getTypeConstructor().getParameters(), builder);
|
renderTypeParameters(descriptor.getTypeConstructor().getParameters(), builder);
|
||||||
Collection<? extends JetType> supertypes = descriptor.getTypeConstructor().getSupertypes();
|
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) {
|
protected void renderName(DeclarationDescriptor descriptor, StringBuilder stringBuilder) {
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ public class JetTestUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassDescriptor getClassDescriptor(JetClass declaration) {
|
public ClassDescriptor getClassDescriptor(JetClassOrObject declaration) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user