IDEA-117584 more stubs for annotations

This commit is contained in:
Max Medvedev
2013-12-09 12:16:04 +04:00
parent 9207b87b99
commit 515ef7a755
8 changed files with 227 additions and 44 deletions
@@ -37,7 +37,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEn
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeParameterList;
import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.annotation.GrAnnotationImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.GrVariableDeclarationImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.blocks.GrBlockImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.blocks.GrClosableBlockImpl;
@@ -308,29 +307,7 @@ public interface GroovyElementTypes extends GroovyTokenTypes, GroovyDocElementTy
GroovyElementType ANNOTATION_ARGUMENTS = new GroovyElementType("annotation arguments");
GroovyElementType ANNOTATION_MEMBER_VALUE_PAIR = new GroovyElementType("annotation member value pair");
GrStubElementType<GrAnnotationStub, GrAnnotation> ANNOTATION = new GrStubElementType<GrAnnotationStub, GrAnnotation>("annotation") {
@Override
public GrAnnotation createPsi(@NotNull GrAnnotationStub stub) {
return new GrAnnotationImpl(stub);
}
@Override
public GrAnnotationStub createStub(@NotNull GrAnnotation psi, StubElement parentStub) {
return new GrAnnotationStub(parentStub, psi);
}
@Override
public void serialize(@NotNull GrAnnotationStub stub, @NotNull StubOutputStream dataStream) throws IOException {
dataStream.writeName(stub.getAnnotationName());
}
@NotNull
@Override
public GrAnnotationStub deserialize(@NotNull StubInputStream dataStream, StubElement parentStub) throws IOException {
return new GrAnnotationStub(parentStub, dataStream.readName());
}
};
GrStubElementType<GrAnnotationStub, GrAnnotation> ANNOTATION = new GrAnnotationElementType("annotation");
//parameters
EmptyStubElementType<GrParameterList> PARAMETERS_LIST = new EmptyStubElementType<GrParameterList>("parameters list", GroovyFileType.GROOVY_LANGUAGE) {
@Override
@@ -523,7 +523,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
@NotNull
@Override
public GrAnnotation createAnnotationFromText(@NotNull @NonNls String annotationText, @Nullable PsiElement context) throws IncorrectOperationException {
return createMethodFromText(annotationText + " void ___shdjklf_pqweirupncp_foo() {}", context).getModifierList().getAnnotations()[0];
return createMethodFromText(annotationText + " void ___shdjklf_pqweirupncp_foo() {}", context).getModifierList().getRawAnnotations()[0];
}
@Override
@@ -82,20 +82,34 @@ public class GrAnnotationImpl extends GrStubElementBase<GrAnnotationStub> implem
@NotNull
public GrAnnotationArgumentList getParameterList() {
final GrAnnotationStub stub = getStub();
if (stub != null) {
return stub.getPsiElement().getParameterList();
}
return findNotNullChildByClass(GrAnnotationArgumentList.class);
}
@Nullable
@NonNls
public String getQualifiedName() {
final GrAnnotationStub stub = getStub();
if (stub != null) {
return stub.getPsiElement().getQualifiedName();
}
final GrCodeReferenceElement nameRef = getClassReference();
final PsiElement resolved = nameRef.resolve();
if (resolved instanceof PsiClass) return ((PsiClass) resolved).getQualifiedName();
if (resolved instanceof PsiClass) return ((PsiClass)resolved).getQualifiedName();
return null;
}
@Nullable
public PsiJavaCodeReferenceElement getNameReferenceElement() {
final GrAnnotationStub stub = getStub();
if (stub != null) {
return stub.getPsiElement().getNameReferenceElement();
}
final GroovyResolveResult resolveResult = getClassReference().advancedResolve();
final PsiElement resolved = resolveResult.getElement();
@@ -107,6 +121,7 @@ public class GrAnnotationImpl extends GrStubElementBase<GrAnnotationStub> implem
}
}
@Nullable
public PsiAnnotationMemberValue findAttributeValue(@Nullable String attributeName) {
return PsiImplUtil.findAttributeValue(this, attributeName);
}
@@ -116,7 +131,7 @@ public class GrAnnotationImpl extends GrStubElementBase<GrAnnotationStub> implem
return PsiImplUtil.findDeclaredAttributeValue(this, attributeName);
}
public <T extends PsiAnnotationMemberValue> T setDeclaredAttributeValue(@Nullable @NonNls String attributeName, T value) {
public <T extends PsiAnnotationMemberValue> T setDeclaredAttributeValue(@Nullable @NonNls String attributeName, T value) {
return (T)PsiImplUtil.setDeclaredAttributeValue(this, attributeName, value, ANNOTATION_CREATOR);
}
@@ -127,6 +142,11 @@ public class GrAnnotationImpl extends GrStubElementBase<GrAnnotationStub> implem
@NotNull
public GrCodeReferenceElement getClassReference() {
final GrAnnotationStub stub = getStub();
if (stub != null) {
return stub.getPsiElement().getClassReference();
}
return findNotNullChildByClass(GrCodeReferenceElement.class);
}
@@ -134,13 +154,15 @@ public class GrAnnotationImpl extends GrStubElementBase<GrAnnotationStub> implem
public String getShortName() {
final GrAnnotationStub stub = getStub();
if (stub != null) {
return stub.getAnnotationName();
}
else {
return getClassReference().getReferenceName();
return stub.getPsiElement().getShortName();
}
final String referenceName = getClassReference().getReferenceName();
assert referenceName != null;
return referenceName;
}
@Nullable
public PsiAnnotationOwner getOwner() {
return (PsiAnnotationOwner)getParent();
}
@@ -42,6 +42,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinitionBody;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
@@ -85,7 +86,7 @@ public class GrVariableDeclarationImpl extends GrStubElementBase<EmptyStub> impl
@NotNull
public GrModifierList getModifierList() {
return (GrModifierList)findNotNullChildByType(GroovyElementTypes.MODIFIERS);
return getRequiredStubOrPsiChild(GroovyElementTypes.MODIFIERS);
}
@Override
@@ -192,7 +193,7 @@ public class GrVariableDeclarationImpl extends GrStubElementBase<EmptyStub> impl
@NotNull ResolveState state,
PsiElement lastParent,
@NotNull PsiElement place) {
if (lastParent != null && lastParent == getTupleInitializer()) {
if (lastParent != null && !(getParent() instanceof GrTypeDefinitionBody) && lastParent == getTupleInitializer()) {
return true;
}
@@ -1,28 +1,67 @@
/*
* Copyright 2000-2013 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.openapi.diagnostic.Logger;
import com.intellij.psi.stubs.StubBase;
import com.intellij.psi.stubs.StubElement;
import com.intellij.util.io.StringRef;
import com.intellij.reference.SoftReference;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation;
/**
* @author peter
*/
public class GrAnnotationStub extends StubBase<GrAnnotation> {
private final StringRef myReference;
private static final Logger LOG = Logger.getInstance(GrAnnotationStub.class);
public GrAnnotationStub(StubElement parent, StringRef reference) {
private final String myText;
private SoftReference<GrAnnotation> myPsiRef;
public GrAnnotationStub(StubElement parent, String text) {
super(parent, GroovyElementTypes.ANNOTATION);
myReference = reference;
myText = text;
}
public GrAnnotationStub(StubElement parent, GrAnnotation from) {
super(parent, GroovyElementTypes.ANNOTATION);
myReference = StringRef.fromString(from.getClassReference().getReferenceName());
myText = from.getText();
}
public String getAnnotationName() {
return myReference.getString();
public GrAnnotation getPsiElement() {
if (myPsiRef != null) {
final GrAnnotation annotation = myPsiRef.get();
if (annotation != null) {
return annotation;
}
}
try {
GrAnnotation annotation = GroovyPsiElementFactory.getInstance(getProject()).createAnnotationFromText(myText, getPsi());
myPsiRef = new SoftReference<GrAnnotation>(annotation);
return annotation;
}
catch (IncorrectOperationException e) {
LOG.error("Bad annotation in repository!", e);
return null;
}
}
public String getText() {
return myText;
}
}
@@ -0,0 +1,56 @@
/*
* Copyright 2000-2013 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.GrAnnotation;
import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.annotation.GrAnnotationImpl;
import org.jetbrains.plugins.groovy.lang.psi.stubs.GrAnnotationStub;
import java.io.IOException;
/**
* Created by Max Medvedev on 12/6/13
*/
public class GrAnnotationElementType extends GrStubElementType<GrAnnotationStub, GrAnnotation> {
public GrAnnotationElementType(@NotNull String name) {
super(name);
}
@Override
public GrAnnotation createPsi(@NotNull GrAnnotationStub stub) {
return new GrAnnotationImpl(stub);
}
@Override
public GrAnnotationStub createStub(@NotNull GrAnnotation psi, StubElement parentStub) {
return new GrAnnotationStub(parentStub, psi);
}
@Override
public void serialize(@NotNull GrAnnotationStub stub, @NotNull StubOutputStream dataStream) throws IOException {
dataStream.writeUTFFast(stub.getText());
}
@NotNull
@Override
public GrAnnotationStub deserialize(@NotNull StubInputStream dataStream, StubElement parentStub) throws IOException {
return new GrAnnotationStub(parentStub, dataStream.readUTFFast());
}
}
@@ -55,7 +55,7 @@ public class GrStubFileElementType extends IStubFileElementType<GrFileStub> {
@Override
public int getStubVersion() {
return super.getStubVersion() + 19;
return super.getStubVersion() + 20;
}
@NotNull
@@ -15,14 +15,19 @@
*/
package org.jetbrains.plugins.groovy.lang.psi
import com.intellij.psi.PsiClass
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import com.intellij.psi.*
import org.jetbrains.plugins.groovy.LightGroovyTestCase
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyFileImpl
/**
* Created by Max Medvedev on 12/4/13
*/
class GrStubAstSwitchTest extends LightCodeInsightFixtureTestCase {
class GrStubAstSwitchTest extends LightGroovyTestCase {
@Override
protected String getBasePath() {
null
}
void testDontLoadContentWhenProcessingImports() {
GroovyFileImpl file = (GroovyFileImpl) myFixture.addFileToProject("A.groovy", """
import java.util.concurrent.ConcurrentHashMap
@@ -44,4 +49,87 @@ class B extends ConcurrentHashMap {
fooMethod.findDeepestSuperMethods()
assert !file.contentsLoaded
}
void testDontLoadAstForAnnotation() {
GroovyFileImpl file = myFixture.addFileToProject('a.groovy', '''\
class A {
def foo(){}
}
class B {
@Delegate
A a = new A()
}
''') as GroovyFileImpl
assert !file.contentsLoaded
PsiClass clazzB = file.classes[1]
assert !file.contentsLoaded
PsiField field = clazzB.fields[0]
assert !file.contentsLoaded
PsiModifierList modifierList = field.modifierList
assert !file.contentsLoaded
PsiAnnotation[] annotations = modifierList.annotations
PsiAnnotation annotation = annotations[0]
assert !file.contentsLoaded
assert annotation.qualifiedName == 'groovy.lang.Delegate'
assert !file.contentsLoaded
}
void testDontLoadAstForAnnotation2() {
GroovyFileImpl file = myFixture.addFileToProject('a.groovy', '''\
class A {
def foo(){}
}
class B extends A {
@Override
def foo() {}
}
''') as GroovyFileImpl
assert !file.contentsLoaded
PsiClass clazzB = file.classes[1]
assert !file.contentsLoaded
PsiMethod method = clazzB.methods[0]
assert !file.contentsLoaded
PsiModifierList modifierList = method.modifierList
assert !file.contentsLoaded
PsiAnnotation[] annotations = modifierList.annotations
PsiAnnotation annotation = annotations[0]
assert !file.contentsLoaded
assert annotation.qualifiedName == "java.lang.Override"
assert !file.contentsLoaded
}
void testDelegateExists() {
GroovyFileImpl file = myFixture.addFileToProject('a.groovy', '''\
class A {
def foo(){}
}
class B {
@Delegate
A a = new A()
}
''') as GroovyFileImpl
assert !file.contentsLoaded
PsiClass clazzB = file.classes[1]
assert !file.contentsLoaded
assert clazzB.methods.find {it.name =='foo'}
assert !file.contentsLoaded
}
}