JET-6 Perform checks for primary and secondary constructors (In progress)
This commit is contained in:
@@ -35,6 +35,7 @@ public interface JetNodeTypes {
|
|||||||
JetNodeType IMPORT_DIRECTIVE = new JetNodeType("IMPORT_DIRECTIVE", JetImportDirective.class);
|
JetNodeType IMPORT_DIRECTIVE = new JetNodeType("IMPORT_DIRECTIVE", JetImportDirective.class);
|
||||||
JetNodeType NAMESPACE_BODY = new JetNodeType("NAMESPACE_BODY", JetNamespaceBody.class);
|
JetNodeType NAMESPACE_BODY = new JetNodeType("NAMESPACE_BODY", JetNamespaceBody.class);
|
||||||
JetNodeType MODIFIER_LIST = new JetNodeType("MODIFIER_LIST", JetModifierList.class);
|
JetNodeType MODIFIER_LIST = new JetNodeType("MODIFIER_LIST", JetModifierList.class);
|
||||||
|
JetNodeType PRIMARY_CONSTRUCTOR_MODIFIER_LIST = new JetNodeType("PRIMARY_CONSTRUCTOR_MODIFIER_LIST", JetModifierList.class);
|
||||||
JetNodeType ATTRIBUTE_ANNOTATION = new JetNodeType("ATTRIBUTE_ANNOTATION", JetAttributeAnnotation.class);
|
JetNodeType ATTRIBUTE_ANNOTATION = new JetNodeType("ATTRIBUTE_ANNOTATION", JetAttributeAnnotation.class);
|
||||||
JetNodeType ATTRIBUTE = new JetNodeType("ATTRIBUTE", JetAttribute.class);
|
JetNodeType ATTRIBUTE = new JetNodeType("ATTRIBUTE", JetAttribute.class);
|
||||||
JetNodeType TYPE_ARGUMENT_LIST = new JetNodeType("TYPE_ARGUMENT_LIST", JetTypeArgumentList.class);
|
JetNodeType TYPE_ARGUMENT_LIST = new JetNodeType("TYPE_ARGUMENT_LIST", JetTypeArgumentList.class);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.jetbrains.jet.lang;
|
package org.jetbrains.jet.lang;
|
||||||
|
|
||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
|
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
|
||||||
import org.jetbrains.jet.lang.types.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.types.DeclarationDescriptor;
|
||||||
@@ -18,7 +19,7 @@ public class ErrorHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void genericError(ASTNode node, String errorMessage) {
|
public void genericError(@NotNull ASTNode node, String errorMessage) {
|
||||||
throw new IllegalStateException(errorMessage);
|
throw new IllegalStateException(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +43,7 @@ public class ErrorHandler {
|
|||||||
public void redeclaration(DeclarationDescriptor existingDescriptor, DeclarationDescriptor redeclaredDescriptor) {
|
public void redeclaration(DeclarationDescriptor existingDescriptor, DeclarationDescriptor redeclaredDescriptor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void genericError(ASTNode node, String errorMessage) {
|
public void genericError(@NotNull ASTNode node, String errorMessage) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void genericWarning(ASTNode node, String message) {
|
public void genericWarning(ASTNode node, String message) {
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public class JetPsiChecker implements Annotator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void genericError(ASTNode node, String errorMessage) {
|
public void genericError(@NotNull ASTNode node, String errorMessage) {
|
||||||
holder.createErrorAnnotation(node, errorMessage);
|
holder.createErrorAnnotation(node, errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -929,7 +929,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
private boolean parseLocalDeclaration() {
|
private boolean parseLocalDeclaration() {
|
||||||
PsiBuilder.Marker decls = mark();
|
PsiBuilder.Marker decls = mark();
|
||||||
JetParsing.TokenDetector enumDetector = new JetParsing.TokenDetector(ENUM_KEYWORD);
|
JetParsing.TokenDetector enumDetector = new JetParsing.TokenDetector(ENUM_KEYWORD);
|
||||||
myJetParsing.parseModifierList(enumDetector);
|
myJetParsing.parseModifierList(MODIFIER_LIST, enumDetector);
|
||||||
|
|
||||||
JetNodeType declType = parseLocalDeclarationRest(enumDetector.isDetected());
|
JetNodeType declType = parseLocalDeclarationRest(enumDetector.isDetected());
|
||||||
|
|
||||||
@@ -1002,7 +1002,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
PsiBuilder.Marker parameter = mark();
|
PsiBuilder.Marker parameter = mark();
|
||||||
int parameterNamePos = matchTokenStreamPredicate(new LastBefore(new At(IDENTIFIER), new AtOffset(doubleArrowPos)));
|
int parameterNamePos = matchTokenStreamPredicate(new LastBefore(new At(IDENTIFIER), new AtOffset(doubleArrowPos)));
|
||||||
|
|
||||||
createTruncatedBuilder(parameterNamePos).parseModifierList();
|
createTruncatedBuilder(parameterNamePos).parseModifierList(MODIFIER_LIST);
|
||||||
|
|
||||||
expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(DOUBLE_ARROW));
|
expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(DOUBLE_ARROW));
|
||||||
|
|
||||||
@@ -1046,7 +1046,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
|
|
||||||
PsiBuilder.Marker parameter = mark();
|
PsiBuilder.Marker parameter = mark();
|
||||||
int parameterNamePos = matchTokenStreamPredicate(new LastBefore(new At(IDENTIFIER), new AtSet(COMMA, RPAR, COLON, DOUBLE_ARROW)));
|
int parameterNamePos = matchTokenStreamPredicate(new LastBefore(new At(IDENTIFIER), new AtSet(COMMA, RPAR, COLON, DOUBLE_ARROW)));
|
||||||
createTruncatedBuilder(parameterNamePos).parseModifierList();
|
createTruncatedBuilder(parameterNamePos).parseModifierList(MODIFIER_LIST);
|
||||||
|
|
||||||
expect(IDENTIFIER, "Expecting parameter declaration");
|
expect(IDENTIFIER, "Expecting parameter declaration");
|
||||||
|
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
PsiBuilder.Marker firstEntry = mark();
|
PsiBuilder.Marker firstEntry = mark();
|
||||||
parseModifierList();
|
parseModifierList(MODIFIER_LIST);
|
||||||
|
|
||||||
if (at(NAMESPACE_KEYWORD)) {
|
if (at(NAMESPACE_KEYWORD)) {
|
||||||
advance(); // NAMESPACE_KEYWORD
|
advance(); // NAMESPACE_KEYWORD
|
||||||
@@ -218,7 +218,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
PsiBuilder.Marker decl = mark();
|
PsiBuilder.Marker decl = mark();
|
||||||
|
|
||||||
TokenDetector detector = new TokenDetector(ENUM_KEYWORD);
|
TokenDetector detector = new TokenDetector(ENUM_KEYWORD);
|
||||||
parseModifierList(detector);
|
parseModifierList(MODIFIER_LIST, detector);
|
||||||
|
|
||||||
IElementType keywordToken = tt();
|
IElementType keywordToken = tt();
|
||||||
JetNodeType declType = null;
|
JetNodeType declType = null;
|
||||||
@@ -253,8 +253,8 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
/*
|
/*
|
||||||
* (modifier | attribute)*
|
* (modifier | attribute)*
|
||||||
*/
|
*/
|
||||||
public void parseModifierList() {
|
public void parseModifierList(JetNodeType nodeType) {
|
||||||
parseModifierList(null);
|
parseModifierList(nodeType, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -262,7 +262,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
*
|
*
|
||||||
* Feeds modifiers (not attributes) into the passed consumer, if it is not null
|
* Feeds modifiers (not attributes) into the passed consumer, if it is not null
|
||||||
*/
|
*/
|
||||||
public void parseModifierList(Consumer<IElementType> tokenConsumer) {
|
public void parseModifierList(JetNodeType nodeType, Consumer<IElementType> tokenConsumer) {
|
||||||
PsiBuilder.Marker list = mark();
|
PsiBuilder.Marker list = mark();
|
||||||
boolean empty = true;
|
boolean empty = true;
|
||||||
while (!eof()) {
|
while (!eof()) {
|
||||||
@@ -280,7 +280,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
if (empty) {
|
if (empty) {
|
||||||
list.drop();
|
list.drop();
|
||||||
} else {
|
} else {
|
||||||
list.done(MODIFIER_LIST);
|
list.done(nodeType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -393,7 +393,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
advance(); // WRAPS_KEYWORD
|
advance(); // WRAPS_KEYWORD
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
parseModifierList();
|
parseModifierList(PRIMARY_CONSTRUCTOR_MODIFIER_LIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (at(LPAR)) {
|
if (at(LPAR)) {
|
||||||
@@ -436,7 +436,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
TokenSet constructorNameFollow = TokenSet.create(SEMICOLON, COLON, LPAR, LT, LBRACE);
|
TokenSet constructorNameFollow = TokenSet.create(SEMICOLON, COLON, LPAR, LT, LBRACE);
|
||||||
int lastId = findLastBefore(ENUM_MEMBER_FIRST, constructorNameFollow, false);
|
int lastId = findLastBefore(ENUM_MEMBER_FIRST, constructorNameFollow, false);
|
||||||
TokenDetector enumDetector = new TokenDetector(ENUM_KEYWORD);
|
TokenDetector enumDetector = new TokenDetector(ENUM_KEYWORD);
|
||||||
createTruncatedBuilder(lastId).parseModifierList(enumDetector);
|
createTruncatedBuilder(lastId).parseModifierList(MODIFIER_LIST, enumDetector);
|
||||||
|
|
||||||
IElementType type;
|
IElementType type;
|
||||||
if (at(IDENTIFIER)) {
|
if (at(IDENTIFIER)) {
|
||||||
@@ -535,7 +535,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
PsiBuilder.Marker decl = mark();
|
PsiBuilder.Marker decl = mark();
|
||||||
|
|
||||||
TokenDetector enumDetector = new TokenDetector(ENUM_KEYWORD);
|
TokenDetector enumDetector = new TokenDetector(ENUM_KEYWORD);
|
||||||
parseModifierList(enumDetector);
|
parseModifierList(MODIFIER_LIST, enumDetector);
|
||||||
|
|
||||||
JetNodeType declType = parseMemberDeclarationRest(enumDetector.isDetected());
|
JetNodeType declType = parseMemberDeclarationRest(enumDetector.isDetected());
|
||||||
|
|
||||||
@@ -786,7 +786,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
private boolean parsePropertyGetterOrSetter() {
|
private boolean parsePropertyGetterOrSetter() {
|
||||||
PsiBuilder.Marker getterOrSetter = mark();
|
PsiBuilder.Marker getterOrSetter = mark();
|
||||||
|
|
||||||
parseModifierList();
|
parseModifierList(MODIFIER_LIST);
|
||||||
|
|
||||||
if (!at(GET_KEYWORD) && !at(SET_KEYWORD)) {
|
if (!at(GET_KEYWORD) && !at(SET_KEYWORD)) {
|
||||||
getterOrSetter.rollbackTo();
|
getterOrSetter.rollbackTo();
|
||||||
@@ -807,7 +807,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
PsiBuilder.Marker parameterList = mark();
|
PsiBuilder.Marker parameterList = mark();
|
||||||
PsiBuilder.Marker setterParameter = mark();
|
PsiBuilder.Marker setterParameter = mark();
|
||||||
int lastId = findLastBefore(TokenSet.create(IDENTIFIER), TokenSet.create(RPAR, COMMA, COLON), false);
|
int lastId = findLastBefore(TokenSet.create(IDENTIFIER), TokenSet.create(RPAR, COMMA, COLON), false);
|
||||||
createTruncatedBuilder(lastId).parseModifierList();
|
createTruncatedBuilder(lastId).parseModifierList(MODIFIER_LIST);
|
||||||
expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(RPAR, COLON, LBRACE, EQ));
|
expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(RPAR, COLON, LBRACE, EQ));
|
||||||
|
|
||||||
if (at(COLON)) {
|
if (at(COLON)) {
|
||||||
@@ -1111,7 +1111,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
PsiBuilder.Marker mark = mark();
|
PsiBuilder.Marker mark = mark();
|
||||||
|
|
||||||
int lastId = findLastBefore(TokenSet.create(IDENTIFIER), TokenSet.create(COMMA, GT, COLON), false);
|
int lastId = findLastBefore(TokenSet.create(IDENTIFIER), TokenSet.create(COMMA, GT, COLON), false);
|
||||||
createTruncatedBuilder(lastId).parseModifierList();
|
createTruncatedBuilder(lastId).parseModifierList(MODIFIER_LIST);
|
||||||
|
|
||||||
expect(IDENTIFIER, "Type parameter name expected", TokenSet.EMPTY);
|
expect(IDENTIFIER, "Type parameter name expected", TokenSet.EMPTY);
|
||||||
|
|
||||||
@@ -1235,7 +1235,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
PsiBuilder.Marker projection = mark();
|
PsiBuilder.Marker projection = mark();
|
||||||
|
|
||||||
int lastId = findLastBefore(TokenSet.create(IDENTIFIER), TokenSet.create(COMMA, COLON, GT), false);
|
int lastId = findLastBefore(TokenSet.create(IDENTIFIER), TokenSet.create(COMMA, COLON, GT), false);
|
||||||
createTruncatedBuilder(lastId).parseModifierList();
|
createTruncatedBuilder(lastId).parseModifierList(MODIFIER_LIST);
|
||||||
|
|
||||||
if (at(MUL)) {
|
if (at(MUL)) {
|
||||||
advance(); // MUL
|
advance(); // MUL
|
||||||
@@ -1372,7 +1372,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
if (isFunctionTypeContents) {
|
if (isFunctionTypeContents) {
|
||||||
if (!tryParseValueParameter()) {
|
if (!tryParseValueParameter()) {
|
||||||
PsiBuilder.Marker valueParameter = mark();
|
PsiBuilder.Marker valueParameter = mark();
|
||||||
parseModifierList(); // lazy, out, ref
|
parseModifierList(MODIFIER_LIST); // lazy, out, ref
|
||||||
parseTypeRef();
|
parseTypeRef();
|
||||||
valueParameter.done(VALUE_PARAMETER);
|
valueParameter.done(VALUE_PARAMETER);
|
||||||
}
|
}
|
||||||
@@ -1406,7 +1406,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
PsiBuilder.Marker parameter = mark();
|
PsiBuilder.Marker parameter = mark();
|
||||||
|
|
||||||
int lastId = findLastBefore(TokenSet.create(IDENTIFIER), TokenSet.create(COMMA, RPAR, COLON), false);
|
int lastId = findLastBefore(TokenSet.create(IDENTIFIER), TokenSet.create(COMMA, RPAR, COLON), false);
|
||||||
createTruncatedBuilder(lastId).parseModifierList();
|
createTruncatedBuilder(lastId).parseModifierList(MODIFIER_LIST);
|
||||||
|
|
||||||
if (at(VAR_KEYWORD) || at(VAL_KEYWORD)) {
|
if (at(VAR_KEYWORD) || at(VAL_KEYWORD)) {
|
||||||
advance(); // VAR_KEYWORD | VAL_KEYWORD
|
advance(); // VAR_KEYWORD | VAL_KEYWORD
|
||||||
|
|||||||
@@ -61,4 +61,9 @@ public class JetClass extends JetTypeParameterListOwner implements JetClassOrObj
|
|||||||
JetDelegationSpecifierList list = getDelegationSpecifierList();
|
JetDelegationSpecifierList list = getDelegationSpecifierList();
|
||||||
return list != null ? list.getDelegationSpecifiers() : Collections.<JetDelegationSpecifier>emptyList();
|
return list != null ? list.getDelegationSpecifiers() : Collections.<JetDelegationSpecifier>emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public JetModifierList getPrimaryConstructorModifierList() {
|
||||||
|
return (JetModifierList) findChildByType(JetNodeTypes.PRIMARY_CONSTRUCTOR_MODIFIER_LIST);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,4 +59,8 @@ public class JetConstructor extends JetDeclaration implements JetDeclarationWith
|
|||||||
public JetElement asElement() {
|
public JetElement asElement() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ASTNode getNameNode() {
|
||||||
|
return getNode().findChildByType(JetTokens.THIS_KEYWORD);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,9 +56,9 @@ public class ClassDescriptorResolver {
|
|||||||
|
|
||||||
WritableFunctionGroup constructors = new WritableFunctionGroup("<init>");
|
WritableFunctionGroup constructors = new WritableFunctionGroup("<init>");
|
||||||
for (JetConstructor constructor : classElement.getSecondaryConstructors()) {
|
for (JetConstructor constructor : classElement.getSecondaryConstructors()) {
|
||||||
constructors.addFunction(resolveConstructorDescriptor(members, classDescriptor, constructor, false));
|
constructors.addFunction(resolveSecondaryConstructorDescriptor(members, classDescriptor, constructor));
|
||||||
}
|
}
|
||||||
ConstructorDescriptor primaryConstructorDescriptor = resolvePrimaryConstructor(scope, classDescriptor, classElement);
|
ConstructorDescriptor primaryConstructorDescriptor = resolvePrimaryConstructorDescriptor(scope, classDescriptor, classElement);
|
||||||
if (primaryConstructorDescriptor != null) {
|
if (primaryConstructorDescriptor != null) {
|
||||||
constructors.addFunction(primaryConstructorDescriptor);
|
constructors.addFunction(primaryConstructorDescriptor);
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,8 @@ public class ClassDescriptorResolver {
|
|||||||
typeParameters,
|
typeParameters,
|
||||||
supertypes,
|
supertypes,
|
||||||
members,
|
members,
|
||||||
constructors
|
constructors,
|
||||||
|
primaryConstructorDescriptor
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,7 +160,7 @@ public class ClassDescriptorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public FunctionDescriptor resolveFunctionDescriptor(DeclarationDescriptor containingDescriptor, JetScope scope, JetFunction function) {
|
public FunctionDescriptorImpl resolveFunctionDescriptor(DeclarationDescriptor containingDescriptor, JetScope scope, JetFunction function) {
|
||||||
FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(
|
FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(
|
||||||
containingDescriptor,
|
containingDescriptor,
|
||||||
AttributeResolver.INSTANCE.resolveAttributes(function.getModifierList()),
|
AttributeResolver.INSTANCE.resolveAttributes(function.getModifierList()),
|
||||||
@@ -307,19 +308,21 @@ public class ClassDescriptorResolver {
|
|||||||
return variableDescriptor;
|
return variableDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public VariableDescriptor resolveLocalVariableDescriptor(DeclarationDescriptor containingDeclaration, WritableScope scope, JetProperty property) {
|
public VariableDescriptor resolveLocalVariableDescriptor(DeclarationDescriptor containingDeclaration, WritableScope scope, JetProperty property) {
|
||||||
JetType type = getType(scope, property);
|
JetType type = getType(scope, property);
|
||||||
|
|
||||||
VariableDescriptorImpl propertyDescriptor = new LocalVariableDescriptor(
|
VariableDescriptorImpl variableDescriptor = new LocalVariableDescriptor(
|
||||||
containingDeclaration,
|
containingDeclaration,
|
||||||
AttributeResolver.INSTANCE.resolveAttributes(property.getModifierList()),
|
AttributeResolver.INSTANCE.resolveAttributes(property.getModifierList()),
|
||||||
JetPsiUtil.safeName(property.getName()),
|
JetPsiUtil.safeName(property.getName()),
|
||||||
type,
|
type,
|
||||||
property.isVar());
|
property.isVar());
|
||||||
trace.recordDeclarationResolution(property, propertyDescriptor);
|
trace.recordDeclarationResolution(property, variableDescriptor);
|
||||||
return propertyDescriptor;
|
return variableDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public PropertyDescriptor resolvePropertyDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope scope, JetProperty property) {
|
public PropertyDescriptor resolvePropertyDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope scope, JetProperty property) {
|
||||||
JetType type = getType(scope, property);
|
JetType type = getType(scope, property);
|
||||||
|
|
||||||
@@ -443,12 +446,18 @@ public class ClassDescriptorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public ConstructorDescriptor resolveConstructorDescriptor(@NotNull JetScope scope, ClassDescriptor classDescriptor, JetConstructor constructor, boolean isPrimary) {
|
public ConstructorDescriptor resolveSecondaryConstructorDescriptor(@NotNull JetScope scope, @NotNull ClassDescriptor classDescriptor, @NotNull JetConstructor constructor) {
|
||||||
return createConstructorDescriptor(scope, classDescriptor, isPrimary, constructor.getModifierList(), constructor, constructor.getParameters());
|
return createConstructorDescriptor(scope, classDescriptor, false, constructor.getModifierList(), constructor, constructor.getParameters());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private ConstructorDescriptor createConstructorDescriptor(JetScope scope, ClassDescriptor classDescriptor, boolean isPrimary, JetModifierList modifierList, JetDeclaration declarationToTrace, List<JetParameter> valueParameters) {
|
private ConstructorDescriptor createConstructorDescriptor(
|
||||||
|
@NotNull JetScope scope,
|
||||||
|
@NotNull ClassDescriptor classDescriptor,
|
||||||
|
boolean isPrimary,
|
||||||
|
@Nullable JetModifierList modifierList,
|
||||||
|
@NotNull JetDeclaration declarationToTrace,
|
||||||
|
@NotNull List<JetParameter> valueParameters) {
|
||||||
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(
|
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(
|
||||||
classDescriptor,
|
classDescriptor,
|
||||||
AttributeResolver.INSTANCE.resolveAttributes(modifierList),
|
AttributeResolver.INSTANCE.resolveAttributes(modifierList),
|
||||||
@@ -463,33 +472,20 @@ public class ClassDescriptorResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public ConstructorDescriptor resolvePrimaryConstructor(@NotNull JetScope scope, @NotNull ClassDescriptor classDescriptor, @NotNull JetClass classElement) {
|
public ConstructorDescriptor resolvePrimaryConstructorDescriptor(@NotNull JetScope scope, @NotNull ClassDescriptor classDescriptor, @NotNull JetClass classElement) {
|
||||||
JetParameterList primaryConstructorParameterList = classElement.getPrimaryConstructorParameterList();
|
JetParameterList primaryConstructorParameterList = classElement.getPrimaryConstructorParameterList();
|
||||||
if (primaryConstructorParameterList != null) {
|
if (primaryConstructorParameterList == null) return null;
|
||||||
return createConstructorDescriptor(
|
return createConstructorDescriptor(
|
||||||
scope,
|
scope,
|
||||||
classDescriptor,
|
classDescriptor,
|
||||||
true,
|
true,
|
||||||
classElement.getModifierList(), // TODO
|
classElement.getPrimaryConstructorModifierList(),
|
||||||
classElement,
|
classElement,
|
||||||
primaryConstructorParameterList.getParameters());
|
primaryConstructorParameterList.getParameters());
|
||||||
}
|
|
||||||
else {
|
|
||||||
List<JetConstructor> secondaryConstructors = classElement.getSecondaryConstructors();
|
|
||||||
if (secondaryConstructors.isEmpty()) {
|
|
||||||
return createConstructorDescriptor(
|
|
||||||
scope,
|
|
||||||
classDescriptor,
|
|
||||||
true,
|
|
||||||
classElement.getModifierList(), // TODO
|
|
||||||
classElement,
|
|
||||||
Collections.<JetParameter>emptyList());
|
|
||||||
}
|
|
||||||
else return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public VariableDescriptor resolvePrimaryConstructorParameterToAProperty(
|
@NotNull
|
||||||
|
public PropertyDescriptor resolvePrimaryConstructorParameterToAProperty(
|
||||||
@NotNull ClassDescriptor classDescriptor,
|
@NotNull ClassDescriptor classDescriptor,
|
||||||
@NotNull JetScope scope,
|
@NotNull JetScope scope,
|
||||||
@NotNull JetParameter parameter) {
|
@NotNull JetParameter parameter) {
|
||||||
@@ -497,6 +493,14 @@ public class ClassDescriptorResolver {
|
|||||||
String name = parameter.getName();
|
String name = parameter.getName();
|
||||||
boolean isMutable = parameter.isMutable();
|
boolean isMutable = parameter.isMutable();
|
||||||
JetModifierList modifierList = parameter.getModifierList();
|
JetModifierList modifierList = parameter.getModifierList();
|
||||||
|
|
||||||
|
if (modifierList != null) {
|
||||||
|
ASTNode abstractNode = modifierList.getModifierNode(JetTokens.ABSTRACT_KEYWORD);
|
||||||
|
if (abstractNode != null) {
|
||||||
|
semanticServices.getErrorHandler().genericError(abstractNode, "This property cannot be declared abstract");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
|
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
|
||||||
classDescriptor,
|
classDescriptor,
|
||||||
AttributeResolver.INSTANCE.resolveAttributes(modifierList),
|
AttributeResolver.INSTANCE.resolveAttributes(modifierList),
|
||||||
|
|||||||
@@ -49,6 +49,11 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor {
|
|||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
|
||||||
|
return original.getUnsubstitutedPrimaryConstructor();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Attribute> getAttributes() {
|
public List<Attribute> getAttributes() {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.jetbrains.jet.lang.resolve;
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
@@ -14,6 +15,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
|
|||||||
private final WritableScope classHeaderScope;
|
private final WritableScope classHeaderScope;
|
||||||
private final WritableScope writableMemberScope;
|
private final WritableScope writableMemberScope;
|
||||||
private final WritableFunctionGroup constructors = new WritableFunctionGroup("<init>");
|
private final WritableFunctionGroup constructors = new WritableFunctionGroup("<init>");
|
||||||
|
private ConstructorDescriptor primaryConstructor;
|
||||||
|
|
||||||
private TypeConstructor typeConstructor;
|
private TypeConstructor typeConstructor;
|
||||||
private JetScope unsubstitutedMemberScope;
|
private JetScope unsubstitutedMemberScope;
|
||||||
@@ -98,4 +100,16 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
|
|||||||
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
|
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
|
||||||
return visitor.visitClassDescriptor(this, data);
|
return visitor.visitClassDescriptor(this, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPrimaryConstructor(@NotNull ConstructorDescriptor constructorDescriptor) {
|
||||||
|
assert this.primaryConstructor == null : "Primary constructor assigned twice " + this;
|
||||||
|
this.primaryConstructor = constructorDescriptor;
|
||||||
|
addConstructor(constructorDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
|
||||||
|
return primaryConstructor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package org.jetbrains.jet.lang.resolve;
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
import com.google.common.collect.ArrayListMultimap;
|
import com.google.common.collect.ArrayListMultimap;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||||
import org.jetbrains.jet.lang.cfg.JetControlFlowProcessor;
|
import org.jetbrains.jet.lang.cfg.JetControlFlowProcessor;
|
||||||
@@ -20,7 +22,8 @@ public class TopDownAnalyzer {
|
|||||||
|
|
||||||
private final Map<JetClass, MutableClassDescriptor> classes = new LinkedHashMap<JetClass, MutableClassDescriptor>();
|
private final Map<JetClass, MutableClassDescriptor> classes = new LinkedHashMap<JetClass, MutableClassDescriptor>();
|
||||||
private final Map<JetNamespace, WritableScope> namespaceScopes = new LinkedHashMap<JetNamespace, WritableScope>();
|
private final Map<JetNamespace, WritableScope> namespaceScopes = new LinkedHashMap<JetNamespace, WritableScope>();
|
||||||
private final Map<JetDeclaration, FunctionDescriptor> functions = new LinkedHashMap<JetDeclaration, FunctionDescriptor>();
|
private final Map<JetDeclaration, FunctionDescriptorImpl> functions = Maps.newLinkedHashMap();
|
||||||
|
private final Map<JetDeclaration, ConstructorDescriptor> constructors = Maps.newLinkedHashMap();
|
||||||
private final Map<JetProperty, PropertyDescriptor> properties = new LinkedHashMap<JetProperty, PropertyDescriptor>();
|
private final Map<JetProperty, PropertyDescriptor> properties = new LinkedHashMap<JetProperty, PropertyDescriptor>();
|
||||||
private final Map<JetDeclaration, WritableScope> declaringScopes = new HashMap<JetDeclaration, WritableScope>();
|
private final Map<JetDeclaration, WritableScope> declaringScopes = new HashMap<JetDeclaration, WritableScope>();
|
||||||
private final Multimap<DeclarationDescriptor, PropertyDescriptor> declaringScopesToProperties = ArrayListMultimap.create();
|
private final Multimap<DeclarationDescriptor, PropertyDescriptor> declaringScopesToProperties = ArrayListMultimap.create();
|
||||||
@@ -37,6 +40,8 @@ public class TopDownAnalyzer {
|
|||||||
this.classDescriptorResolver = new ClassDescriptorResolver(semanticServices, bindingTrace);
|
this.classDescriptorResolver = new ClassDescriptorResolver(semanticServices, bindingTrace);
|
||||||
this.trace = bindingTrace;
|
this.trace = bindingTrace;
|
||||||
this.flowDataTraceFactory = flowDataTraceFactory;
|
this.flowDataTraceFactory = flowDataTraceFactory;
|
||||||
|
|
||||||
|
// This allows access to backing fields
|
||||||
this.traceForConstructors = new BindingTraceAdapter(trace) {
|
this.traceForConstructors = new BindingTraceAdapter(trace) {
|
||||||
@Override
|
@Override
|
||||||
public void recordReferenceResolution(@NotNull JetReferenceExpression expression, @NotNull DeclarationDescriptor descriptor) {
|
public void recordReferenceResolution(@NotNull JetReferenceExpression expression, @NotNull DeclarationDescriptor descriptor) {
|
||||||
@@ -208,7 +213,7 @@ public class TopDownAnalyzer {
|
|||||||
public void visitConstructor(JetConstructor constructor) {
|
public void visitConstructor(JetConstructor constructor) {
|
||||||
DeclarationDescriptor containingDeclaration = declaringScope.getContainingDeclaration();
|
DeclarationDescriptor containingDeclaration = declaringScope.getContainingDeclaration();
|
||||||
if (containingDeclaration instanceof ClassDescriptor) {
|
if (containingDeclaration instanceof ClassDescriptor) {
|
||||||
processConstructor((MutableClassDescriptor) containingDeclaration, constructor);
|
processSecondaryConstructor((MutableClassDescriptor) containingDeclaration, constructor);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
semanticServices.getErrorHandler().genericError(constructor.getNode(), "Constructors are only allowed inside classes");
|
semanticServices.getErrorHandler().genericError(constructor.getNode(), "Constructors are only allowed inside classes");
|
||||||
@@ -225,9 +230,11 @@ public class TopDownAnalyzer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void processPrimaryConstructor(MutableClassDescriptor classDescriptor, JetClass klass) {
|
private void processPrimaryConstructor(MutableClassDescriptor classDescriptor, JetClass klass) {
|
||||||
|
if (klass.getPrimaryConstructorParameterList() == null) return; // No constructors
|
||||||
|
|
||||||
// TODO : not all the parameters are real properties
|
// TODO : not all the parameters are real properties
|
||||||
WritableScope memberScope = classDescriptor.getWritableUnsubstitutedMemberScope(); // TODO : this is REALLY questionable
|
WritableScope memberScope = classDescriptor.getWritableUnsubstitutedMemberScope(); // TODO : this is REALLY questionable
|
||||||
ConstructorDescriptor constructorDescriptor = classDescriptorResolver.resolvePrimaryConstructor(memberScope, classDescriptor, klass);
|
ConstructorDescriptor constructorDescriptor = classDescriptorResolver.resolvePrimaryConstructorDescriptor(memberScope, classDescriptor, klass);
|
||||||
for (JetParameter parameter : klass.getPrimaryConstructorParameters()) {
|
for (JetParameter parameter : klass.getPrimaryConstructorParameters()) {
|
||||||
VariableDescriptor propertyDescriptor = classDescriptorResolver.resolvePrimaryConstructorParameterToAProperty(
|
VariableDescriptor propertyDescriptor = classDescriptorResolver.resolvePrimaryConstructorParameterToAProperty(
|
||||||
classDescriptor,
|
classDescriptor,
|
||||||
@@ -238,20 +245,23 @@ public class TopDownAnalyzer {
|
|||||||
propertyDescriptor);
|
propertyDescriptor);
|
||||||
}
|
}
|
||||||
if (constructorDescriptor != null) {
|
if (constructorDescriptor != null) {
|
||||||
classDescriptor.addConstructor(constructorDescriptor);
|
classDescriptor.setPrimaryConstructor(constructorDescriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processConstructor(MutableClassDescriptor classDescriptor, JetConstructor constructor) {
|
private void processSecondaryConstructor(MutableClassDescriptor classDescriptor, JetConstructor constructor) {
|
||||||
ConstructorDescriptor constructorDescriptor = classDescriptorResolver.resolveConstructorDescriptor(classDescriptor.getWritableUnsubstitutedMemberScope(), classDescriptor, constructor, false);
|
ConstructorDescriptor constructorDescriptor = classDescriptorResolver.resolveSecondaryConstructorDescriptor(
|
||||||
|
classDescriptor.getWritableUnsubstitutedMemberScope(),
|
||||||
|
classDescriptor,
|
||||||
|
constructor);
|
||||||
classDescriptor.addConstructor(constructorDescriptor);
|
classDescriptor.addConstructor(constructorDescriptor);
|
||||||
functions.put(constructor, constructorDescriptor);
|
constructors.put(constructor, constructorDescriptor);
|
||||||
declaringScopes.put(constructor, classDescriptor.getWritableUnsubstitutedMemberScope());
|
declaringScopes.put(constructor, classDescriptor.getWritableUnsubstitutedMemberScope());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processFunction(@NotNull WritableScope declaringScope, JetFunction function) {
|
private void processFunction(@NotNull WritableScope declaringScope, JetFunction function) {
|
||||||
declaringScopes.put(function, declaringScope);
|
declaringScopes.put(function, declaringScope);
|
||||||
FunctionDescriptor descriptor = classDescriptorResolver.resolveFunctionDescriptor(declaringScope.getContainingDeclaration(), declaringScope, function);
|
FunctionDescriptorImpl descriptor = classDescriptorResolver.resolveFunctionDescriptor(declaringScope.getContainingDeclaration(), declaringScope, function);
|
||||||
declaringScope.addFunctionDescriptor(descriptor);
|
declaringScope.addFunctionDescriptor(descriptor);
|
||||||
functions.put(function, descriptor);
|
functions.put(function, descriptor);
|
||||||
}
|
}
|
||||||
@@ -272,21 +282,22 @@ public class TopDownAnalyzer {
|
|||||||
|
|
||||||
private void resolveBehaviorDeclarationBodies() {
|
private void resolveBehaviorDeclarationBodies() {
|
||||||
resolveDelegationSpecifierLists();
|
resolveDelegationSpecifierLists();
|
||||||
|
resolveSecondaryConstructorBodies();
|
||||||
|
|
||||||
//TODO : anonymous initializers
|
//TODO : anonymous initializers
|
||||||
|
|
||||||
resolvePropertyDeclarationBodies();
|
resolvePropertyDeclarationBodies();
|
||||||
resolveFunctionDeclarationBodies();
|
resolveFunctionBodies();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resolveDelegationSpecifierLists() {
|
private void resolveDelegationSpecifierLists() {
|
||||||
|
// TODO : Make sure the same thing is not initialized twice
|
||||||
final JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(trace, JetFlowInformationProvider.NONE);
|
final JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(trace, JetFlowInformationProvider.NONE);
|
||||||
for (Map.Entry<JetClass, MutableClassDescriptor> entry : classes.entrySet()) {
|
for (Map.Entry<JetClass, MutableClassDescriptor> entry : classes.entrySet()) {
|
||||||
final JetClass declaration = entry.getKey();
|
final JetClass jetClass = entry.getKey();
|
||||||
final MutableClassDescriptor descriptor = entry.getValue();
|
final MutableClassDescriptor descriptor = entry.getValue();
|
||||||
|
|
||||||
for (JetDelegationSpecifier delegationSpecifier : declaration.getDelegationSpecifiers()) {
|
for (JetDelegationSpecifier delegationSpecifier : jetClass.getDelegationSpecifiers()) {
|
||||||
delegationSpecifier.accept(new JetVisitor() {
|
delegationSpecifier.accept(new JetVisitor() {
|
||||||
@Override
|
@Override
|
||||||
public void visitDelegationByExpressionSpecifier(JetDelegatorByExpressionSpecifier specifier) {
|
public void visitDelegationByExpressionSpecifier(JetDelegatorByExpressionSpecifier specifier) {
|
||||||
@@ -305,19 +316,36 @@ public class TopDownAnalyzer {
|
|||||||
JetTypeReference typeReference = call.getTypeReference();
|
JetTypeReference typeReference = call.getTypeReference();
|
||||||
if (typeReference != null) {
|
if (typeReference != null) {
|
||||||
typeInferrer.checkConstructorCall(descriptor.getWritableUnsubstitutedMemberScope(), typeReference, call);
|
typeInferrer.checkConstructorCall(descriptor.getWritableUnsubstitutedMemberScope(), typeReference, call);
|
||||||
|
if (jetClass.getPrimaryConstructorParameterList() == null) {
|
||||||
|
JetArgumentList valueArgumentList = call.getValueArgumentList();
|
||||||
|
assert valueArgumentList != null;
|
||||||
|
semanticServices.getErrorHandler().genericError(valueArgumentList.getNode(),
|
||||||
|
"Class " + JetPsiUtil.safeName(jetClass.getName()) + " must have a constructor in order to be able to initialize supertypes");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitDelegationToSuperClassSpecifier(JetDelegatorToSuperClass specifier) {
|
public void visitDelegationToSuperClassSpecifier(JetDelegatorToSuperClass specifier) {
|
||||||
if (declaration.getPrimaryConstructorParameterList() != null) {
|
JetType supertype = trace.resolveTypeReference(specifier.getTypeReference());
|
||||||
semanticServices.getErrorHandler().genericError(specifier.getNode(), "Constructor parameters required in initializer");
|
if (supertype != null) {
|
||||||
|
DeclarationDescriptor declarationDescriptor = supertype.getConstructor().getDeclarationDescriptor();
|
||||||
|
if (declarationDescriptor instanceof ClassDescriptor) {
|
||||||
|
ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor;
|
||||||
|
if (classDescriptor.getUnsubstitutedPrimaryConstructor() != null) {
|
||||||
|
semanticServices.getErrorHandler().genericError(specifier.getNode(), "This type has a constructor, and thus must be initialized here");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
semanticServices.getErrorHandler().genericError(specifier.getNode(), "Only classes may serve as supertypes");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitDelegationToThisCall(JetDelegatorToThisCall thisCall) {
|
public void visitDelegationToThisCall(JetDelegatorToThisCall thisCall) {
|
||||||
throw new IllegalStateException("This-calls should be prohibitied by the parser");
|
throw new IllegalStateException("This-calls should be prohibited by the parser");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -329,6 +357,93 @@ public class TopDownAnalyzer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void resolveSecondaryConstructorBodies() {
|
||||||
|
for (Map.Entry<JetDeclaration, ConstructorDescriptor> entry : constructors.entrySet()) {
|
||||||
|
JetDeclaration declaration = entry.getKey();
|
||||||
|
ConstructorDescriptor descriptor = entry.getValue();
|
||||||
|
|
||||||
|
WritableScope declaringScope = declaringScopes.get(declaration);
|
||||||
|
assert declaringScope != null;
|
||||||
|
|
||||||
|
resolveSecondaryConstructorBody((JetConstructor) declaration, descriptor, declaringScope);
|
||||||
|
|
||||||
|
assert descriptor.getUnsubstitutedReturnType() != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resolveSecondaryConstructorBody(JetConstructor declaration, final ConstructorDescriptor descriptor, final WritableScope declaringScope) {
|
||||||
|
WritableScope constructorScope = semanticServices.createWritableScope(declaringScope, declaringScope.getContainingDeclaration());
|
||||||
|
for (PropertyDescriptor propertyDescriptor : declaringScopesToProperties.get(descriptor.getContainingDeclaration())) {
|
||||||
|
constructorScope.addPropertyDescriptorByFieldName("$" + propertyDescriptor.getName(), propertyDescriptor);
|
||||||
|
}
|
||||||
|
final JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(constructorScope, descriptor, semanticServices);
|
||||||
|
|
||||||
|
final JetTypeInferrer typeInferrerForInitializers = semanticServices.getTypeInferrer(traceForConstructors, JetFlowInformationProvider.NONE);
|
||||||
|
|
||||||
|
JetClass containingClass = PsiTreeUtil.getParentOfType(declaration, JetClass.class);
|
||||||
|
assert containingClass != null : "This must be guaranteed by the parser";
|
||||||
|
if (containingClass.getPrimaryConstructorParameterList() == null) {
|
||||||
|
semanticServices.getErrorHandler().genericError(declaration.getNameNode(), "A secondary constructor may appear only in a class that has a primary constructor");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
List<JetDelegationSpecifier> initializers = declaration.getInitializers();
|
||||||
|
if (initializers.isEmpty()) {
|
||||||
|
semanticServices.getErrorHandler().genericError(declaration.getNameNode(), "Secondary constructors must have an initializer list");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
initializers.get(0).accept(new JetVisitor() {
|
||||||
|
@Override
|
||||||
|
public void visitDelegationToSuperCallSpecifier(JetDelegatorToSuperCall call) {
|
||||||
|
JetTypeReference typeReference = call.getTypeReference();
|
||||||
|
if (typeReference != null) {
|
||||||
|
typeInferrerForInitializers.checkConstructorCall(functionInnerScope, typeReference, call);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitDelegationToThisCall(JetDelegatorToThisCall call) {
|
||||||
|
// TODO : check that there's no recursion in this() calls
|
||||||
|
// TODO : check: if a this() call is present, no other initializers are allowed
|
||||||
|
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor.getContainingDeclaration();
|
||||||
|
typeInferrerForInitializers.checkClassConstructorCall(
|
||||||
|
functionInnerScope,
|
||||||
|
call.getThisReference(),
|
||||||
|
classDescriptor,
|
||||||
|
classDescriptor.getDefaultType(),
|
||||||
|
call);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitDelegationByExpressionSpecifier(JetDelegatorByExpressionSpecifier specifier) {
|
||||||
|
semanticServices.getErrorHandler().genericError(specifier.getNode(), "'by'-clause is only supported for primary constructors");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitDelegationToSuperClassSpecifier(JetDelegatorToSuperClass specifier) {
|
||||||
|
semanticServices.getErrorHandler().genericError(specifier.getNode(), "Constructor parameters required");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitDelegationSpecifier(JetDelegationSpecifier specifier) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
for (int i = 1, initializersSize = initializers.size(); i < initializersSize; i++) {
|
||||||
|
JetDelegationSpecifier initializer = initializers.get(i);
|
||||||
|
semanticServices.getErrorHandler().genericError(initializer.getNode(), "Only one call to 'this(...)' is allowed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JetExpression bodyExpression = declaration.getBodyExpression();
|
||||||
|
if (bodyExpression != null) {
|
||||||
|
computeFlowData(declaration, bodyExpression);
|
||||||
|
JetFlowInformationProvider flowInformationProvider = computeFlowData(declaration, bodyExpression);
|
||||||
|
JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(traceForConstructors, flowInformationProvider);
|
||||||
|
|
||||||
|
typeInferrer.getType(functionInnerScope, bodyExpression, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void resolvePropertyDeclarationBodies() {
|
private void resolvePropertyDeclarationBodies() {
|
||||||
for (Map.Entry<JetProperty, PropertyDescriptor> entry : properties.entrySet()) {
|
for (Map.Entry<JetProperty, PropertyDescriptor> entry : properties.entrySet()) {
|
||||||
JetProperty declaration = entry.getKey();
|
JetProperty declaration = entry.getKey();
|
||||||
@@ -395,85 +510,20 @@ public class TopDownAnalyzer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resolveFunctionDeclarationBodies() {
|
private void resolveFunctionBodies() {
|
||||||
for (Map.Entry<JetDeclaration, FunctionDescriptor> entry : functions.entrySet()) {
|
for (Map.Entry<JetDeclaration, FunctionDescriptorImpl> entry : functions.entrySet()) {
|
||||||
JetDeclaration declaration = entry.getKey();
|
JetDeclaration declaration = entry.getKey();
|
||||||
FunctionDescriptor descriptor = entry.getValue();
|
FunctionDescriptor descriptor = entry.getValue();
|
||||||
|
|
||||||
WritableScope declaringScope = declaringScopes.get(declaration);
|
WritableScope declaringScope = declaringScopes.get(declaration);
|
||||||
assert declaringScope != null;
|
assert declaringScope != null;
|
||||||
|
|
||||||
if (declaration instanceof JetFunction) {
|
resolveFunctionBody(trace, (JetFunction) declaration, (FunctionDescriptorImpl) descriptor, declaringScope);
|
||||||
resolveFunctionBody(trace, (JetFunction) declaration, (FunctionDescriptorImpl) descriptor, declaringScope);
|
|
||||||
}
|
|
||||||
else if (declaration instanceof JetConstructor) {
|
|
||||||
resolveConstructorBody((JetConstructor) declaration, descriptor, declaringScope);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new UnsupportedOperationException(); // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
assert descriptor.getUnsubstitutedReturnType() != null;
|
assert descriptor.getUnsubstitutedReturnType() != null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resolveConstructorBody(JetConstructor declaration, final FunctionDescriptor descriptor, final WritableScope declaringScope) {
|
|
||||||
WritableScope constructorScope = semanticServices.createWritableScope(declaringScope, declaringScope.getContainingDeclaration());
|
|
||||||
for (PropertyDescriptor propertyDescriptor : declaringScopesToProperties.get(descriptor.getContainingDeclaration())) {
|
|
||||||
constructorScope.addPropertyDescriptorByFieldName("$" + propertyDescriptor.getName(), propertyDescriptor);
|
|
||||||
}
|
|
||||||
final JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(constructorScope, descriptor, semanticServices);
|
|
||||||
final JetTypeInferrer typeInferrerForInitializers = semanticServices.getTypeInferrer(traceForConstructors, JetFlowInformationProvider.NONE);
|
|
||||||
for (JetDelegationSpecifier initializer : declaration.getInitializers()) {
|
|
||||||
// TODO : check that the type being referenced is actually a supertype
|
|
||||||
initializer.accept(new JetVisitor() {
|
|
||||||
@Override
|
|
||||||
public void visitDelegationToSuperCallSpecifier(JetDelegatorToSuperCall call) {
|
|
||||||
JetTypeReference typeReference = call.getTypeReference();
|
|
||||||
if (typeReference != null) {
|
|
||||||
typeInferrerForInitializers.checkConstructorCall(functionInnerScope, typeReference, call);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitDelegationToThisCall(JetDelegatorToThisCall call) {
|
|
||||||
// TODO : check that there's no recursion in this() calls
|
|
||||||
// TODO : check: if a this() call is present, no other initializers are allowed
|
|
||||||
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor.getContainingDeclaration();
|
|
||||||
typeInferrerForInitializers.checkClassConstructorCall(
|
|
||||||
functionInnerScope,
|
|
||||||
call.getThisReference(),
|
|
||||||
classDescriptor,
|
|
||||||
classDescriptor.getDefaultType(),
|
|
||||||
call);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitDelegationByExpressionSpecifier(JetDelegatorByExpressionSpecifier specifier) {
|
|
||||||
semanticServices.getErrorHandler().genericError(specifier.getNode(), "'by'-clause is only supported for primary constructors");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitDelegationToSuperClassSpecifier(JetDelegatorToSuperClass specifier) {
|
|
||||||
semanticServices.getErrorHandler().genericError(specifier.getNode(), "Constructor parameters required");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitDelegationSpecifier(JetDelegationSpecifier specifier) {
|
|
||||||
throw new IllegalStateException();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
JetExpression bodyExpression = declaration.getBodyExpression();
|
|
||||||
if (bodyExpression != null) {
|
|
||||||
computeFlowData(declaration, bodyExpression);
|
|
||||||
JetFlowInformationProvider flowInformationProvider = computeFlowData(declaration, bodyExpression);
|
|
||||||
JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(traceForConstructors, flowInformationProvider);
|
|
||||||
|
|
||||||
typeInferrer.getType(functionInnerScope, bodyExpression, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resolveFunctionBody(
|
private void resolveFunctionBody(
|
||||||
@NotNull BindingTrace trace,
|
@NotNull BindingTrace trace,
|
||||||
@NotNull JetDeclarationWithBody function,
|
@NotNull JetDeclarationWithBody function,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.resolve.JetScope;
|
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -16,6 +17,9 @@ public interface ClassDescriptor extends ClassifierDescriptor {
|
|||||||
@NotNull
|
@NotNull
|
||||||
FunctionGroup getConstructors(List<TypeProjection> typeArguments);
|
FunctionGroup getConstructors(List<TypeProjection> typeArguments);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
ConstructorDescriptor getUnsubstitutedPrimaryConstructor();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
DeclarationDescriptor getContainingDeclaration();
|
DeclarationDescriptor getContainingDeclaration();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.jetbrains.jet.lang.types;
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.resolve.JetScope;
|
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||||
import org.jetbrains.jet.lang.resolve.SubstitutingScope;
|
import org.jetbrains.jet.lang.resolve.SubstitutingScope;
|
||||||
|
|
||||||
@@ -16,6 +17,7 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
|
|||||||
|
|
||||||
private JetScope memberDeclarations;
|
private JetScope memberDeclarations;
|
||||||
private FunctionGroup constructors;
|
private FunctionGroup constructors;
|
||||||
|
private ConstructorDescriptor primaryConstructor;
|
||||||
|
|
||||||
public ClassDescriptorImpl(
|
public ClassDescriptorImpl(
|
||||||
@NotNull DeclarationDescriptor containingDeclaration,
|
@NotNull DeclarationDescriptor containingDeclaration,
|
||||||
@@ -28,10 +30,13 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
|
|||||||
@NotNull List<TypeParameterDescriptor> typeParameters,
|
@NotNull List<TypeParameterDescriptor> typeParameters,
|
||||||
@NotNull Collection<? extends JetType> superclasses,
|
@NotNull Collection<? extends JetType> superclasses,
|
||||||
@NotNull JetScope memberDeclarations,
|
@NotNull JetScope memberDeclarations,
|
||||||
@NotNull FunctionGroup constructors) {
|
@NotNull FunctionGroup constructors,
|
||||||
|
@Nullable ConstructorDescriptor primaryConstructor) {
|
||||||
this.typeConstructor = new TypeConstructorImpl(this, getAttributes(), sealed, getName(), typeParameters, superclasses);
|
this.typeConstructor = new TypeConstructorImpl(this, getAttributes(), sealed, getName(), typeParameters, superclasses);
|
||||||
this.memberDeclarations = memberDeclarations;
|
this.memberDeclarations = memberDeclarations;
|
||||||
this.constructors = constructors;
|
this.constructors = constructors;
|
||||||
|
this.primaryConstructor = primaryConstructor;
|
||||||
|
assert !constructors.isEmpty() || primaryConstructor == null;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,4 +84,9 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
|
|||||||
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
|
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
|
||||||
return visitor.visitClassDescriptor(this, data);
|
return visitor.visitClassDescriptor(this, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
|
||||||
|
return primaryConstructor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -80,8 +80,12 @@ public class ErrorUtils {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final ClassDescriptor ERROR_CLASS = new ClassDescriptorImpl(ERROR_MODULE, Collections.<Attribute>emptyList(), "<ERROR CLASS>").initialize(
|
private static final ClassDescriptorImpl ERROR_CLASS = new ClassDescriptorImpl(ERROR_MODULE, Collections.<Attribute>emptyList(), "<ERROR CLASS>");
|
||||||
true, Collections.<TypeParameterDescriptor>emptyList(), Collections.<JetType>emptyList(), getErrorScope(), ERROR_FUNCTION_GROUP);
|
private static final ConstructorDescriptor ERROR_CONSTRUCTOR = new ConstructorDescriptorImpl(ERROR_CLASS, Collections.<Attribute>emptyList(), true);
|
||||||
|
static {
|
||||||
|
ERROR_CLASS.initialize(
|
||||||
|
true, Collections.<TypeParameterDescriptor>emptyList(), Collections.<JetType>emptyList(), getErrorScope(), ERROR_FUNCTION_GROUP, ERROR_CONSTRUCTOR);
|
||||||
|
}
|
||||||
|
|
||||||
private static JetScope getErrorScope() {
|
private static JetScope getErrorScope() {
|
||||||
return ERROR_SCOPE;
|
return ERROR_SCOPE;
|
||||||
|
|||||||
@@ -47,7 +47,8 @@ public class JetStandardClasses {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
JetScope.EMPTY,
|
JetScope.EMPTY,
|
||||||
FunctionGroup.EMPTY
|
FunctionGroup.EMPTY,
|
||||||
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
private static final JetType NOTHING_TYPE = new JetTypeImpl(getNothing());
|
private static final JetType NOTHING_TYPE = new JetTypeImpl(getNothing());
|
||||||
@@ -68,7 +69,8 @@ public class JetStandardClasses {
|
|||||||
Collections.<TypeParameterDescriptor>emptyList(),
|
Collections.<TypeParameterDescriptor>emptyList(),
|
||||||
Collections.<JetType>emptySet(),
|
Collections.<JetType>emptySet(),
|
||||||
JetScope.EMPTY,
|
JetScope.EMPTY,
|
||||||
FunctionGroup.EMPTY
|
FunctionGroup.EMPTY,
|
||||||
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
private static final JetType ANY_TYPE = new JetTypeImpl(ANY.getTypeConstructor(), JetScope.EMPTY);
|
private static final JetType ANY_TYPE = new JetTypeImpl(ANY.getTypeConstructor(), JetScope.EMPTY);
|
||||||
@@ -102,7 +104,8 @@ public class JetStandardClasses {
|
|||||||
parameters,
|
parameters,
|
||||||
Collections.singleton(getAnyType()),
|
Collections.singleton(getAnyType()),
|
||||||
STUB,
|
STUB,
|
||||||
STUB_FG);
|
STUB_FG,
|
||||||
|
null); // TODO : constructor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,7 +125,7 @@ public class JetStandardClasses {
|
|||||||
FUNCTION[i] = function.initialize(
|
FUNCTION[i] = function.initialize(
|
||||||
false,
|
false,
|
||||||
createTypeParameters(i, function),
|
createTypeParameters(i, function),
|
||||||
Collections.singleton(getAnyType()), STUB, STUB_FG);
|
Collections.singleton(getAnyType()), STUB, FunctionGroup.EMPTY, null);
|
||||||
|
|
||||||
ClassDescriptorImpl receiverFunction = new ClassDescriptorImpl(
|
ClassDescriptorImpl receiverFunction = new ClassDescriptorImpl(
|
||||||
STANDARD_CLASSES_NAMESPACE,
|
STANDARD_CLASSES_NAMESPACE,
|
||||||
@@ -136,7 +139,7 @@ public class JetStandardClasses {
|
|||||||
RECEIVER_FUNCTION[i] = receiverFunction.initialize(
|
RECEIVER_FUNCTION[i] = receiverFunction.initialize(
|
||||||
false,
|
false,
|
||||||
parameters,
|
parameters,
|
||||||
Collections.singleton(getAnyType()), STUB, STUB_FG);
|
Collections.singleton(getAnyType()), STUB, FunctionGroup.EMPTY, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
class A {
|
class A() {
|
||||||
fun equals(a : Any?) : Boolean
|
fun equals(a : Any?) : Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
class B {
|
class B() {
|
||||||
fun equals(a : Any?) : Boolean?
|
fun equals(a : Any?) : Boolean?
|
||||||
}
|
}
|
||||||
|
|
||||||
class C {
|
class C() {
|
||||||
fun equals(a : Any?) : Int
|
fun equals(a : Any?) : Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,34 @@
|
|||||||
class Z {
|
|
||||||
this() : this(1, true) {}
|
|
||||||
|
|
||||||
this(x : Int, y : Boolean) : this<error>(1)</error> {}
|
class NoC
|
||||||
|
class NoC1 : NoC
|
||||||
|
|
||||||
|
class WithC0() : NoC<error>()</error>
|
||||||
|
class WithC1() : NoC
|
||||||
|
class NoC2 : <error>WithC1</error>
|
||||||
|
class NoC3 : WithC1<error>()</error>
|
||||||
|
class WithC2() : <error>WithC1</error>
|
||||||
|
|
||||||
|
class NoPC {
|
||||||
|
<error>this</error>() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Foo() : <error>Z</error>, <error>this</error>() {
|
class WithPC0() {
|
||||||
|
this(a : Int) : this() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class WithPC1(a : Int) {
|
||||||
|
<error>this</error>() {}
|
||||||
|
|
||||||
|
this(b : Long) : this("") {}
|
||||||
|
|
||||||
|
this(s : String) : this(1) {}
|
||||||
|
|
||||||
|
this(b : Char) : this<error>("", 2)</error> {}
|
||||||
|
|
||||||
|
this(b : Byte) : this(""), <error>this(1)</error> {}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Foo() : <error>WithPC0</error>, <error>this</error>() {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
class NotRange1 {
|
class NotRange1() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class NotRange2 {
|
class NotRange2() {
|
||||||
fun iterator() : Unit
|
fun iterator() : Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ class ImproperIterator1 {
|
|||||||
fun hasNext() : Boolean
|
fun hasNext() : Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
class NotRange3 {
|
class NotRange3() {
|
||||||
fun iterator() : ImproperIterator1
|
fun iterator() : ImproperIterator1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ class ImproperIterator2 {
|
|||||||
fun next() : Boolean
|
fun next() : Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
class NotRange4 {
|
class NotRange4() {
|
||||||
fun iterator() : ImproperIterator2
|
fun iterator() : ImproperIterator2
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ class ImproperIterator3 {
|
|||||||
fun next() : Int
|
fun next() : Int
|
||||||
}
|
}
|
||||||
|
|
||||||
class NotRange5 {
|
class NotRange5() {
|
||||||
fun iterator() : ImproperIterator3
|
fun iterator() : ImproperIterator3
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ class AmbiguousHasNextIterator {
|
|||||||
fun next() : Int
|
fun next() : Int
|
||||||
}
|
}
|
||||||
|
|
||||||
class NotRange6 {
|
class NotRange6() {
|
||||||
fun iterator() : AmbiguousHasNextIterator
|
fun iterator() : AmbiguousHasNextIterator
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ class ImproperIterator4 {
|
|||||||
fun next() : Int
|
fun next() : Int
|
||||||
}
|
}
|
||||||
|
|
||||||
class NotRange7 {
|
class NotRange7() {
|
||||||
fun iterator() : ImproperIterator3
|
fun iterator() : ImproperIterator3
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,11 +57,11 @@ class GoodIterator {
|
|||||||
fun next() : Int
|
fun next() : Int
|
||||||
}
|
}
|
||||||
|
|
||||||
class Range0 {
|
class Range0() {
|
||||||
fun iterator() : GoodIterator
|
fun iterator() : GoodIterator
|
||||||
}
|
}
|
||||||
|
|
||||||
class Range1 {
|
class Range1() {
|
||||||
fun iterator() : Iterator<Int>
|
fun iterator() : Iterator<Int>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
class IncDec {
|
class IncDec() {
|
||||||
fun inc() : IncDec = this
|
fun inc() : IncDec = this
|
||||||
fun dec() : IncDec = this
|
fun dec() : IncDec = this
|
||||||
}
|
}
|
||||||
@@ -15,7 +15,7 @@ fun testIncDec() {
|
|||||||
x = --x
|
x = --x
|
||||||
}
|
}
|
||||||
|
|
||||||
class WrongIncDec {
|
class WrongIncDec() {
|
||||||
fun inc() : Int = 1
|
fun inc() : Int = 1
|
||||||
fun dec() : Int = 1
|
fun dec() : Int = 1
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,7 @@ fun testWrongIncDec() {
|
|||||||
<error>--</error>x
|
<error>--</error>x
|
||||||
}
|
}
|
||||||
|
|
||||||
class UnitIncDec {
|
class UnitIncDec() {
|
||||||
fun inc() : Unit {}
|
fun inc() : Unit {}
|
||||||
fun dec() : Unit {}
|
fun dec() : Unit {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,11 +12,11 @@
|
|||||||
val p : Int = <error>1</error>
|
val p : Int = <error>1</error>
|
||||||
get() = 1
|
get() = 1
|
||||||
|
|
||||||
class Test {
|
class Test() {
|
||||||
var a : Int
|
var a : Int
|
||||||
var b : Int get() = <error>$a</error>; set(x) {a = x; <error>$a</error> = x}
|
var b : Int get() = <error>$a</error>; set(x) {a = x; <error>$a</error> = x}
|
||||||
|
|
||||||
this() {
|
this(i : Int) : this() {
|
||||||
<error>$b</error> = $a
|
<error>$b</error> = $a
|
||||||
$a = <error>$b</error>
|
$a = <error>$b</error>
|
||||||
a = <error>$b</error>
|
a = <error>$b</error>
|
||||||
|
|||||||
@@ -7,3 +7,8 @@ class foo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class foo() : Bar
|
||||||
|
protected class foo private () : Bar
|
||||||
|
private class foo<T>() : Bar
|
||||||
|
internal class foo<T> private () : Bar
|
||||||
@@ -124,4 +124,106 @@ JetFile: Constructors.jet
|
|||||||
PsiWhiteSpace('\n\n ')
|
PsiWhiteSpace('\n\n ')
|
||||||
PsiElement(RBRACE)('}')
|
PsiElement(RBRACE)('}')
|
||||||
PsiWhiteSpace('\n\n')
|
PsiWhiteSpace('\n\n')
|
||||||
PsiElement(RBRACE)('}')
|
PsiElement(RBRACE)('}')
|
||||||
|
PsiWhiteSpace('\n\n')
|
||||||
|
CLASS
|
||||||
|
MODIFIER_LIST
|
||||||
|
PsiElement(public)('public')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(class)('class')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('foo')
|
||||||
|
TYPE_PARAMETER_LIST
|
||||||
|
<empty list>
|
||||||
|
VALUE_PARAMETER_LIST
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(COLON)(':')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
DELEGATION_SPECIFIER_LIST
|
||||||
|
DELEGATOR_SUPER_CLASS
|
||||||
|
TYPE_REFERENCE
|
||||||
|
USER_TYPE
|
||||||
|
REFERENCE_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('Bar')
|
||||||
|
PsiWhiteSpace('\n')
|
||||||
|
CLASS
|
||||||
|
MODIFIER_LIST
|
||||||
|
PsiElement(protected)('protected')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(class)('class')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('foo')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
TYPE_PARAMETER_LIST
|
||||||
|
<empty list>
|
||||||
|
PRIMARY_CONSTRUCTOR_MODIFIER_LIST
|
||||||
|
PsiElement(private)('private')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
VALUE_PARAMETER_LIST
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(COLON)(':')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
DELEGATION_SPECIFIER_LIST
|
||||||
|
DELEGATOR_SUPER_CLASS
|
||||||
|
TYPE_REFERENCE
|
||||||
|
USER_TYPE
|
||||||
|
REFERENCE_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('Bar')
|
||||||
|
PsiWhiteSpace('\n')
|
||||||
|
CLASS
|
||||||
|
MODIFIER_LIST
|
||||||
|
PsiElement(private)('private')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(class)('class')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('foo')
|
||||||
|
TYPE_PARAMETER_LIST
|
||||||
|
PsiElement(LT)('<')
|
||||||
|
TYPE_PARAMETER
|
||||||
|
PsiElement(IDENTIFIER)('T')
|
||||||
|
PsiElement(GT)('>')
|
||||||
|
VALUE_PARAMETER_LIST
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(COLON)(':')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
DELEGATION_SPECIFIER_LIST
|
||||||
|
DELEGATOR_SUPER_CLASS
|
||||||
|
TYPE_REFERENCE
|
||||||
|
USER_TYPE
|
||||||
|
REFERENCE_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('Bar')
|
||||||
|
PsiWhiteSpace('\n')
|
||||||
|
CLASS
|
||||||
|
MODIFIER_LIST
|
||||||
|
PsiElement(internal)('internal')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(class)('class')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('foo')
|
||||||
|
TYPE_PARAMETER_LIST
|
||||||
|
PsiElement(LT)('<')
|
||||||
|
TYPE_PARAMETER
|
||||||
|
PsiElement(IDENTIFIER)('T')
|
||||||
|
PsiElement(GT)('>')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PRIMARY_CONSTRUCTOR_MODIFIER_LIST
|
||||||
|
PsiElement(private)('private')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
VALUE_PARAMETER_LIST
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(COLON)(':')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
DELEGATION_SPECIFIER_LIST
|
||||||
|
DELEGATOR_SUPER_CLASS
|
||||||
|
TYPE_REFERENCE
|
||||||
|
USER_TYPE
|
||||||
|
REFERENCE_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('Bar')
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
class Z {
|
class Z(a : Int) {
|
||||||
~c1~this() : `c2`this(1, true) {}
|
~c1~this() : `c2`this(1, true) {}
|
||||||
|
|
||||||
~c2~this(x : Int, y : Boolean) : `c1`this() {}
|
~c2~this(x : Int, y : Boolean) : `c1`this() {}
|
||||||
|
|||||||
Reference in New Issue
Block a user