[groovy] stubs for annotation argument list and name value pairs (IDEA-CR-14566)

This commit is contained in:
Daniil Ovchinnikov
2016-10-17 22:52:42 +03:00
parent 9632a62f40
commit c9efc8f6be
9 changed files with 193 additions and 53 deletions
@@ -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<GrAnnotationStub, GrAnnotation> ANNOTATION = new GrAnnotationElementType("annotation");
//parameters
@@ -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<GrAnnotationArgumentListStub>
implements GrAnnotationArgumentList, StubBasedPsiElement<GrAnnotationArgumentListStub> {
/**
* @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<GrAnnotationNameValuePair> 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);
}
}
@@ -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<GrAnnotationStub> implements GrAnnotation, StubBasedPsiElement<GrAnnotationStub> {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.annotation.GrAnnotationImpl");
private static final PairFunction<Project, String, PsiAnnotation> ANNOTATION_CREATOR =
(project, text) -> GroovyPsiElementFactory.getInstance(project).createAnnotationFromText(text);
@@ -78,7 +75,7 @@ public class GrAnnotationImpl extends GrStubElementBase<GrAnnotationStub> 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<GrAnnotationStub> 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<GrAnnotationStub> 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 extends PsiAnnotationMemberValue> T setDeclaredAttributeValue(@Nullable @NonNls String attributeName, T value) {
//noinspection unchecked
return (T)PsiImplUtil.setDeclaredAttributeValue(this, attributeName, value, ANNOTATION_CREATOR);
}
@@ -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<GrNameValuePairStub>
implements GrAnnotationNameValuePair, PsiPolyVariantReference, StubBasedPsiElement<GrNameValuePairStub> {
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;
}
@@ -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<GrAnnotationArgumentListStub, GrAnnotationArgumentList> {
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);
}
}
@@ -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<GrNameValuePairStub, GrAnnotationNameValuePair> {
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());
}
}
@@ -40,7 +40,7 @@ import java.io.IOException;
* @author ilyas
*/
public class GrStubFileElementType extends IStubFileElementType<GrFileStub> {
public static final int STUB_VERSION = 30;
public static final int STUB_VERSION = 31;
public GrStubFileElementType(Language language) {
super(language);
@@ -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<GrAnnotationNameValuePair>(parent, ANNOTATION_MEMBER_VALUE_PAIR)
class GrAnnotationArgumentListStub(parent: StubElement<*>?)
: StubBase<GrAnnotationArgumentList>(parent, ANNOTATION_ARGUMENTS)
+3 -1
View File
@@ -1,4 +1,4 @@
@Anno class Stub<A,B> {
@Anno(a=b) class Stub<A,B> {
def <T> 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]