Parse primary constructor into separate PSI element

This commit is contained in:
Denis Zharkov
2015-03-30 17:41:57 +03:00
parent 59f939d9ef
commit af2bcfb524
51 changed files with 1566 additions and 1413 deletions
@@ -38,6 +38,7 @@ public interface JetNodeTypes {
IElementType ENUM_ENTRY = JetStubElementTypes.ENUM_ENTRY;
IElementType ANONYMOUS_INITIALIZER = JetStubElementTypes.ANONYMOUS_INITIALIZER;
IElementType SECONDARY_CONSTRUCTOR = JetStubElementTypes.SECONDARY_CONSTRUCTOR;
IElementType PRIMARY_CONSTRUCTOR = JetStubElementTypes.PRIMARY_CONSTRUCTOR;
IElementType TYPE_PARAMETER_LIST = JetStubElementTypes.TYPE_PARAMETER_LIST;
IElementType TYPE_PARAMETER = JetStubElementTypes.TYPE_PARAMETER;
@@ -55,7 +56,6 @@ public interface JetNodeTypes {
IElementType FILE_ANNOTATION_LIST = JetStubElementTypes.FILE_ANNOTATION_LIST;
IElementType IMPORT_DIRECTIVE = JetStubElementTypes.IMPORT_DIRECTIVE;
IElementType MODIFIER_LIST = JetStubElementTypes.MODIFIER_LIST;
IElementType PRIMARY_CONSTRUCTOR_MODIFIER_LIST = JetStubElementTypes.PRIMARY_CONSTRUCTOR_MODIFIER_LIST;
IElementType ANNOTATION = JetStubElementTypes.ANNOTATION;
IElementType ANNOTATION_ENTRY = JetStubElementTypes.ANNOTATION_ENTRY;
@@ -626,7 +626,8 @@ public class JetParsing extends AbstractJetParsing {
OptionalMarker constructorModifiersMarker = new OptionalMarker(object);
PsiBuilder.Marker beforeConstructorModifiers = mark();
boolean hasConstructorModifiers = parseModifierList(PRIMARY_CONSTRUCTOR_MODIFIER_LIST, REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
PsiBuilder.Marker primaryConstructorMarker = mark();
boolean hasConstructorModifiers = parseModifierList(MODIFIER_LIST, REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
// Some modifiers found, but no parentheses following: class has already ended, and we are looking at something else
if (hasConstructorModifiers && !atSet(LPAR, LBRACE, COLON)) {
@@ -640,14 +641,19 @@ public class JetParsing extends AbstractJetParsing {
if (at(LPAR)) {
parseValueParameterList(false, /* typeRequired = */ true, TokenSet.create(COLON, LBRACE));
primaryConstructorMarker.done(PRIMARY_CONSTRUCTOR);
}
else if (hasConstructorModifiers) {
// A comprehensive error message for cases like:
// class A private : Foo
// or
// class A private {
primaryConstructorMarker.done(PRIMARY_CONSTRUCTOR);
error("Expecting primary constructor parameter list");
}
else {
primaryConstructorMarker.drop();
}
constructorModifiersMarker.error("Constructors are not allowed for objects");
if (at(COLON)) {
@@ -62,9 +62,15 @@ public class JetClass extends JetTypeParameterListOwnerStub<KotlinClassStub> imp
return visitor.visitClass(this, data);
}
@Nullable
public JetPrimaryConstructor getPrimaryConstructor() {
return getStubOrPsiChild(JetStubElementTypes.PRIMARY_CONSTRUCTOR);
}
@Nullable
public JetParameterList getPrimaryConstructorParameterList() {
return getStubOrPsiChild(JetStubElementTypes.VALUE_PARAMETER_LIST);
JetPrimaryConstructor primaryConstructor = getPrimaryConstructor();
return primaryConstructor != null ? primaryConstructor.getValueParameterList() : null;
}
@NotNull
@@ -89,22 +95,8 @@ public class JetClass extends JetTypeParameterListOwnerStub<KotlinClassStub> imp
@Nullable
public JetModifierList getPrimaryConstructorModifierList() {
return getStubOrPsiChild(JetStubElementTypes.PRIMARY_CONSTRUCTOR_MODIFIER_LIST);
}
public void addPrimaryConstructorModifier(@NotNull JetModifierKeywordToken modifier) {
JetModifierList modifierList = getPrimaryConstructorModifierList();
if (modifierList != null) {
AddRemoveModifierPackage.addModifier(modifierList, modifier, JetTokens.PUBLIC_KEYWORD);
}
else {
if (modifier == JetTokens.PUBLIC_KEYWORD) return;
JetParameterList parameterList = getPrimaryConstructorParameterList();
assert parameterList != null;
JetModifierList newModifierList = new JetPsiFactory(getProject()).createModifierList(modifier);
addBefore(newModifierList, parameterList);
}
JetPrimaryConstructor primaryConstructor = getPrimaryConstructor();
return primaryConstructor != null ? primaryConstructor.getModifierList() : null;
}
@Override
@@ -0,0 +1,85 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.psi;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.lexer.JetModifierKeywordToken;
import org.jetbrains.kotlin.lexer.JetTokens;
import org.jetbrains.kotlin.psi.addRemoveModifier.AddRemoveModifierPackage;
import org.jetbrains.kotlin.psi.stubs.KotlinPlaceHolderStub;
import org.jetbrains.kotlin.psi.stubs.elements.JetStubElementTypes;
import java.util.Collections;
import java.util.List;
public class JetPrimaryConstructor extends JetDeclarationStub<KotlinPlaceHolderStub<JetPrimaryConstructor>> {
public JetPrimaryConstructor(@NotNull ASTNode node) {
super(node);
}
public JetPrimaryConstructor(@NotNull KotlinPlaceHolderStub<JetPrimaryConstructor> stub) {
super(stub, JetStubElementTypes.PRIMARY_CONSTRUCTOR);
}
@Override
public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
return visitor.visitPrimaryConstructor(this, data);
}
@Nullable
public JetParameterList getValueParameterList() {
return getStubOrPsiChild(JetStubElementTypes.VALUE_PARAMETER_LIST);
}
@NotNull
public List<JetParameter> getValueParameters() {
JetParameterList list = getValueParameterList();
return list != null ? list.getParameters() : Collections.<JetParameter>emptyList();
}
@Override
public void addModifier(@NotNull JetModifierKeywordToken modifier) {
JetModifierList modifierList = getModifierList();
if (modifierList != null) {
AddRemoveModifierPackage.addModifier(modifierList, modifier, JetTokens.PUBLIC_KEYWORD);
}
else {
if (modifier == JetTokens.PUBLIC_KEYWORD) return;
JetParameterList parameterList = getValueParameterList();
assert parameterList != null;
JetPsiFactory psiFactory = new JetPsiFactory(getProject());
JetModifierList newModifierList = psiFactory.createModifierList(modifier);
addBefore(newModifierList, parameterList);
}
}
@Nullable
public JetClass getContainingClassOrNull() {
JetClassOrObject classOrObject = (JetClassOrObject) getParent();
return classOrObject instanceof JetClass ? (JetClass) classOrObject : null;
}
@NotNull
public JetClass getContainingClass() {
JetClass classOrNull = getContainingClassOrNull();
assert classOrNull != null : "This method should be called when parent is JetClass";
return classOrNull;
}
}
@@ -1,32 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.psi;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.psi.stubs.KotlinModifierListStub;
import org.jetbrains.kotlin.psi.stubs.elements.JetStubElementTypes;
public class JetPrimaryConstructorModifierList extends JetModifierList {
public JetPrimaryConstructorModifierList(@NotNull ASTNode node) {
super(node);
}
public JetPrimaryConstructorModifierList(@NotNull KotlinModifierListStub stub) {
super(stub, JetStubElementTypes.PRIMARY_CONSTRUCTOR_MODIFIER_LIST);
}
}
@@ -37,6 +37,10 @@ public class JetVisitor<R, D> extends PsiElementVisitor {
return visitJetElement(constructor, data);
}
public R visitPrimaryConstructor(@NotNull JetPrimaryConstructor constructor, D data) {
return visitJetElement(constructor, data);
}
public R visitNamedFunction(@NotNull JetNamedFunction function, D data) {
return visitNamedDeclaration(function, data);
}
@@ -37,6 +37,10 @@ public class JetVisitorVoid extends JetVisitor<Void, Void> {
super.visitSecondaryConstructor(constructor, null);
}
public void visitPrimaryConstructor(@NotNull JetPrimaryConstructor constructor) {
super.visitPrimaryConstructor(constructor, null);
}
public void visitNamedFunction(@NotNull JetNamedFunction function) {
super.visitNamedFunction(function, null);
}
@@ -38,6 +38,10 @@ public class JetVisitorVoidWithParameter<P> extends JetVisitor<Void, P> {
super.visitSecondaryConstructor(constructor, data);
}
public void visitPrimaryConstructorVoid(@NotNull JetPrimaryConstructor constructor, P data) {
super.visitPrimaryConstructor(constructor, data);
}
public void visitNamedFunctionVoid(@NotNull JetNamedFunction function, P data) {
super.visitNamedFunction(function, data);
}
@@ -441,6 +445,12 @@ public class JetVisitorVoidWithParameter<P> extends JetVisitor<Void, P> {
return null;
}
@Override
public Void visitPrimaryConstructor(@NotNull JetPrimaryConstructor constructor, P data) {
visitPrimaryConstructorVoid(constructor, data);
return null;
}
@Override
public final Void visitNamedFunction(@NotNull JetNamedFunction function, P data) {
visitNamedFunctionVoid(function, data);
@@ -35,6 +35,8 @@ public interface JetStubElementTypes {
new JetPlaceHolderStubElementType<JetClassInitializer>("ANONYMOUS_INITIALIZER", JetClassInitializer.class);
JetPlaceHolderStubElementType<JetSecondaryConstructor> SECONDARY_CONSTRUCTOR =
new JetPlaceHolderStubElementType<JetSecondaryConstructor>("SECONDARY_CONSTRUCTOR", JetSecondaryConstructor.class);
JetPlaceHolderStubElementType<JetPrimaryConstructor> PRIMARY_CONSTRUCTOR =
new JetPlaceHolderStubElementType<JetPrimaryConstructor>("PRIMARY_CONSTRUCTOR", JetPrimaryConstructor.class);
JetParameterElementType VALUE_PARAMETER = new JetParameterElementType("VALUE_PARAMETER");
JetPlaceHolderStubElementType<JetParameterList> VALUE_PARAMETER_LIST =
@@ -65,9 +67,6 @@ public interface JetStubElementTypes {
JetModifierListElementType<JetDeclarationModifierList> MODIFIER_LIST =
new JetModifierListElementType<JetDeclarationModifierList>("MODIFIER_LIST", JetDeclarationModifierList.class);
JetModifierListElementType<JetPrimaryConstructorModifierList> PRIMARY_CONSTRUCTOR_MODIFIER_LIST =
new JetModifierListElementType<JetPrimaryConstructorModifierList>("PRIMARY_CONSTRUCTOR_MODIFIER_LIST", JetPrimaryConstructorModifierList.class);
JetPlaceHolderStubElementType<JetTypeConstraintList> TYPE_CONSTRAINT_LIST =
new JetPlaceHolderStubElementType<JetTypeConstraintList>("TYPE_CONSTRAINT_LIST", JetTypeConstraintList.class);