blob: dd209edac517451374d07b2ebfaad35f4ff9b62c [file] [log] [blame]
/*
* Copyright 2000-2014 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.impl.synthetic;
import com.intellij.lang.Language;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.light.LightClassReference;
import com.intellij.psi.impl.light.LightElement;
import com.intellij.psi.meta.PsiMetaData;
import com.intellij.util.containers.ContainerUtilRt;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
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;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationArgumentList;
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.AnnotationArgConverter;
import java.util.List;
/**
* @author Max Medvedev
*/
public class GrLightAnnotation extends LightElement implements GrAnnotation {
private final GrLightAnnotationArgumentList myAnnotationArgList;
private final String myQualifiedName;
private final PsiAnnotationOwner myOwner;
private final GrLightClassReferenceElement myRef;
public GrLightAnnotation(@NotNull PsiManager manager,
@NotNull Language language,
@NotNull String qualifiedName,
@NotNull PsiAnnotationOwner owner) {
super(manager, language);
myQualifiedName = qualifiedName;
myOwner = owner;
myAnnotationArgList = new GrLightAnnotationArgumentList(manager, language);
myRef = new GrLightClassReferenceElement(qualifiedName, qualifiedName, this);
}
@NotNull
@Override
public GrCodeReferenceElement getClassReference() {
return myRef;
}
@NotNull
@Override
public String getShortName() {
return StringUtil.getShortName(myQualifiedName);
}
@NotNull
@Override
public GrAnnotationArgumentList getParameterList() {
return myAnnotationArgList;
}
@Override
public void accept(GroovyElementVisitor visitor) {
visitor.visitAnnotation(this);
}
@Override
public void acceptChildren(GroovyElementVisitor visitor) {
//todo
}
@Override
public String toString() {
return "light groovy annotation";
}
@Override
public String getText() {
return "@" + myQualifiedName + myAnnotationArgList.getText();
}
@Override
public String getQualifiedName() {
return myQualifiedName;
}
@Override
public PsiJavaCodeReferenceElement getNameReferenceElement() {
final GroovyResolveResult resolveResult = myRef.advancedResolve();
final PsiElement resolved = resolveResult.getElement();
if (resolved instanceof PsiClass) {
return new LightClassReference(getManager(), getClassReference().getText(), (PsiClass)resolved, resolveResult.getSubstitutor());
}
else {
return null;
}
}
@Override
public PsiAnnotationMemberValue findAttributeValue(@NonNls String attributeName) {
return PsiImplUtil.findAttributeValue(this, attributeName);
}
@Override
public PsiAnnotationMemberValue findDeclaredAttributeValue(@NonNls String attributeName) {
return PsiImplUtil.findDeclaredAttributeValue(this, attributeName);
}
@Override
public <T extends PsiAnnotationMemberValue> T setDeclaredAttributeValue(@NonNls String attributeName, @Nullable T value) {
throw new UnsupportedOperationException("light annotation does not support changes");
}
@Override
public PsiAnnotationOwner getOwner() {
return myOwner;
}
@Override
public PsiMetaData getMetaData() {
return null;
}
public void addAttribute(PsiNameValuePair pair) {
if (pair instanceof GrAnnotationNameValuePair) {
myAnnotationArgList.addAttribute((GrAnnotationNameValuePair)pair);
}
else {
GrAnnotationMemberValue newValue = new AnnotationArgConverter().convert(pair.getValue());
if (newValue == null) return;
String name = pair.getName();
GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(pair.getProject());
String annotationText;
annotationText = name != null ? "@A(" + name + "=" + newValue.getText() + ")"
: "@A(" + newValue.getText() + ")";
GrAnnotation annotation = factory.createAnnotationFromText(annotationText);
myAnnotationArgList.addAttribute(annotation.getParameterList().getAttributes()[0]);
}
}
private class GrLightAnnotationArgumentList extends LightElement implements GrAnnotationArgumentList {
private List<GrAnnotationNameValuePair> myAttributes = null;
private GrAnnotationNameValuePair[] myCachedAttributes = GrAnnotationNameValuePair.EMPTY_ARRAY;
@Override
public PsiElement getContext() {
return GrLightAnnotation.this;
}
private GrLightAnnotationArgumentList(@NotNull PsiManager manager, @NotNull Language language) {
super(manager, language);
}
@NotNull
@Override
public GrAnnotationNameValuePair[] getAttributes() {
if (myCachedAttributes == null) {
assert myAttributes != null;
myCachedAttributes = myAttributes.toArray(new GrAnnotationNameValuePair[myAttributes.size()]);
}
return myCachedAttributes;
}
public void addAttribute(@NotNull GrAnnotationNameValuePair attribute) {
if (myAttributes == null) myAttributes = ContainerUtilRt.newArrayList();
myAttributes.add(attribute);
myCachedAttributes = null;
}
@Override
public void accept(GroovyElementVisitor visitor) {
visitor.visitAnnotationArgumentList(this);
}
@Override
public void acceptChildren(GroovyElementVisitor visitor) {
if (myAttributes != null) {
for (GrAnnotationNameValuePair attribute : myAttributes) {
attribute.accept(visitor);
}
}
}
@Override
public String toString() {
return "light annotation argument list";
}
@Override
public String getText() {
if (myAttributes == null || myAttributes.isEmpty()) return "";
StringBuilder buffer = new StringBuilder();
buffer.append('(');
for (GrAnnotationNameValuePair attribute : myAttributes) {
buffer.append(attribute.getText());
buffer.append(',');
}
if (!myAttributes.isEmpty()) buffer.deleteCharAt(buffer.length() - 1);
buffer.append(')');
return buffer.toString();
}
}
}