From c9efc8f6be838351f86765f75df997f8fc553ee1 Mon Sep 17 00:00:00 2001 From: Daniil Ovchinnikov Date: Mon, 17 Oct 2016 22:31:55 +0300 Subject: [PATCH] [groovy] stubs for annotation argument list and name value pairs (IDEA-CR-14566) --- .../lang/parser/GroovyElementTypes.java | 4 +- .../GrAnnotationArgumentListImpl.java | 30 ++++---- .../annotation/GrAnnotationImpl.java | 28 +------- .../GrAnnotationNameValuePairImpl.java | 20 ++++-- .../GrAnnotationArgumentListElementType.java | 59 ++++++++++++++++ .../elements/GrNameValuePairElementType.java | 70 +++++++++++++++++++ .../stubs/elements/GrStubFileElementType.java | 2 +- .../plugins/groovy/lang/psi/stubs/stubs.kt | 29 ++++++++ .../testdata/groovy/stubs/typeParameters.test | 4 +- 9 files changed, 193 insertions(+), 53 deletions(-) create mode 100644 plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrAnnotationArgumentListElementType.java create mode 100644 plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrNameValuePairElementType.java create mode 100644 plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/stubs.kt diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java index 6596d556bf95..23f5c0b5c611 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java @@ -323,8 +323,8 @@ public interface GroovyElementTypes { }; //annotation GroovyElementType ANNOTATION_ARRAY_INITIALIZER = new GroovyElementType("annotation array initializer"); - GroovyElementType ANNOTATION_ARGUMENTS = new GroovyElementType("annotation arguments", true); - GroovyElementType ANNOTATION_MEMBER_VALUE_PAIR = new GroovyElementType("annotation member value pair"); + GrAnnotationArgumentListElementType ANNOTATION_ARGUMENTS = new GrAnnotationArgumentListElementType(); + GrNameValuePairElementType ANNOTATION_MEMBER_VALUE_PAIR = new GrNameValuePairElementType(); GrStubElementType ANNOTATION = new GrAnnotationElementType("annotation"); //parameters diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationArgumentListImpl.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationArgumentListImpl.java index 223e834d0c57..49408103f50f 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationArgumentListImpl.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationArgumentListImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -19,8 +19,8 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.annotation; import com.intellij.lang.ASTNode; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.PsiAnnotation; -import com.intellij.psi.PsiElement; import com.intellij.psi.PsiNameValuePair; +import com.intellij.psi.StubBasedPsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; @@ -29,18 +29,17 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationNameValuePair; -import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiElementImpl; +import org.jetbrains.plugins.groovy.lang.psi.impl.GrStubElementBase; +import org.jetbrains.plugins.groovy.lang.psi.stubs.GrAnnotationArgumentListStub; -import java.util.ArrayList; -import java.util.List; +public class GrAnnotationArgumentListImpl extends GrStubElementBase + implements GrAnnotationArgumentList, StubBasedPsiElement { -/** - * @author: Dmitry.Krasilschikov - * @date: 04.04.2007 - */ -public class GrAnnotationArgumentListImpl extends GroovyPsiElementImpl implements GrAnnotationArgumentList { - private static final Logger LOG = - Logger.getInstance("#org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.annotation.GrAnnotationArgumentListImpl"); + private static final Logger LOG = Logger.getInstance(GrAnnotationArgumentListImpl.class); + + public GrAnnotationArgumentListImpl(@NotNull GrAnnotationArgumentListStub stub) { + super(stub, GroovyElementTypes.ANNOTATION_ARGUMENTS); + } public GrAnnotationArgumentListImpl(@NotNull ASTNode node) { super(node); @@ -58,11 +57,7 @@ public class GrAnnotationArgumentListImpl extends GroovyPsiElementImpl implement @Override @NotNull public GrAnnotationNameValuePair[] getAttributes() { - List result = new ArrayList<>(); - for (PsiElement cur = getFirstChild(); cur != null; cur = cur.getNextSibling()) { - if (cur instanceof GrAnnotationNameValuePair) result.add((GrAnnotationNameValuePair)cur); - } - return result.toArray(new GrAnnotationNameValuePair[result.size()]); + return getStubOrPsiChildren(GroovyElementTypes.ANNOTATION_MEMBER_VALUE_PAIR, GrAnnotationNameValuePair.EMPTY_ARRAY); } @Override @@ -100,5 +95,4 @@ public class GrAnnotationArgumentListImpl extends GroovyPsiElementImpl implement return super.addInternal(first, last, anchor, before); } - } diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationImpl.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationImpl.java index b82f7dbce2c4..c2ed34ca81ea 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationImpl.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationImpl.java @@ -18,13 +18,11 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.annotation; import com.intellij.codeInsight.AnnotationTargetUtil; import com.intellij.lang.ASTNode; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.impl.PsiImplUtil; import com.intellij.psi.impl.light.LightClassReference; import com.intellij.psi.meta.PsiMetaData; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.PairFunction; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -53,7 +51,6 @@ import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; * @date: 04.04.2007 */ public class GrAnnotationImpl extends GrStubElementBase implements GrAnnotation, StubBasedPsiElement { - private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.annotation.GrAnnotationImpl"); private static final PairFunction ANNOTATION_CREATOR = (project, text) -> GroovyPsiElementFactory.getInstance(project).createAnnotationFromText(text); @@ -78,7 +75,7 @@ public class GrAnnotationImpl extends GrStubElementBase implem @Override @NotNull public GrAnnotationArgumentList getParameterList() { - return findNotNullChildByClass(GrAnnotationArgumentList.class); + return getRequiredStubOrPsiChild(GroovyElementTypes.ANNOTATION_ARGUMENTS); } @Override @@ -99,7 +96,7 @@ public class GrAnnotationImpl extends GrStubElementBase implem @Override @Nullable public PsiJavaCodeReferenceElement getNameReferenceElement() { - final GroovyResolveResult resolveResult = resolveWithStub(); + final GroovyResolveResult resolveResult = getClassReference().advancedResolve(); final PsiElement resolved = resolveResult.getElement(); if (!(resolved instanceof PsiClass)) return null; @@ -107,40 +104,21 @@ public class GrAnnotationImpl extends GrStubElementBase implem return new LightClassReference(getManager(), getClassReference().getText(), (PsiClass)resolved, resolveResult.getSubstitutor()); } - @NotNull - private GroovyResolveResult resolveWithStub() { - final GrAnnotationStub stub = getStub(); - final GrCodeReferenceElement reference = stub != null ? stub.getPsiElement().getClassReference() : getClassReference(); - return reference.advancedResolve(); - } - @Override @Nullable public PsiAnnotationMemberValue findAttributeValue(@Nullable String attributeName) { - final GrAnnotationStub stub = getStub(); - if (stub != null) { - final GrAnnotation stubbedPsi = stub.getPsiElement(); - final PsiAnnotationMemberValue value = PsiImplUtil.findAttributeValue(stubbedPsi, attributeName); - if (value == null || !PsiTreeUtil.isAncestor(stubbedPsi, value, true)) { // if value is a default value we can use it - return value; - } - } return PsiImplUtil.findAttributeValue(this, attributeName); } @Override @Nullable public PsiAnnotationMemberValue findDeclaredAttributeValue(@NonNls final String attributeName) { - final GrAnnotationStub stub = getStub(); - if (stub != null) { - final GrAnnotation stubbedPsi = stub.getPsiElement(); - return PsiImplUtil.findDeclaredAttributeValue(stubbedPsi, attributeName); - } return PsiImplUtil.findDeclaredAttributeValue(this, attributeName); } @Override public T setDeclaredAttributeValue(@Nullable @NonNls String attributeName, T value) { + //noinspection unchecked return (T)PsiImplUtil.setDeclaredAttributeValue(this, attributeName, value, ANNOTATION_CREATOR); } diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java index 28bf0c202e1d..f7d9a16ce5b7 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java @@ -27,6 +27,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; +import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; @@ -34,19 +35,22 @@ import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation. import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationMemberValue; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationNameValuePair; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; -import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiElementImpl; +import org.jetbrains.plugins.groovy.lang.psi.impl.GrStubElementBase; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.modifiers.GrAnnotationCollector; +import org.jetbrains.plugins.groovy.lang.psi.stubs.GrNameValuePairStub; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; import java.util.List; -/** - * @author: Dmitry.Krasilschikov - * @date: 04.04.2007 - */ -public class GrAnnotationNameValuePairImpl extends GroovyPsiElementImpl implements GrAnnotationNameValuePair, PsiPolyVariantReference { +public class GrAnnotationNameValuePairImpl extends GrStubElementBase + implements GrAnnotationNameValuePair, PsiPolyVariantReference, StubBasedPsiElement { + + public GrAnnotationNameValuePairImpl(@NotNull GrNameValuePairStub stub) { + super(stub, GroovyElementTypes.ANNOTATION_MEMBER_VALUE_PAIR); + } + public GrAnnotationNameValuePairImpl(@NotNull ASTNode node) { super(node); } @@ -63,6 +67,10 @@ public class GrAnnotationNameValuePairImpl extends GroovyPsiElementImpl implemen @Override @Nullable public String getName() { + GrNameValuePairStub stub = getStub(); + if (stub != null) { + return stub.getName(); + } final PsiElement nameId = getNameIdentifierGroovy(); return nameId != null ? nameId.getText() : null; } diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrAnnotationArgumentListElementType.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrAnnotationArgumentListElementType.java new file mode 100644 index 000000000000..866bdb0f812d --- /dev/null +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrAnnotationArgumentListElementType.java @@ -0,0 +1,59 @@ +/* + * Copyright 2000-2016 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.plugins.groovy.lang.psi.stubs.elements; + +import com.intellij.psi.stubs.StubElement; +import com.intellij.psi.stubs.StubInputStream; +import com.intellij.psi.stubs.StubOutputStream; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationArgumentList; +import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.annotation.GrAnnotationArgumentListImpl; +import org.jetbrains.plugins.groovy.lang.psi.stubs.GrAnnotationArgumentListStub; + +import java.io.IOException; + +public class GrAnnotationArgumentListElementType extends GrStubElementType { + + public GrAnnotationArgumentListElementType() { + super("annotation arguments"); + } + + @Override + public boolean isLeftBound() { + return true; + } + + @Override + public void serialize(@NotNull GrAnnotationArgumentListStub stub, @NotNull StubOutputStream dataStream) throws IOException { + } + + @NotNull + @Override + public GrAnnotationArgumentListStub deserialize(@NotNull StubInputStream dataStream, StubElement parentStub) throws IOException { + return new GrAnnotationArgumentListStub(parentStub); + } + + @Override + public GrAnnotationArgumentList createPsi(@NotNull GrAnnotationArgumentListStub stub) { + return new GrAnnotationArgumentListImpl(stub); + } + + @NotNull + @Override + public GrAnnotationArgumentListStub createStub(@NotNull GrAnnotationArgumentList psi, StubElement parentStub) { + return new GrAnnotationArgumentListStub(parentStub); + } +} diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrNameValuePairElementType.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrNameValuePairElementType.java new file mode 100644 index 000000000000..8727dcd20ea8 --- /dev/null +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrNameValuePairElementType.java @@ -0,0 +1,70 @@ +/* + * Copyright 2000-2016 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.plugins.groovy.lang.psi.stubs.elements; + +import com.intellij.psi.stubs.StubElement; +import com.intellij.psi.stubs.StubInputStream; +import com.intellij.psi.stubs.StubOutputStream; +import com.intellij.util.io.StringRef; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationMemberValue; +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationNameValuePair; +import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.annotation.GrAnnotationNameValuePairImpl; +import org.jetbrains.plugins.groovy.lang.psi.stubs.GrNameValuePairStub; + +import java.io.IOException; + +@SuppressWarnings("Duplicates") +public class GrNameValuePairElementType extends GrStubElementType { + + public GrNameValuePairElementType() { + super("Annotation name value pair"); + } + + @Override + public void serialize(@NotNull GrNameValuePairStub stub, @NotNull StubOutputStream dataStream) throws IOException { + dataStream.writeName(stub.getName()); + String value = stub.getValue(); + boolean hasValue = value != null; + dataStream.writeBoolean(hasValue); + if (hasValue) { + dataStream.writeUTFFast(value); + } + } + + @NotNull + @Override + public GrNameValuePairStub deserialize(@NotNull StubInputStream dataStream, StubElement parentStub) throws IOException { + return new GrNameValuePairStub( + parentStub, + StringRef.toString(dataStream.readName()), + dataStream.readBoolean() ? dataStream.readUTFFast() : null + ); + } + + @Override + public GrAnnotationNameValuePair createPsi(@NotNull GrNameValuePairStub stub) { + return new GrAnnotationNameValuePairImpl(stub); + } + + @NotNull + @Override + public GrNameValuePairStub createStub(@NotNull GrAnnotationNameValuePair psi, StubElement parentStub) { + String name = psi.getName(); + GrAnnotationMemberValue value = psi.getValue(); + return new GrNameValuePairStub(parentStub, name, value == null ? null : value.getText()); + } +} diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrStubFileElementType.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrStubFileElementType.java index a76f36e60f8c..829e6d02c2e5 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrStubFileElementType.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/elements/GrStubFileElementType.java @@ -40,7 +40,7 @@ import java.io.IOException; * @author ilyas */ public class GrStubFileElementType extends IStubFileElementType { - public static final int STUB_VERSION = 30; + public static final int STUB_VERSION = 31; public GrStubFileElementType(Language language) { super(language); diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/stubs.kt b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/stubs.kt new file mode 100644 index 000000000000..2508e5c57e4b --- /dev/null +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/stubs/stubs.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2000-2016 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.plugins.groovy.lang.psi.stubs + +import com.intellij.psi.stubs.StubBase +import com.intellij.psi.stubs.StubElement +import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes.ANNOTATION_ARGUMENTS +import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes.ANNOTATION_MEMBER_VALUE_PAIR +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationArgumentList +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationNameValuePair + +class GrNameValuePairStub(parent: StubElement<*>?, val name: String?, val value: String?) +: StubBase(parent, ANNOTATION_MEMBER_VALUE_PAIR) + +class GrAnnotationArgumentListStub(parent: StubElement<*>?) +: StubBase(parent, ANNOTATION_ARGUMENTS) diff --git a/plugins/groovy/testdata/groovy/stubs/typeParameters.test b/plugins/groovy/testdata/groovy/stubs/typeParameters.test index 858cf40ab484..1744a5a41a6c 100644 --- a/plugins/groovy/testdata/groovy/stubs/typeParameters.test +++ b/plugins/groovy/testdata/groovy/stubs/typeParameters.test @@ -1,4 +1,4 @@ -@Anno class Stub { +@Anno(a=b) class Stub { def T foo() {} } ----- @@ -6,6 +6,8 @@ [Class definition : Stub] [Modifiers] [Annotation] + [Annotation arguments] + [Annotation member value pair] [Type parameter list] [Type parameter : A] [Type parameter : B]