mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -143,40 +143,66 @@ public class JavaDocInfoGenerator {
|
||||
}
|
||||
|
||||
interface DocTagLocator <T> {
|
||||
T find(PsiDocComment comment);
|
||||
T find(PsiDocCommentOwner owner, PsiDocComment comment);
|
||||
}
|
||||
|
||||
private static DocTagLocator<PsiDocTag> parameterLocator(final String name) {
|
||||
private static DocTagLocator<PsiDocTag> parameterLocator(final int parameterIndex) {
|
||||
return new DocTagLocator<PsiDocTag>() {
|
||||
@Override
|
||||
public PsiDocTag find(PsiDocComment comment) {
|
||||
if (comment == null) {
|
||||
return null;
|
||||
}
|
||||
public PsiDocTag find(PsiDocCommentOwner owner, PsiDocComment comment) {
|
||||
if (parameterIndex < 0 || comment == null || !(owner instanceof PsiMethod)) return null;
|
||||
|
||||
PsiDocTag[] tags = comment.findTagsByName("param");
|
||||
|
||||
for (PsiDocTag tag : tags) {
|
||||
PsiDocTagValue value = tag.getValueElement();
|
||||
|
||||
if (value != null) {
|
||||
String text = value.getText();
|
||||
|
||||
if (text != null && text.equals(name)) {
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
PsiParameter[] parameters = ((PsiMethod)owner).getParameterList().getParameters();
|
||||
if (parameterIndex >= parameters.length) return null;
|
||||
|
||||
String name = parameters[parameterIndex].getName();
|
||||
return getParamTagByName(comment, name);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static DocTagLocator<PsiDocTag> typeParameterLocator(final int parameterIndex) {
|
||||
return new DocTagLocator<PsiDocTag>() {
|
||||
@Override
|
||||
public PsiDocTag find(PsiDocCommentOwner owner, PsiDocComment comment) {
|
||||
if (parameterIndex < 0 || comment == null || !(owner instanceof PsiTypeParameterListOwner)) return null;
|
||||
|
||||
PsiTypeParameter[] parameters = ((PsiTypeParameterListOwner)owner).getTypeParameters();
|
||||
if (parameterIndex >= parameters.length) return null;
|
||||
|
||||
String rawName = parameters[parameterIndex].getName();
|
||||
if (rawName == null) return null;
|
||||
String name = "<" + rawName + ">";
|
||||
return getParamTagByName(comment, name);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static PsiDocTag getParamTagByName(@NotNull PsiDocComment comment, String name) {
|
||||
PsiDocTag[] tags = comment.findTagsByName("param");
|
||||
return getTagByName(tags, name);
|
||||
}
|
||||
|
||||
private static PsiDocTag getTagByName(@NotNull PsiDocTag[] tags, String name) {
|
||||
for (PsiDocTag tag : tags) {
|
||||
PsiDocTagValue value = tag.getValueElement();
|
||||
|
||||
if (value != null) {
|
||||
String text = value.getText();
|
||||
|
||||
if (text != null && text.equals(name)) {
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static DocTagLocator<PsiDocTag> exceptionLocator(final String name) {
|
||||
return new DocTagLocator<PsiDocTag>() {
|
||||
@Override
|
||||
public PsiDocTag find(PsiDocComment comment) {
|
||||
public PsiDocTag find(PsiDocCommentOwner owner, PsiDocComment comment) {
|
||||
if (comment == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -467,23 +493,24 @@ public class JavaDocInfoGenerator {
|
||||
}
|
||||
|
||||
private void generateTypeParametersSection(final StringBuilder buffer, final PsiClass aClass) {
|
||||
final LinkedList<Pair<PsiDocTag, InheritDocProvider<PsiDocTag>>> result =
|
||||
new LinkedList<Pair<PsiDocTag, InheritDocProvider<PsiDocTag>>>();
|
||||
final LinkedList<ParamInfo> result = new LinkedList<ParamInfo>();
|
||||
final PsiTypeParameter[] typeParameters = aClass.getTypeParameters();
|
||||
for (PsiTypeParameter typeParameter : typeParameters) {
|
||||
final DocTagLocator<PsiDocTag> locator = parameterLocator("<" + typeParameter.getName() + ">");
|
||||
for (int i = 0; i < typeParameters.length; i++) {
|
||||
PsiTypeParameter typeParameter = typeParameters[i];
|
||||
String name = "<" + typeParameter.getName() + ">";
|
||||
final DocTagLocator<PsiDocTag> locator = typeParameterLocator(i);
|
||||
final Pair<PsiDocTag, InheritDocProvider<PsiDocTag>> inClassComment = findInClassComment(aClass, locator);
|
||||
if (inClassComment != null) {
|
||||
result.add(inClassComment);
|
||||
result.add(new ParamInfo(name, inClassComment));
|
||||
}
|
||||
else {
|
||||
final Pair<PsiDocTag, InheritDocProvider<PsiDocTag>> pair = findInHierarchy(aClass, locator);
|
||||
if (pair != null) {
|
||||
result.add(pair);
|
||||
result.add(new ParamInfo(name, pair));
|
||||
}
|
||||
}
|
||||
}
|
||||
generateTypeParametersSection(buffer, result);
|
||||
generateParametersSection(buffer, CodeInsightBundle.message("javadoc.type.parameters"), result);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -500,7 +527,7 @@ public class JavaDocInfoGenerator {
|
||||
}
|
||||
|
||||
private static Pair<PsiDocTag, InheritDocProvider<PsiDocTag>> findInClassComment(final PsiClass psiClass, final DocTagLocator<PsiDocTag> locator) {
|
||||
final PsiDocTag tag = locator.find(getDocComment(psiClass));
|
||||
final PsiDocTag tag = locator.find(psiClass, getDocComment(psiClass));
|
||||
if (tag != null) {
|
||||
return new Pair<PsiDocTag, InheritDocProvider<PsiDocTag>>(tag, new InheritDocProvider<PsiDocTag>() {
|
||||
@Override
|
||||
@@ -541,17 +568,7 @@ public class JavaDocInfoGenerator {
|
||||
if (generatePrologueAndEpilogue)
|
||||
generatePrologue(buffer);
|
||||
|
||||
PsiClass parentClass = field.getContainingClass();
|
||||
if (parentClass != null) {
|
||||
String qName = parentClass.getQualifiedName();
|
||||
if (qName != null) {
|
||||
buffer.append("<small><b>");
|
||||
//buffer.append(qName);
|
||||
generateLink(buffer, qName, qName, field, false);
|
||||
buffer.append("</b></small>");
|
||||
//buffer.append("<br>");
|
||||
}
|
||||
}
|
||||
generateLinkToParentIfNeeded(buffer, field);
|
||||
|
||||
buffer.append("<PRE>");
|
||||
generateFieldSignature(buffer, field, true);
|
||||
@@ -929,8 +946,11 @@ public class JavaDocInfoGenerator {
|
||||
}
|
||||
|
||||
private void generateMethodParameterJavaDoc(@NonNls StringBuilder buffer, PsiParameter parameter, boolean generatePrologueAndEpilogue) {
|
||||
if (generatePrologueAndEpilogue)
|
||||
String parameterName = parameter.getName();
|
||||
|
||||
if (generatePrologueAndEpilogue) {
|
||||
generatePrologue(buffer);
|
||||
}
|
||||
|
||||
buffer.append("<PRE>");
|
||||
String modifiers = PsiFormatUtil.formatModifiers(parameter, PsiFormatUtilBase.JAVADOC_MODIFIERS_ONLY);
|
||||
@@ -942,7 +962,7 @@ public class JavaDocInfoGenerator {
|
||||
generateType(buffer, parameter.getType(), parameter);
|
||||
buffer.append(" ");
|
||||
buffer.append("<b>");
|
||||
buffer.append(parameter.getName());
|
||||
buffer.append(parameterName);
|
||||
appendInitializer(buffer, parameter);
|
||||
buffer.append("</b>");
|
||||
buffer.append("</PRE>");
|
||||
@@ -950,14 +970,14 @@ public class JavaDocInfoGenerator {
|
||||
final PsiElement method = PsiTreeUtil.getParentOfType(parameter, PsiMethod.class, PsiLambdaExpression.class);
|
||||
|
||||
if (method instanceof PsiMethod) {
|
||||
final PsiDocComment docComment = getDocComment((PsiMethod)method);
|
||||
PsiMethod psiMethod = (PsiMethod)method;
|
||||
final PsiDocComment docComment = getDocComment(psiMethod);
|
||||
final PsiDocTag[] localTags = docComment != null ? docComment.getTags() : PsiDocTag.EMPTY_ARRAY;
|
||||
final Pair<PsiDocTag, InheritDocProvider<PsiDocTag>> tagInfoProvider =
|
||||
findDocTag(localTags, parameter.getName(), (PsiMethod)method);
|
||||
int parameterIndex = psiMethod.getParameterList().getParameterIndex(parameter);
|
||||
final ParamInfo tagInfoProvider = findDocTag(localTags, parameterName, psiMethod, parameterLocator(parameterIndex));
|
||||
|
||||
if (tagInfoProvider != null) {
|
||||
PsiElement[] elements = tagInfoProvider.first.getDataElements();
|
||||
if (elements.length != 0) generateOneParameter(elements, buffer, tagInfoProvider);
|
||||
generateOneParameter(buffer, tagInfoProvider);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -969,17 +989,7 @@ public class JavaDocInfoGenerator {
|
||||
if (generatePrologueAndEpilogue)
|
||||
generatePrologue(buffer);
|
||||
|
||||
PsiClass parentClass = method.getContainingClass();
|
||||
if (parentClass != null) {
|
||||
String qName = parentClass.getQualifiedName();
|
||||
if (qName != null) {
|
||||
buffer.append("<small><b>");
|
||||
generateLink(buffer, qName, qName, method, false);
|
||||
//buffer.append(qName);
|
||||
buffer.append("</b></small>");
|
||||
//buffer.append("<br>");
|
||||
}
|
||||
}
|
||||
generateLinkToParentIfNeeded(buffer, method);
|
||||
|
||||
buffer.append("<PRE>");
|
||||
generateMethodSignature(buffer, method, true, false);
|
||||
@@ -999,7 +1009,7 @@ public class JavaDocInfoGenerator {
|
||||
}
|
||||
|
||||
generateParametersSection(buffer, method, comment);
|
||||
generateTypeParametersSection(buffer, method);
|
||||
generateTypeParametersSection(buffer, method, comment);
|
||||
generateReturnsSection(buffer, method, comment);
|
||||
generateThrowsSection(buffer, method, comment);
|
||||
|
||||
@@ -1013,6 +1023,18 @@ public class JavaDocInfoGenerator {
|
||||
generateEpilogue(buffer);
|
||||
}
|
||||
|
||||
private static void generateLinkToParentIfNeeded(StringBuilder buffer, PsiMember member) {
|
||||
PsiClass parentClass = member.getContainingClass();
|
||||
if (parentClass != null) {
|
||||
String qName = parentClass.getQualifiedName();
|
||||
if (qName != null) {
|
||||
buffer.append("<small><b>");
|
||||
generateLink(buffer, qName, qName, member, false);
|
||||
buffer.append("</b></small>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void generateMethodSignature(StringBuilder buffer, PsiMethod method, boolean generateLink, boolean useShortNames) {
|
||||
generateAnnotations(buffer, method, generateLink, true, useShortNames);
|
||||
String modifiers = PsiFormatUtil.formatModifiers(method, PsiFormatUtilBase.JAVADOC_MODIFIERS_ONLY);
|
||||
@@ -1218,7 +1240,7 @@ public class JavaDocInfoGenerator {
|
||||
private void generateMethodDescription(@NonNls StringBuilder buffer, final PsiMethod method, final PsiDocComment comment) {
|
||||
final DocTagLocator<PsiElement[]> descriptionLocator = new DocTagLocator<PsiElement[]>() {
|
||||
@Override
|
||||
public PsiElement[] find(PsiDocComment comment) {
|
||||
public PsiElement[] find(PsiDocCommentOwner owner, PsiDocComment comment) {
|
||||
if (comment == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -1537,113 +1559,86 @@ public class JavaDocInfoGenerator {
|
||||
PsiParameter[] params = method.getParameterList().getParameters();
|
||||
PsiDocTag[] localTags = comment != null ? comment.findTagsByName("param") : PsiDocTag.EMPTY_ARRAY;
|
||||
|
||||
LinkedList<Pair<PsiDocTag, InheritDocProvider<PsiDocTag>>> collectedTags =
|
||||
new LinkedList<Pair<PsiDocTag, InheritDocProvider<PsiDocTag>>>();
|
||||
LinkedList<ParamInfo> collectedTags = new LinkedList<ParamInfo>();
|
||||
|
||||
for (PsiParameter param : params) {
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
PsiParameter param = params[i];
|
||||
final String paramName = param.getName();
|
||||
Pair<PsiDocTag, InheritDocProvider<PsiDocTag>> parmTag = findDocTag(localTags, paramName, method);
|
||||
DocTagLocator<PsiDocTag> tagLocator = parameterLocator(i);
|
||||
ParamInfo parmTag = findDocTag(localTags, paramName, method, tagLocator);
|
||||
|
||||
if (parmTag != null) {
|
||||
collectedTags.addLast(parmTag);
|
||||
}
|
||||
}
|
||||
|
||||
if (!collectedTags.isEmpty()) {
|
||||
buffer.append("<DD><DL>");
|
||||
buffer.append("<DT><b>").append(CodeInsightBundle.message("javadoc.parameters")).append("</b>");
|
||||
for (Pair<PsiDocTag, InheritDocProvider<PsiDocTag>> tag : collectedTags) {
|
||||
PsiElement[] elements = tag.first.getDataElements();
|
||||
if (elements.length == 0) continue;
|
||||
generateOneParameter(elements, buffer, tag);
|
||||
}
|
||||
buffer.append("</DD></DL></DD>");
|
||||
}
|
||||
generateParametersSection(buffer, CodeInsightBundle.message("javadoc.parameters"), collectedTags);
|
||||
}
|
||||
|
||||
private void generateTypeParametersSection(final StringBuilder buffer, final PsiMethod method) {
|
||||
final PsiDocComment docComment = method.getDocComment();
|
||||
if (docComment == null) return;
|
||||
final PsiDocTag[] localTags = docComment.findTagsByName("param");
|
||||
private void generateTypeParametersSection(final StringBuilder buffer, final PsiMethod method, PsiDocComment comment) {
|
||||
final PsiDocTag[] localTags = comment == null ? PsiDocTag.EMPTY_ARRAY : comment.findTagsByName("param");
|
||||
final PsiTypeParameter[] typeParameters = method.getTypeParameters();
|
||||
final LinkedList<Pair<PsiDocTag, InheritDocProvider<PsiDocTag>>> collectedTags = new LinkedList<Pair<PsiDocTag, InheritDocProvider<PsiDocTag>>>();
|
||||
for (PsiTypeParameter typeParameter : typeParameters) {
|
||||
final LinkedList<ParamInfo> collectedTags = new LinkedList<ParamInfo>();
|
||||
for (int i = 0; i < typeParameters.length; i++) {
|
||||
PsiTypeParameter typeParameter = typeParameters[i];
|
||||
final String paramName = "<" + typeParameter.getName() + ">";
|
||||
Pair<PsiDocTag, InheritDocProvider<PsiDocTag>> parmTag = findDocTag(localTags, paramName, method);
|
||||
DocTagLocator<PsiDocTag> tagLocator = typeParameterLocator(i);
|
||||
ParamInfo parmTag = findDocTag(localTags, paramName, method, tagLocator);
|
||||
|
||||
if (parmTag != null) {
|
||||
collectedTags.addLast(parmTag);
|
||||
}
|
||||
}
|
||||
generateTypeParametersSection(buffer, collectedTags);
|
||||
generateParametersSection(buffer, CodeInsightBundle.message("javadoc.type.parameters"), collectedTags);
|
||||
}
|
||||
|
||||
private void generateTypeParametersSection(final StringBuilder buffer, final LinkedList<Pair<PsiDocTag, InheritDocProvider<PsiDocTag>>> collectedTags) {
|
||||
private void generateParametersSection(StringBuilder buffer, String titleMessage, LinkedList<ParamInfo> collectedTags) {
|
||||
if (!collectedTags.isEmpty()) {
|
||||
buffer.append("<DD><DL>");
|
||||
buffer.append("<DT><b>").append(CodeInsightBundle.message("javadoc.type.parameters")).append("</b>");
|
||||
for (Pair<PsiDocTag, InheritDocProvider<PsiDocTag>> tag : collectedTags) {
|
||||
PsiElement[] elements = tag.first.getDataElements();
|
||||
if (elements.length == 0) continue;
|
||||
generateOneParameter(elements, buffer, tag);
|
||||
buffer.append("<DT><b>").append(titleMessage).append("</b>");
|
||||
for (ParamInfo tag : collectedTags) {
|
||||
generateOneParameter(buffer, tag);
|
||||
}
|
||||
buffer.append("</DD></DL></DD>");
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable private Pair<PsiDocTag, InheritDocProvider<PsiDocTag>> findDocTag(final PsiDocTag[] localTags,
|
||||
final String paramName,
|
||||
final PsiMethod method) {
|
||||
Pair<PsiDocTag, InheritDocProvider<PsiDocTag>> parmTag = null;
|
||||
for (PsiDocTag localTag : localTags) {
|
||||
PsiDocTagValue value = localTag.getValueElement();
|
||||
|
||||
if (value != null) {
|
||||
String tagName = value.getText();
|
||||
|
||||
if (tagName != null && tagName.equals(paramName)) {
|
||||
parmTag =
|
||||
new Pair<PsiDocTag, InheritDocProvider<PsiDocTag>>
|
||||
(localTag,
|
||||
new InheritDocProvider<PsiDocTag>() {
|
||||
@Override
|
||||
public Pair<PsiDocTag, InheritDocProvider<PsiDocTag>> getInheritDoc() {
|
||||
return findInheritDocTag(method, parameterLocator(paramName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiClass getElement() {
|
||||
return method.getContainingClass();
|
||||
}
|
||||
});
|
||||
break;
|
||||
@Nullable private ParamInfo findDocTag(final PsiDocTag[] localTags,
|
||||
final String paramName, final PsiMethod method, final DocTagLocator<PsiDocTag> tagLocator) {
|
||||
PsiDocTag localTag = getTagByName(localTags, paramName);
|
||||
if (localTag != null) {
|
||||
return new ParamInfo(paramName, localTag, new InheritDocProvider<PsiDocTag>() {
|
||||
@Override
|
||||
public Pair<PsiDocTag, InheritDocProvider<PsiDocTag>> getInheritDoc() {
|
||||
return findInheritDocTag(method, tagLocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (parmTag == null) {
|
||||
parmTag = findInheritDocTag(method, parameterLocator(paramName));
|
||||
@Override
|
||||
public PsiClass getElement() {
|
||||
return method.getContainingClass();
|
||||
}
|
||||
});
|
||||
}
|
||||
return parmTag;
|
||||
Pair<PsiDocTag, InheritDocProvider<PsiDocTag>> tag = findInheritDocTag(method, tagLocator);
|
||||
return tag == null ? null : new ParamInfo(paramName, tag);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
private void generateOneParameter(final PsiElement[] elements,
|
||||
final StringBuilder buffer,
|
||||
final Pair<PsiDocTag, InheritDocProvider<PsiDocTag>> tag) {
|
||||
private void generateOneParameter(StringBuilder buffer, ParamInfo tag) {
|
||||
PsiElement[] elements = tag.docTag.getDataElements();
|
||||
if (elements.length == 0) return;
|
||||
String text = elements[0].getText();
|
||||
buffer.append("<DD>");
|
||||
int spaceIndex = text.indexOf(' ');
|
||||
if (spaceIndex < 0) {
|
||||
spaceIndex = text.length();
|
||||
}
|
||||
String parmName = text.substring(0, spaceIndex);
|
||||
buffer.append("<code>");
|
||||
buffer.append(StringUtil.escapeXml(parmName));
|
||||
buffer.append(StringUtil.escapeXml(tag.name));
|
||||
buffer.append("</code>");
|
||||
buffer.append(" - ");
|
||||
buffer.append(text.substring(spaceIndex));
|
||||
generateValue(buffer, elements, 1, mapProvider(tag.second, true));
|
||||
generateValue(buffer, elements, 1, mapProvider(tag.inheritDocTagProvider, true));
|
||||
}
|
||||
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
@@ -2073,7 +2068,7 @@ public class JavaDocInfoGenerator {
|
||||
final PsiMethod overriden = findMethodInSuperClass(method, aSuper);
|
||||
|
||||
if (overriden != null) {
|
||||
T tag = loc.find(getDocComment(overriden));
|
||||
T tag = loc.find(overriden, getDocComment(overriden));
|
||||
|
||||
if (tag != null) {
|
||||
return new Pair<T, InheritDocProvider<T>>
|
||||
@@ -2167,10 +2162,26 @@ public class JavaDocInfoGenerator {
|
||||
|
||||
return findInheritDocTagInClass(method, aClass, loc, new HashSet<PsiClass>());
|
||||
}
|
||||
|
||||
private static class ParamInfo {
|
||||
private final String name;
|
||||
private final PsiDocTag docTag;
|
||||
private final InheritDocProvider<PsiDocTag> inheritDocTagProvider;
|
||||
|
||||
private ParamInfo(String paramName, PsiDocTag tag, InheritDocProvider<PsiDocTag> provider) {
|
||||
name = paramName;
|
||||
docTag = tag;
|
||||
inheritDocTagProvider = provider;
|
||||
}
|
||||
|
||||
private ParamInfo(String paramName, @NotNull Pair<PsiDocTag, InheritDocProvider<PsiDocTag>> tagWithInheritProvider) {
|
||||
this(paramName, tagWithInheritProvider.first, tagWithInheritProvider.second);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ReturnTagLocator implements DocTagLocator<PsiDocTag> {
|
||||
@Override
|
||||
public PsiDocTag find(PsiDocComment comment) {
|
||||
public PsiDocTag find(PsiDocCommentOwner owner, PsiDocComment comment) {
|
||||
if (comment == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
+2
-1
@@ -21,13 +21,14 @@ import com.intellij.ide.util.PsiElementListCellRenderer;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class JavaGotoTargetRendererProvider implements GotoTargetRendererProvider {
|
||||
@Override
|
||||
public PsiElementListCellRenderer getRenderer(final PsiElement element, GotoTargetHandler.GotoData gotoData) {
|
||||
public PsiElementListCellRenderer getRenderer(@NotNull final PsiElement element, @NotNull GotoTargetHandler.GotoData gotoData) {
|
||||
if (element instanceof PsiMethod) {
|
||||
return new MethodCellRenderer(gotoData.hasDifferentNames());
|
||||
}
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package com.intellij.psi.impl.compiled;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectCoreUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.stubs.IStubElementType;
|
||||
import com.intellij.psi.stubs.PsiFileStub;
|
||||
@@ -45,10 +43,6 @@ public abstract class ClsRepositoryPsiElement<T extends StubElement> extends Cls
|
||||
|
||||
@Override
|
||||
public PsiManager getManager() {
|
||||
Project project = ProjectCoreUtil.theOnlyOpenProject();
|
||||
if (project != null) {
|
||||
return PsiManager.getInstance(project);
|
||||
}
|
||||
final PsiFile file = getContainingFile();
|
||||
if (file == null) throw new PsiInvalidElementAccessException(this);
|
||||
return file.getManager();
|
||||
|
||||
@@ -16,17 +16,21 @@
|
||||
package com.intellij.psi.impl.light;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiClassImplUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import static com.intellij.psi.PsiReferenceList.Role.EXTENDS_LIST;
|
||||
import static com.intellij.psi.PsiReferenceList.Role.IMPLEMENTS_LIST;
|
||||
|
||||
public class LightPsiClassBuilder extends LightPsiClassBase implements OriginInfoAwareElement {
|
||||
|
||||
private final LightModifierList myModifierList = new LightModifierList(getManager());
|
||||
private final LightReferenceListBuilder myImplementsList = new LightReferenceListBuilder(getManager(), PsiReferenceList.Role.EXTENDS_LIST);
|
||||
private final LightReferenceListBuilder myExtendsList = new LightReferenceListBuilder(getManager(), PsiReferenceList.Role.EXTENDS_LIST);
|
||||
private final LightReferenceListBuilder myImplementsList = new LightReferenceListBuilder(getManager(), IMPLEMENTS_LIST);
|
||||
private final LightReferenceListBuilder myExtendsList = new LightReferenceListBuilder(getManager(), EXTENDS_LIST);
|
||||
private final LightTypeParameterListBuilder myTypeParametersList = new LightTypeParameterListBuilder(getManager(), getLanguage());
|
||||
private final Collection<PsiMethod> myMethods = ContainerUtil.newArrayList();
|
||||
private PsiElement myScope;
|
||||
@@ -104,6 +108,11 @@ public class LightPsiClassBuilder extends LightPsiClassBase implements OriginInf
|
||||
return myTypeParametersList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEquivalentTo(PsiElement another) {
|
||||
return PsiClassImplUtil.isClassEquivalentTo(this, another);
|
||||
}
|
||||
|
||||
public LightPsiClassBuilder setOriginInfo(String originInfo) {
|
||||
myOriginInfo = originInfo;
|
||||
return this;
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2000-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 com.intellij.psi.impl.light;
|
||||
|
||||
import com.intellij.psi.PsiAnnotation;
|
||||
import com.intellij.psi.PsiTypeParameter;
|
||||
import com.intellij.psi.PsiTypeParameterListOwner;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class LightTypeParameterBuilder extends LightPsiClassBuilder implements PsiTypeParameter {
|
||||
|
||||
private final PsiTypeParameterListOwner myOwner;
|
||||
private final int myIndex;
|
||||
|
||||
public LightTypeParameterBuilder(@NotNull String name, PsiTypeParameterListOwner owner, int index) {
|
||||
super(owner, name);
|
||||
myOwner = owner;
|
||||
myIndex = index;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiTypeParameterListOwner getOwner() {
|
||||
return myOwner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndex() {
|
||||
return myIndex;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiAnnotation[] getAnnotations() {
|
||||
return getModifierList().getAnnotations();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiAnnotation[] getApplicableAnnotations() {
|
||||
return getModifierList().getApplicableAnnotations();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiAnnotation findAnnotation(@NotNull @NonNls String qualifiedName) {
|
||||
return getModifierList().findAnnotation(qualifiedName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiAnnotation addAnnotation(@NotNull @NonNls String qualifiedName) {
|
||||
return getModifierList().addAnnotation(qualifiedName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
<html><head><base href="placeholder"> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } p { margin: 5px 0; } </style></head><body><small><b><a href="psi_element://Bar"><code>Bar</code></a></b></small><PRE>
|
||||
void <b>m</b>(int bar)</PRE><DD><DL><DT><b>Overrides:</b><DD><a href="psi_element://Foo#m(int)"><code>m</code></a> in class <a href="psi_element://Foo"><code>Foo</code></a></DD></DL></DD><DD><DL><DT><b>Parameters:</b><DD><code>bar</code> - description</DD></DL></DD></body></html>
|
||||
@@ -0,0 +1,13 @@
|
||||
import java.lang.Override;
|
||||
|
||||
class Foo {
|
||||
/**
|
||||
* @param foo description
|
||||
*/
|
||||
void m(int foo) {}
|
||||
}
|
||||
|
||||
class Bar extends Foo {
|
||||
@Override
|
||||
void m(int bar) {}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
<html><head><base href="placeholder"> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } p { margin: 5px 0; } </style></head><body><small><b><a href="psi_element://Bar"><code>Bar</code></a></b></small><PRE>
|
||||
<U> void <b>m</b>(U u)</PRE><DD><DL><DT><b>Overrides:</b><DD><a href="psi_element://Foo#m(java.lang.Object)"><code>m</code></a> in class <a href="psi_element://Foo"><code>Foo</code></a></DD></DL></DD><DD><DL><DT><b>Type parameters:</b><DD><code><U></code> - description</DD></DL></DD></body></html>
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import java.lang.Override;
|
||||
|
||||
class Foo {
|
||||
/**
|
||||
* @param <T> description
|
||||
*/
|
||||
<T> void m(T t) {}
|
||||
}
|
||||
|
||||
class Bar extends Foo {
|
||||
@Override
|
||||
<U> void m(U u) {}
|
||||
}
|
||||
+1
-1
@@ -677,7 +677,7 @@ interface TxANotAnno {}
|
||||
public void testLiveTemplateOrdering() {
|
||||
LiveTemplateCompletionContributor.setShowTemplatesInTests(true, getTestRootDisposable())
|
||||
checkPreferredItems(0, 'return')
|
||||
assert lookup.items[-1].lookupString == 'ritar'
|
||||
assert lookup.items.find { it.lookupString == 'ritar'} != null
|
||||
}
|
||||
|
||||
public void testPreferLocalToExpectedTypedMethod() {
|
||||
|
||||
+14
@@ -277,6 +277,20 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase {
|
||||
useJava7();
|
||||
verifyJavaDoc(getTestClass());
|
||||
}
|
||||
|
||||
public void testMatchingParameterNameFromParent() throws Exception {
|
||||
configureByFile("/codeInsight/javadocIG/" + getTestName(true) + ".java");
|
||||
PsiClass psiClass = ((PsiJavaFile)myFile).getClasses()[1];
|
||||
PsiMethod method = psiClass.getMethods()[0];
|
||||
verifyJavaDoc(method);
|
||||
}
|
||||
|
||||
public void testMatchingTypeParameterNameFromParent() throws Exception {
|
||||
configureByFile("/codeInsight/javadocIG/" + getTestName(true) + ".java");
|
||||
PsiClass psiClass = ((PsiJavaFile)myFile).getClasses()[1];
|
||||
PsiMethod method = psiClass.getMethods()[0];
|
||||
verifyJavaDoc(method);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
|
||||
-1
@@ -85,7 +85,6 @@ public abstract class RecursiveLighterASTNodeWalkingVisitor extends LighterASTNo
|
||||
parent.put(child, element);
|
||||
}
|
||||
parent.put(children.get(0), element);
|
||||
ast.disposeChildren(children);
|
||||
return children.get(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.dvcs;
|
||||
|
||||
import com.intellij.dvcs.push.PushSupport;
|
||||
import com.intellij.dvcs.repo.RepoStateException;
|
||||
import com.intellij.dvcs.repo.Repository;
|
||||
import com.intellij.dvcs.repo.RepositoryManager;
|
||||
@@ -24,6 +25,7 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.fileEditor.FileEditor;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
@@ -422,4 +424,14 @@ public class DvcsUtil {
|
||||
}
|
||||
return groupedCommits;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PushSupport getPushSupport(@NotNull final AbstractVcs vcs) {
|
||||
return ContainerUtil.find(Extensions.getExtensions(PushSupport.PUSH_SUPPORT_EP, vcs.getProject()), new Condition<PushSupport>() {
|
||||
@Override
|
||||
public boolean value(final PushSupport support) {
|
||||
return support.getVcs().equals(vcs);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import com.intellij.dvcs.repo.VcsRepositoryManager;
|
||||
import com.intellij.dvcs.ui.DvcsBundle;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -31,6 +30,7 @@ import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.vcs.AbstractVcs;
|
||||
import com.intellij.ui.CheckedTreeNode;
|
||||
import com.intellij.util.ConcurrencyUtil;
|
||||
import com.intellij.util.Function;
|
||||
@@ -62,7 +62,7 @@ public class PushController implements Disposable {
|
||||
@NotNull private final Project myProject;
|
||||
@NotNull private final List<? extends Repository> myPreselectedRepositories;
|
||||
@NotNull private final VcsRepositoryManager myGlobalRepositoryManager;
|
||||
@NotNull private final List<PushSupport<? extends Repository, ? extends PushSource, ? extends PushTarget>> myPushSupports;
|
||||
@NotNull private final List<PushSupport<Repository, PushSource, PushTarget>> myPushSupports;
|
||||
@NotNull private final PushLog myPushLog;
|
||||
@NotNull private final VcsPushDialog myDialog;
|
||||
@NotNull private final PushSettings myPushSettings;
|
||||
@@ -83,7 +83,7 @@ public class PushController implements Disposable {
|
||||
myExcludedRepositoryRoots = ContainerUtil.newHashSet(myPushSettings.getExcludedRepoRoots());
|
||||
myPreselectedRepositories = preselectedRepositories;
|
||||
myCurrentlyOpenedRepository = currentRepo;
|
||||
myPushSupports = getAffectedSupports(myProject);
|
||||
myPushSupports = getAffectedSupports();
|
||||
mySingleRepoProject = isSingleRepoProject();
|
||||
myDialog = dialog;
|
||||
CheckedTreeNode rootNode = new CheckedTreeNode(null);
|
||||
@@ -106,13 +106,12 @@ public class PushController implements Disposable {
|
||||
|
||||
private boolean isSyncStrategiesAllowed() {
|
||||
return !mySingleRepoProject &&
|
||||
ContainerUtil.and(getAffectedSupports(myProject),
|
||||
new Condition<PushSupport<? extends Repository, ? extends PushSource, ? extends PushTarget>>() {
|
||||
@Override
|
||||
public boolean value(PushSupport<? extends Repository, ? extends PushSource, ? extends PushTarget> support) {
|
||||
return support.mayChangeTargetsSync();
|
||||
}
|
||||
});
|
||||
ContainerUtil.and(getAffectedSupports(), new Condition<PushSupport<Repository, PushSource, PushTarget>>() {
|
||||
@Override
|
||||
public boolean value(PushSupport<Repository, PushSource, PushTarget> support) {
|
||||
return support.mayChangeTargetsSync();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean isSingleRepoProject() {
|
||||
@@ -120,17 +119,19 @@ public class PushController implements Disposable {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<PushSupport<? extends Repository, ? extends PushSource, ? extends PushTarget>> getAffectedSupports(@NotNull Project project) {
|
||||
final Collection<Repository> repositories = myGlobalRepositoryManager.getRepositories();
|
||||
return ContainerUtil.filter(Extensions.getExtensions(PushSupport.PUSH_SUPPORT_EP, project), new Condition<PushSupport>() {
|
||||
private <R extends Repository, S extends PushSource, T extends PushTarget> List<PushSupport<R, S, T>> getAffectedSupports() {
|
||||
Collection<Repository> repositories = myGlobalRepositoryManager.getRepositories();
|
||||
Collection<AbstractVcs> vcss = ContainerUtil.map2Set(repositories, new Function<Repository, AbstractVcs>() {
|
||||
@Override
|
||||
public boolean value(final PushSupport support) {
|
||||
return ContainerUtil.exists(repositories, new Condition<Repository>() {
|
||||
@Override
|
||||
public boolean value(Repository repository) {
|
||||
return support.getVcs().equals(repository.getVcs());
|
||||
}
|
||||
});
|
||||
public AbstractVcs fun(@NotNull Repository repository) {
|
||||
return repository.getVcs();
|
||||
}
|
||||
});
|
||||
return ContainerUtil.map(vcss, new Function<AbstractVcs, PushSupport<R, S, T>>() {
|
||||
@Override
|
||||
public PushSupport<R, S, T> fun(AbstractVcs vcs) {
|
||||
//noinspection unchecked
|
||||
return DvcsUtil.getPushSupport(vcs);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -308,13 +309,12 @@ public class PushController implements Disposable {
|
||||
public boolean isPushAllowed(final boolean force) {
|
||||
JTree tree = myPushLog.getTree();
|
||||
return !tree.isEditing() &&
|
||||
ContainerUtil
|
||||
.exists(myPushSupports, new Condition<PushSupport<? extends Repository, ? extends PushSource, ? extends PushTarget>>() {
|
||||
@Override
|
||||
public boolean value(PushSupport<? extends Repository, ? extends PushSource, ? extends PushTarget> support) {
|
||||
return isPushAllowed(support, force);
|
||||
}
|
||||
});
|
||||
ContainerUtil.exists(myPushSupports, new Condition<PushSupport<Repository, PushSource, PushTarget>>() {
|
||||
@Override
|
||||
public boolean value(PushSupport<Repository, PushSource, PushTarget> support) {
|
||||
return isPushAllowed(support, force);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean isPushAllowed(@NotNull PushSupport<?, ?, ?> pushSupport, boolean force) {
|
||||
|
||||
@@ -242,7 +242,8 @@ public abstract class GotoTargetHandler implements CodeInsightActionHandler {
|
||||
};
|
||||
}
|
||||
|
||||
public static PsiElementListCellRenderer createRenderer(GotoData gotoData, PsiElement eachTarget) {
|
||||
@NotNull
|
||||
public static PsiElementListCellRenderer createRenderer(@NotNull GotoData gotoData, @NotNull PsiElement eachTarget) {
|
||||
PsiElementListCellRenderer renderer = null;
|
||||
for (GotoTargetRendererProvider eachProvider : Extensions.getExtensions(GotoTargetRendererProvider.EP_NAME)) {
|
||||
renderer = eachProvider.getRenderer(eachTarget, gotoData);
|
||||
|
||||
+2
-1
@@ -19,6 +19,7 @@ package com.intellij.codeInsight.navigation;
|
||||
import com.intellij.ide.util.PsiElementListCellRenderer;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
@@ -28,5 +29,5 @@ public interface GotoTargetRendererProvider {
|
||||
ExtensionPointName<GotoTargetRendererProvider> EP_NAME = ExtensionPointName.create("com.intellij.gotoTargetRendererProvider");
|
||||
|
||||
@Nullable
|
||||
PsiElementListCellRenderer getRenderer(PsiElement element, GotoTargetHandler.GotoData gotoData);
|
||||
PsiElementListCellRenderer getRenderer(@NotNull PsiElement element, @NotNull GotoTargetHandler.GotoData gotoData);
|
||||
}
|
||||
|
||||
+311
@@ -0,0 +1,311 @@
|
||||
/*
|
||||
* Copyright 2000-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 com.intellij.execution.startup;
|
||||
|
||||
import com.intellij.execution.Executor;
|
||||
import com.intellij.execution.ExecutorRegistry;
|
||||
import com.intellij.execution.RunManager;
|
||||
import com.intellij.execution.RunnerAndConfigurationSettings;
|
||||
import com.intellij.execution.actions.ChooseRunConfigurationPopup;
|
||||
import com.intellij.execution.actions.ExecutorProvider;
|
||||
import com.intellij.execution.impl.EditConfigurationsDialog;
|
||||
import com.intellij.execution.impl.RunManagerImpl;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.idea.ActionsBundle;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.options.SearchableConfigurable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.wm.ToolWindowId;
|
||||
import com.intellij.ui.*;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.ui.popup.PopupFactoryImpl;
|
||||
import com.intellij.ui.treeStructure.Tree;
|
||||
import com.intellij.util.ui.FormBuilder;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.tree.TreePath;
|
||||
import javax.swing.tree.TreeSelectionModel;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Irina.Chernushina on 8/19/2015.
|
||||
*/
|
||||
public class ProjectStartupConfigurable implements SearchableConfigurable, Configurable.NoScroll {
|
||||
private final Project myProject;
|
||||
private Tree myTree;
|
||||
private ProjectStartupConfiguration myConfiguration;
|
||||
private ToolbarDecorator myDecorator;
|
||||
|
||||
public ProjectStartupConfigurable(Project project) {
|
||||
myProject = project;
|
||||
myConfiguration = ProjectStartupConfiguration.getInstance(myProject);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getId() {
|
||||
return "preferences.startup.tasks";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Runnable enableSearch(String option) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nls
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return "Project Startup Tasks";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getHelpTopic() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public JComponent createComponent() {
|
||||
myTree = new Tree();
|
||||
installRenderer();
|
||||
myDecorator = ToolbarDecorator.createDecorator(myTree)
|
||||
.setAddAction(new AnActionButtonRunnable() {
|
||||
@Override
|
||||
public void run(AnActionButton button) {
|
||||
selectAndAddConfiguration(button);
|
||||
}
|
||||
})
|
||||
.setEditAction(new AnActionButtonRunnable() {
|
||||
@Override
|
||||
public void run(AnActionButton button) {
|
||||
RunnerAndConfigurationSettings selected = getSelectedSettings();
|
||||
if (selected == null) return;
|
||||
|
||||
final RunManager runManager = RunManagerImpl.getInstance(myProject);
|
||||
final RunnerAndConfigurationSettings was = runManager.getSelectedConfiguration();
|
||||
try {
|
||||
runManager.setSelectedConfiguration(selected);
|
||||
new EditConfigurationsDialog(myProject).showAndGet();
|
||||
} finally {
|
||||
runManager.setSelectedConfiguration(was);
|
||||
}
|
||||
}
|
||||
})
|
||||
.setEditActionUpdater(new AnActionButtonUpdater() {
|
||||
@Override
|
||||
public boolean isEnabled(AnActionEvent e) {
|
||||
return getSelectedSettings() != null;
|
||||
}
|
||||
})
|
||||
.setRemoveAction(new AnActionButtonRunnable() {
|
||||
@Override
|
||||
public void run(AnActionButton button) {
|
||||
RunnerAndConfigurationSettings selected = getSelectedSettings();
|
||||
if (selected == null) return;
|
||||
final ProjectStartupTasksTreeModel oldModel = (ProjectStartupTasksTreeModel)myTree.getModel();
|
||||
final List<RunnerAndConfigurationSettings> configurations = oldModel.getConfigurations();
|
||||
if (!configurations.contains(selected)) {
|
||||
return;
|
||||
}
|
||||
configurations.remove(selected);
|
||||
Collections.sort(configurations, new Comparator<RunnerAndConfigurationSettings>() {
|
||||
@Override
|
||||
public int compare(RunnerAndConfigurationSettings o1, RunnerAndConfigurationSettings o2) {
|
||||
return o1.getName().compareToIgnoreCase(o2.getName());
|
||||
}
|
||||
});
|
||||
setModel(new ProjectStartupTasksTreeModel(configurations));
|
||||
}
|
||||
});
|
||||
myTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
|
||||
final JPanel tasksPanel = myDecorator.createPanel();
|
||||
return FormBuilder.createFormBuilder() // todo bundle
|
||||
.addLabeledComponentFillVertically("Tasks to be executed right after opening the project.", tasksPanel)
|
||||
.getPanel();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private RunnerAndConfigurationSettings getSelectedSettings() {
|
||||
final TreePath path = myTree.getSelectionPath();
|
||||
if (path == null) return null;
|
||||
if (! (path.getLastPathComponent() instanceof RunnerAndConfigurationSettings)) return null;
|
||||
return (RunnerAndConfigurationSettings)path.getLastPathComponent();
|
||||
}
|
||||
|
||||
private ChooseRunConfigurationPopup.ItemWrapper<Void> createEditWrapper() {
|
||||
return new ChooseRunConfigurationPopup.ItemWrapper<Void>(null) {
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return AllIcons.Actions.EditSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return UIUtil.removeMnemonic(ActionsBundle.message("action.editRunConfigurations.text"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void perform(@NotNull final Project project, @NotNull final Executor executor, @NotNull DataContext context) {
|
||||
if (new EditConfigurationsDialog(project).showAndGet()) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
RunnerAndConfigurationSettings configuration = RunManager.getInstance(project).getSelectedConfiguration();
|
||||
if (configuration != null) {
|
||||
addConfigurationToList(configuration);
|
||||
}
|
||||
}
|
||||
}, project.getDisposed());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean available(Executor executor) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void selectAndAddConfiguration(final AnActionButton button) {
|
||||
final Executor executor = ExecutorRegistry.getInstance().getExecutorById(ToolWindowId.DEBUG);
|
||||
final List<ChooseRunConfigurationPopup.ItemWrapper> wrappers = new ArrayList<ChooseRunConfigurationPopup.ItemWrapper>();
|
||||
wrappers.add(createEditWrapper());
|
||||
final ChooseRunConfigurationPopup.ItemWrapper[] allSettings =
|
||||
ChooseRunConfigurationPopup.createSettingsList(myProject, new ExecutorProvider() {
|
||||
@Override
|
||||
public Executor getExecutor() {
|
||||
return executor;
|
||||
}
|
||||
}, false);
|
||||
for (ChooseRunConfigurationPopup.ItemWrapper setting : allSettings) {
|
||||
if (setting.getValue() instanceof RunnerAndConfigurationSettings) {
|
||||
// todo maybe auto save temporary?
|
||||
if (! ((RunnerAndConfigurationSettings)setting.getValue()).isTemporary()) {
|
||||
wrappers.add(setting);
|
||||
}
|
||||
}
|
||||
}
|
||||
final JBList list = new JBList(wrappers);
|
||||
list.setCellRenderer(new ColoredListCellRenderer() {
|
||||
@Override
|
||||
protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {
|
||||
if (value instanceof ChooseRunConfigurationPopup.ItemWrapper) {
|
||||
setIcon(((ChooseRunConfigurationPopup.ItemWrapper)value).getIcon());
|
||||
append(((ChooseRunConfigurationPopup.ItemWrapper)value).getText());
|
||||
}
|
||||
}
|
||||
});
|
||||
final JBPopup popup = PopupFactoryImpl.getInstance()
|
||||
.createListPopupBuilder(list)
|
||||
.setItemChoosenCallback(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final int index = list.getSelectedIndex();
|
||||
if (index < 0) return;
|
||||
final ChooseRunConfigurationPopup.ItemWrapper at = (ChooseRunConfigurationPopup.ItemWrapper)list.getModel().getElementAt(index);
|
||||
if (at.getValue() instanceof RunnerAndConfigurationSettings) {
|
||||
addConfigurationToList((RunnerAndConfigurationSettings)at.getValue());
|
||||
} else {
|
||||
at.perform(myProject, executor, button.getDataContext());
|
||||
}
|
||||
}
|
||||
})
|
||||
.createPopup();
|
||||
popup.show(new RelativePoint(myDecorator.getActionsPanel(), new Point(10, 10)));
|
||||
}
|
||||
|
||||
private void addConfigurationToList(final RunnerAndConfigurationSettings settings) {
|
||||
if (settings != null) {
|
||||
final ProjectStartupTasksTreeModel oldModel = (ProjectStartupTasksTreeModel)myTree.getModel();
|
||||
final List<RunnerAndConfigurationSettings> configurations = oldModel.getConfigurations();
|
||||
if (!configurations.contains(settings)) {
|
||||
configurations.add(settings);
|
||||
}
|
||||
Collections.sort(configurations, new Comparator<RunnerAndConfigurationSettings>() {
|
||||
@Override
|
||||
public int compare(RunnerAndConfigurationSettings o1, RunnerAndConfigurationSettings o2) {
|
||||
return o1.getName().compareToIgnoreCase(o2.getName());
|
||||
}
|
||||
});
|
||||
setModel(new ProjectStartupTasksTreeModel(configurations));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModified() {
|
||||
final List<RunnerAndConfigurationSettings> recorded = myConfiguration.getStartupConfigurations();
|
||||
final List<RunnerAndConfigurationSettings> current = ((ProjectStartupTasksTreeModel)myTree.getModel()).getConfigurations();
|
||||
return ! Comparing.equal(recorded, current);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws ConfigurationException {
|
||||
myConfiguration.setStartupConfigurations(((ProjectStartupTasksTreeModel)myTree.getModel()).getConfigurations(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
final ProjectStartupTasksTreeModel model = new ProjectStartupTasksTreeModel(myConfiguration.getStartupConfigurations());
|
||||
setModel(model);
|
||||
}
|
||||
|
||||
private void setModel(ProjectStartupTasksTreeModel model) {
|
||||
myTree.setModel(model);
|
||||
myTree.setShowsRootHandles(false);
|
||||
myTree.setRootVisible(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disposeUIResources() {
|
||||
|
||||
}
|
||||
|
||||
private void installRenderer() {
|
||||
myTree.setCellRenderer(new ColoredTreeCellRenderer() {
|
||||
@Override
|
||||
public void customizeCellRenderer(@NotNull JTree tree,
|
||||
Object value,
|
||||
boolean selected,
|
||||
boolean expanded,
|
||||
boolean leaf,
|
||||
int row,
|
||||
boolean hasFocus) {
|
||||
if (value instanceof RunnerAndConfigurationSettings) {
|
||||
final RunnerAndConfigurationSettings settings = (RunnerAndConfigurationSettings)value;
|
||||
setIcon(settings.getConfiguration().getIcon());
|
||||
append(settings.getName());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2000-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 com.intellij.execution.startup;
|
||||
|
||||
import com.intellij.execution.RunManager;
|
||||
import com.intellij.execution.RunManagerEx;
|
||||
import com.intellij.execution.RunnerAndConfigurationSettings;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Irina.Chernushina on 8/19/2015.
|
||||
*/
|
||||
public class ProjectStartupConfiguration {
|
||||
private final Project myProject;
|
||||
private final ProjectStartupSharedConfiguration myShared;
|
||||
private final ProjectStartupLocalConfiguration myLocal;
|
||||
private final RunManagerEx myRunManager;
|
||||
|
||||
public static ProjectStartupConfiguration getInstance(@NotNull final Project project) {
|
||||
return ServiceManager.getService(project, ProjectStartupConfiguration.class);
|
||||
}
|
||||
|
||||
public ProjectStartupConfiguration(Project project, ProjectStartupSharedConfiguration shared, ProjectStartupLocalConfiguration local,
|
||||
@NotNull RunManager runManager) {
|
||||
myProject = project;
|
||||
myShared = shared;
|
||||
myLocal = local;
|
||||
myRunManager = (RunManagerEx)runManager;
|
||||
}
|
||||
|
||||
public List<RunnerAndConfigurationSettings> getStartupConfigurations() {
|
||||
final List<RunnerAndConfigurationSettings> result = new ArrayList<RunnerAndConfigurationSettings>();
|
||||
if (! myShared.isEmpty()) {
|
||||
myLocal.clear();
|
||||
return fillResult(result, myShared.getList());
|
||||
}
|
||||
return fillResult(result, myLocal.getList());
|
||||
}
|
||||
|
||||
private List<RunnerAndConfigurationSettings> fillResult(List<RunnerAndConfigurationSettings> result, List<String> list) {
|
||||
for (String s : list) {
|
||||
final RunnerAndConfigurationSettings settings = myRunManager.findConfigurationByName(s);
|
||||
if (settings != null) {
|
||||
result.add(settings);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setStartupConfigurations(final @NotNull List<RunnerAndConfigurationSettings> list, final boolean shared) {
|
||||
final List<String> names = ContainerUtil.map(list, new Function<RunnerAndConfigurationSettings, String>() {
|
||||
@Override
|
||||
public String fun(RunnerAndConfigurationSettings settings) {
|
||||
return settings.getName();
|
||||
}
|
||||
});
|
||||
if (shared) {
|
||||
myLocal.clear();
|
||||
myShared.setList(names);
|
||||
} else {
|
||||
myShared.clear();
|
||||
myLocal.setList(names);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canBeShared() {
|
||||
if (isShared()) return true;
|
||||
if (isEmpty()) return true;
|
||||
|
||||
final List<String> list = myLocal.getList();
|
||||
for (String s : list) {
|
||||
final RunnerAndConfigurationSettings settings = myRunManager.findConfigurationByName(s);
|
||||
if (settings != null) {
|
||||
if (! myRunManager.isConfigurationShared(settings)) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isShared() {
|
||||
return ! myShared.isEmpty();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return myShared.isEmpty() && myLocal.isEmpty();
|
||||
}
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2000-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 com.intellij.execution.startup;
|
||||
|
||||
import com.intellij.openapi.components.PersistentStateComponent;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Irina.Chernushina on 8/19/2015.
|
||||
*/
|
||||
public class ProjectStartupConfigurationBase implements PersistentStateComponent<Element> {
|
||||
private final static String TOP_ELEMENT = "startup-tasks";
|
||||
private final static String TASK = "task";
|
||||
private final static String NAME = "name";
|
||||
private final static String TYPE = "type";
|
||||
|
||||
private final List<String> myList;
|
||||
|
||||
protected ProjectStartupConfigurationBase() {
|
||||
myList = new ArrayList<String>();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Element getState() {
|
||||
if (myList.isEmpty()) return null;
|
||||
final Element element = new Element(TOP_ELEMENT);
|
||||
for (String name : myList) {
|
||||
final Element child = new Element(TASK);
|
||||
child.setAttribute(NAME, name);
|
||||
|
||||
element.addContent(child);
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadState(Element state) {
|
||||
myList.clear();
|
||||
final List<Element> children = state.getChildren();
|
||||
for (Element child : children) {
|
||||
if (TASK.equals(child.getName())) {
|
||||
final String name = child.getAttributeValue(NAME);
|
||||
if (! StringUtil.isEmptyOrSpaces(name)) {
|
||||
myList.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
myList.clear();
|
||||
}
|
||||
|
||||
public List<String> getList() {
|
||||
return myList;
|
||||
}
|
||||
|
||||
public void setList(@NotNull final List<String> list) {
|
||||
myList.clear();
|
||||
myList.addAll(list);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return myList.isEmpty();
|
||||
}
|
||||
|
||||
public static class ConfigurationDescriptor {
|
||||
private final @NotNull String myTypeId;
|
||||
private final @NotNull String myName;
|
||||
|
||||
public ConfigurationDescriptor(@NotNull String typeId, @NotNull String name) {
|
||||
myTypeId = typeId;
|
||||
myName = name;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getTypeId() {
|
||||
return myTypeId;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return myName;
|
||||
}
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2000-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 com.intellij.execution.startup;
|
||||
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.openapi.components.StoragePathMacros;
|
||||
|
||||
/**
|
||||
* @author Irina.Chernushina on 8/19/2015.
|
||||
*/
|
||||
@State(
|
||||
name = "ProjectStartupLocalConfiguration",
|
||||
storages = {
|
||||
@Storage(file = StoragePathMacros.WORKSPACE_FILE)
|
||||
}
|
||||
)
|
||||
public class ProjectStartupLocalConfiguration extends ProjectStartupConfigurationBase {
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2000-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 com.intellij.execution.startup;
|
||||
|
||||
import com.intellij.execution.Executor;
|
||||
import com.intellij.execution.ProgramRunnerUtil;
|
||||
import com.intellij.execution.RunnerAndConfigurationSettings;
|
||||
import com.intellij.execution.executors.DefaultRunExecutor;
|
||||
import com.intellij.ide.startup.StartupManagerEx;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.startup.StartupActivity;
|
||||
import com.intellij.openapi.startup.StartupManager;
|
||||
import com.intellij.util.Alarm;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Irina.Chernushina on 8/19/2015.
|
||||
*/
|
||||
public class ProjectStartupRunner implements StartupActivity {
|
||||
public static final int DELAY_MILLIS = 200;
|
||||
|
||||
@Override
|
||||
public void runActivity(@NotNull Project project) {
|
||||
if (ProjectStartupConfiguration.getInstance(project).isEmpty()) return;
|
||||
|
||||
final Alarm alarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, project);
|
||||
alarm.addRequest(createRequest(project, alarm), DELAY_MILLIS);
|
||||
}
|
||||
|
||||
private Runnable createRequest(final Project project, final Alarm alarm) {
|
||||
return new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (! ((StartupManagerEx) StartupManager.getInstance(project)).postStartupActivityPassed()) {
|
||||
alarm.addRequest(createRequest(project, alarm), DELAY_MILLIS);
|
||||
} else {
|
||||
runActivities(project);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void runActivities(final Project project) {
|
||||
final List<RunnerAndConfigurationSettings> configurations = ProjectStartupConfiguration.getInstance(project).getStartupConfigurations();
|
||||
final Executor executor = DefaultRunExecutor.getRunExecutorInstance();
|
||||
for (final RunnerAndConfigurationSettings configuration : configurations) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ProgramRunnerUtil.executeConfiguration(project, configuration, executor);
|
||||
}
|
||||
}, ModalityState.any());
|
||||
}
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2000-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 com.intellij.execution.startup;
|
||||
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.openapi.components.StoragePathMacros;
|
||||
import com.intellij.openapi.components.StorageScheme;
|
||||
|
||||
/**
|
||||
* @author Irina.Chernushina on 8/19/2015.
|
||||
*/
|
||||
@State(
|
||||
name = "ProjectStartupSharedConfiguration",
|
||||
storages = {
|
||||
@Storage(file = StoragePathMacros.PROJECT_FILE),
|
||||
@Storage(file = StoragePathMacros.PROJECT_CONFIG_DIR + "/startup.xml", scheme = StorageScheme.DEFAULT)
|
||||
}
|
||||
)
|
||||
public class ProjectStartupSharedConfiguration extends ProjectStartupConfigurationBase {
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2000-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 com.intellij.execution.startup;
|
||||
|
||||
import com.intellij.execution.RunnerAndConfigurationSettings;
|
||||
|
||||
import javax.swing.event.TreeModelListener;
|
||||
import javax.swing.tree.TreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Irina.Chernushina on 8/19/2015.
|
||||
*/
|
||||
public class ProjectStartupTasksTreeModel implements TreeModel {
|
||||
private final Object myRoot = new Object();
|
||||
private final List<RunnerAndConfigurationSettings> myConfigurations;
|
||||
|
||||
public ProjectStartupTasksTreeModel(List<RunnerAndConfigurationSettings> configurations) {
|
||||
myConfigurations = configurations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRoot() {
|
||||
return myRoot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getChild(Object parent, int index) {
|
||||
if (parent == myRoot) {
|
||||
return myConfigurations.get(index);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildCount(Object parent) {
|
||||
if (parent == myRoot) {
|
||||
return myConfigurations.size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeaf(Object node) {
|
||||
return getChildCount(node) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueForPathChanged(TreePath path, Object newValue) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndexOfChild(Object parent, Object child) {
|
||||
if (parent == myRoot) {
|
||||
for (int i = 0; i < myConfigurations.size(); i++) {
|
||||
final RunnerAndConfigurationSettings configuration = myConfigurations.get(i);
|
||||
if (configuration == child) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTreeModelListener(TreeModelListener l) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTreeModelListener(TreeModelListener l) {
|
||||
|
||||
}
|
||||
|
||||
public List<RunnerAndConfigurationSettings> getConfigurations() {
|
||||
return myConfigurations;
|
||||
}
|
||||
}
|
||||
@@ -1182,7 +1182,7 @@ public abstract class DialogWrapper {
|
||||
ensureEventDispatchThread();
|
||||
myErrorText = new ErrorText();
|
||||
myErrorText.setVisible(false);
|
||||
myErrorText.myLabel.addComponentListener(new ComponentAdapter() {
|
||||
final ComponentAdapter resizeListener = new ComponentAdapter() {
|
||||
private int myHeight;
|
||||
|
||||
@Override
|
||||
@@ -1203,6 +1203,13 @@ public abstract class DialogWrapper {
|
||||
myResizeInProgress = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
myErrorText.myLabel.addComponentListener(resizeListener);
|
||||
Disposer.register(myDisposable, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
myErrorText.myLabel.removeComponentListener(resizeListener);
|
||||
}
|
||||
});
|
||||
|
||||
final JPanel root = new JPanel(createRootLayout());
|
||||
|
||||
@@ -29,6 +29,9 @@ import java.nio.charset.Charset;
|
||||
public abstract class BaseOutputReader extends BaseDataReader {
|
||||
protected final Reader myReader;
|
||||
|
||||
private final char[] myInputBuffer = new char[8192];
|
||||
private final StringBuilder myLineBuffer = new StringBuilder();
|
||||
|
||||
public BaseOutputReader(@NotNull InputStream inputStream, @Nullable Charset charset) {
|
||||
this(inputStream, charset, null);
|
||||
}
|
||||
@@ -62,18 +65,16 @@ public abstract class BaseOutputReader extends BaseDataReader {
|
||||
* @throws IOException If an I/O error occurs
|
||||
*/
|
||||
protected final boolean readAvailableNonBlocking() throws IOException {
|
||||
char[] buffer = new char[8192];
|
||||
StringBuilder line = new StringBuilder();
|
||||
boolean read = false;
|
||||
|
||||
int n;
|
||||
while (myReader.ready() && (n = myReader.read(buffer)) > 0) {
|
||||
while (myReader.ready() && (n = myReader.read(myInputBuffer)) > 0) {
|
||||
read = true;
|
||||
processLine(buffer, line, n);
|
||||
processLine(myInputBuffer, myLineBuffer, n);
|
||||
}
|
||||
|
||||
if (line.length() > 0) {
|
||||
sendLine(line);
|
||||
if (myLineBuffer.length() > 0) {
|
||||
sendLine(myLineBuffer);
|
||||
}
|
||||
|
||||
return read;
|
||||
@@ -89,23 +90,21 @@ public abstract class BaseOutputReader extends BaseDataReader {
|
||||
* @throws IOException If an I/O error occurs
|
||||
*/
|
||||
protected final boolean readAvailableBlocking() throws IOException {
|
||||
char[] buffer = new char[8192];
|
||||
StringBuilder line = new StringBuilder();
|
||||
boolean read = false;
|
||||
|
||||
int n;
|
||||
while ((n = myReader.read(buffer)) > 0) {
|
||||
while ((n = myReader.read(myInputBuffer)) > 0) {
|
||||
read = true;
|
||||
processLine(buffer, line, n);
|
||||
processLine(myInputBuffer, myLineBuffer, n);
|
||||
|
||||
if (!myReader.ready()) {
|
||||
if (line.length() > 0) sendLine(line);
|
||||
if (myLineBuffer.length() > 0) sendLine(myLineBuffer);
|
||||
onBufferExhaustion();
|
||||
}
|
||||
}
|
||||
|
||||
if (line.length() > 0) {
|
||||
sendLine(line);
|
||||
if (myLineBuffer.length() > 0) {
|
||||
sendLine(myLineBuffer);
|
||||
}
|
||||
|
||||
return read;
|
||||
|
||||
+3
@@ -18,6 +18,7 @@ package com.intellij.openapi.vcs.versionBrowser;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.util.text.SyncDateFormat;
|
||||
import com.intellij.util.xmlb.annotations.Transient;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -54,6 +55,8 @@ public class ChangeBrowserSettings implements JDOMExternalizable {
|
||||
public String USER = "";
|
||||
public boolean STOP_ON_COPY = false;
|
||||
|
||||
@Transient public boolean STRICTLY_AFTER = false;
|
||||
|
||||
public void readExternal(Element element) throws InvalidDataException {
|
||||
DefaultJDOMExternalizer.readExternal(this, element);
|
||||
}
|
||||
|
||||
+2
-2
@@ -84,7 +84,6 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
|
||||
private final Set<CommittedChangeList> myNewIncomingChanges = new LinkedHashSet<CommittedChangeList>();
|
||||
private final ProjectLevelVcsManager myVcsManager;
|
||||
|
||||
public static final Change[] ALL_CHANGES = new Change[0];
|
||||
private MyRefreshRunnable myRefresnRunnable;
|
||||
|
||||
private final Map<String, Pair<Long, List<CommittedChangeList>>> myExternallyLoadedChangeLists;
|
||||
@@ -538,7 +537,7 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
|
||||
});
|
||||
}
|
||||
|
||||
// todo: fix - would externally loaded nesseccerily for file? i.e. just not efficient now
|
||||
// todo: fix - would externally loaded necessarily for file? i.e. just not efficient now
|
||||
private List<CommittedChangeList> refreshCache(final ChangesCacheFile cacheFile) throws VcsException, IOException {
|
||||
final List<CommittedChangeList> newLists = new ArrayList<CommittedChangeList>();
|
||||
|
||||
@@ -571,6 +570,7 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
|
||||
defaultSettings.setDateAfter(date);
|
||||
defaultSettings.USE_DATE_AFTER_FILTER = true;
|
||||
}
|
||||
defaultSettings.STRICTLY_AFTER = true;
|
||||
final List<CommittedChangeList> newChanges = provider.getCommittedChanges(defaultSettings, location, maxCount);
|
||||
debug("Loaded " + newChanges.size() + " new changelists");
|
||||
newLists.addAll(appendLoadedChanges(cacheFile, location, newChanges));
|
||||
|
||||
@@ -22,11 +22,13 @@ import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.diff.LineTokenizer;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.EmptyRunnable;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vcs.*;
|
||||
import com.intellij.openapi.vcs.annotate.AnnotationProvider;
|
||||
import com.intellij.openapi.vcs.annotate.FileAnnotation;
|
||||
import com.intellij.openapi.vcs.changes.*;
|
||||
import com.intellij.openapi.vcs.changes.committed.CommittedChangesCache;
|
||||
import com.intellij.openapi.vcs.impl.ProjectLevelVcsManagerImpl;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -160,6 +162,7 @@ public abstract class AbstractVcsTestCase {
|
||||
protected void tearDownProject() throws Exception {
|
||||
if (myProject != null) {
|
||||
((ChangeListManagerImpl)ChangeListManager.getInstance(myProject)).stopEveryThingIfInTestMode();
|
||||
CommittedChangesCache.getInstance(myProject).clearCaches(EmptyRunnable.INSTANCE);
|
||||
myProject = null;
|
||||
}
|
||||
if (myProjectFixture != null) {
|
||||
|
||||
+6
@@ -52,6 +52,12 @@ public class XDebuggerTreePanel implements DnDSource {
|
||||
myMainPanel = new JPanel(new BorderLayout());
|
||||
myMainPanel.add(ScrollPaneFactory.createScrollPane(myTree), BorderLayout.CENTER);
|
||||
Disposer.register(parentDisposable, myTree);
|
||||
Disposer.register(parentDisposable, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
myMainPanel.removeAll();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public XDebuggerTree getTree() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-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.
|
||||
@@ -105,6 +105,7 @@ public interface IdeaPlugin extends DomElement {
|
||||
|
||||
@NotNull
|
||||
@SubTagList("extensions")
|
||||
@Stubbed
|
||||
List<Extensions> getExtensions();
|
||||
Extensions addExtensions();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-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.
|
||||
@@ -43,6 +43,6 @@ public class PluginXmlDomFileDescription extends DomFileDescription<IdeaPlugin>
|
||||
|
||||
@Override
|
||||
public int getStubVersion() {
|
||||
return 3;
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,4 +13,6 @@
|
||||
<extensionPoint qualifiedName="qualifiedName" beanClass="BeanClass"/>
|
||||
</extensionPoints>
|
||||
|
||||
<extensions defaultExtensionNs="defaultExtensionNs" xmlns="extensionXmlNs"/>
|
||||
|
||||
</idea-plugin>
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-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.
|
||||
@@ -40,7 +40,10 @@ public class PluginXmlDomStubsTest extends DomStubTest {
|
||||
" Attribute:implements:SomeImplements\n" +
|
||||
" Element:extensionPoint\n" +
|
||||
" Attribute:qualifiedName:qualifiedName\n" +
|
||||
" Attribute:beanClass:BeanClass\n");
|
||||
" Attribute:beanClass:BeanClass\n" +
|
||||
" Element:extensions\n" +
|
||||
" Attribute:defaultExtensionNs:defaultExtensionNs\n" +
|
||||
" Attribute:xmlns:extensionXmlNs\n");
|
||||
}
|
||||
|
||||
public void testXInclude() throws Exception {
|
||||
|
||||
+2
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-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.
|
||||
@@ -224,6 +224,7 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase<PsiRefere
|
||||
processImplicitConstructorCall(clazz, consumer, searchedConstructor);
|
||||
}
|
||||
for (PsiMethod constructor : constructors) {
|
||||
if (!(constructor instanceof GrMethod)) continue;
|
||||
final GrOpenBlock block = ((GrMethod)constructor).getBlock();
|
||||
if (block != null) {
|
||||
final GrStatement[] statements = block.getStatements();
|
||||
|
||||
+41
-37
@@ -116,7 +116,7 @@ public class GrTypeDefinitionMembersCache {
|
||||
final List<PsiClass> result = ContainerUtil.newArrayList();
|
||||
final GrTypeDefinitionBody body = myDefinition.getBody();
|
||||
if (body != null) ContainerUtil.addAll(result, body.getInnerClasses());
|
||||
result.addAll(AstTransformContributor.runContributorsForClasses(myDefinition));
|
||||
result.addAll(AstTransformContributor.runContributors(myDefinition).getClasses());
|
||||
return Result.create(result.toArray(new PsiClass[result.size()]), myTreeChangeTracker);
|
||||
}
|
||||
});
|
||||
@@ -135,16 +135,17 @@ public class GrTypeDefinitionMembersCache {
|
||||
|
||||
private List<GrField> getFieldsImpl() {
|
||||
List<GrField> fields = ContainerUtil.newArrayList(myDefinition.getCodeFields());
|
||||
fields.addAll(new TraitCollector().collectFields());
|
||||
fields.addAll(getSyntheticFields());
|
||||
return fields;
|
||||
}
|
||||
|
||||
private List<GrField> getSyntheticFields() {
|
||||
return CachedValuesManager.getCachedValue(myDefinition, new CachedValueProvider<List<GrField>>() {
|
||||
private Collection<GrField> getSyntheticFields() {
|
||||
return CachedValuesManager.getCachedValue(myDefinition, new CachedValueProvider<Collection<GrField>>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public Result<List<GrField>> compute() {
|
||||
return Result.create(AstTransformContributor.runContributorsForFields(myDefinition), myTreeChangeTracker,
|
||||
public Result<Collection<GrField>> compute() {
|
||||
return Result.create(AstTransformContributor.runContributors(myDefinition).getFields(), myTreeChangeTracker,
|
||||
PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
|
||||
}
|
||||
});
|
||||
@@ -154,10 +155,11 @@ public class GrTypeDefinitionMembersCache {
|
||||
return CachedValuesManager.getCachedValue(myDefinition, new CachedValueProvider<PsiMethod[]>() {
|
||||
@Override
|
||||
public Result<PsiMethod[]> compute() {
|
||||
List<PsiMethod> result = ContainerUtil.newArrayList();
|
||||
GrClassImplUtil.collectMethodsFromBody(myDefinition, result);
|
||||
Collection<PsiMethod> result = ContainerUtil.newLinkedHashSet();
|
||||
|
||||
for (PsiMethod method : AstTransformContributor.runContributorsForMethods(myDefinition)) {
|
||||
GrClassImplUtil.collectMethodsFromBody(myDefinition, result);
|
||||
result.addAll(new TraitCollector().collectMethods(result));
|
||||
for (PsiMethod method : AstTransformContributor.runContributors(myDefinition).getMethods()) {
|
||||
GrClassImplUtil.addExpandingReflectedMethods(result, method);
|
||||
}
|
||||
|
||||
@@ -166,6 +168,9 @@ public class GrTypeDefinitionMembersCache {
|
||||
ContainerUtil.addIfNotNull(result, field.getSetter());
|
||||
Collections.addAll(result, field.getGetters());
|
||||
}
|
||||
|
||||
result = GrClassImplUtil.filterOutAccessors(result);
|
||||
|
||||
return Result.create(result.toArray(new PsiMethod[result.size()]), myTreeChangeTracker,
|
||||
PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
|
||||
}
|
||||
@@ -176,8 +181,8 @@ public class GrTypeDefinitionMembersCache {
|
||||
myTreeChangeTracker.incModificationCount();
|
||||
}
|
||||
|
||||
public static class TraitCollector extends AstTransformContributor {
|
||||
private abstract static class TraitProcessor<T extends PsiElement> {
|
||||
private class TraitCollector {
|
||||
private abstract class TraitProcessor<T extends PsiElement> {
|
||||
private final ArrayList<CandidateInfo> result = ContainerUtil.newArrayList();
|
||||
private final Set<PsiClass> processed = ContainerUtil.newHashSet();
|
||||
|
||||
@@ -213,18 +218,17 @@ public class GrTypeDefinitionMembersCache {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectMethods(@NotNull GrTypeDefinition clazz, Collection<PsiMethod> collector) {
|
||||
if (clazz.isInterface() && !clazz.isTrait()) return;
|
||||
@NotNull
|
||||
public List<PsiMethod> collectMethods(@NotNull Collection<PsiMethod> codeMethods) {
|
||||
if (myDefinition.isInterface() && !myDefinition.isTrait()) return Collections.emptyList();
|
||||
|
||||
GrImplementsClause clause = clazz.getImplementsClause();
|
||||
if (clause == null) return;
|
||||
GrImplementsClause clause = myDefinition.getImplementsClause();
|
||||
if (clause == null) return Collections.emptyList();
|
||||
PsiClassType[] types = clause.getReferencedTypes();
|
||||
|
||||
List<PsiClassType.ClassResolveResult> traits = getSuperTraitsByCorrectOrder(types);
|
||||
if (traits.isEmpty()) return;
|
||||
if (traits.isEmpty()) return Collections.emptyList();
|
||||
|
||||
PsiMethod[] codeMethods = clazz.getCodeMethods();
|
||||
Set<MethodSignature> existingSignatures = ContainerUtil.newHashSet(ContainerUtil.map(codeMethods, new Function<PsiMethod, MethodSignature>() {
|
||||
@Override
|
||||
public MethodSignature fun(PsiMethod method) {
|
||||
@@ -232,6 +236,8 @@ public class GrTypeDefinitionMembersCache {
|
||||
}
|
||||
}));
|
||||
|
||||
List<PsiMethod> result = ContainerUtil.newArrayList();
|
||||
|
||||
for (PsiClassType.ClassResolveResult resolveResult : traits) {
|
||||
GrTypeDefinition trait = (GrTypeDefinition)resolveResult.getElement();
|
||||
LOG.assertTrue(trait != null);
|
||||
@@ -257,29 +263,31 @@ public class GrTypeDefinitionMembersCache {
|
||||
}
|
||||
}.getResult();
|
||||
for (CandidateInfo candidateInfo : concreteTraitMethods) {
|
||||
List<GrMethod> methodsToAdd = getExpandingMethods(clazz, candidateInfo);
|
||||
List<GrMethod> methodsToAdd = getExpandingMethods(candidateInfo);
|
||||
for (GrMethod impl : methodsToAdd) {
|
||||
if (existingSignatures.add(impl.getSignature(PsiSubstitutor.EMPTY))) {
|
||||
collector.add(impl);
|
||||
result.add(impl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectFields(@NotNull GrTypeDefinition clazz, Collection<GrField> collector) {
|
||||
if (clazz.isInterface() && !clazz.isTrait()) return;
|
||||
@NotNull
|
||||
public List<GrField> collectFields() {
|
||||
if (myDefinition.isInterface() && !myDefinition.isTrait()) return Collections.emptyList();
|
||||
|
||||
if (clazz.isTrait()) {
|
||||
for (GrField field : clazz.getCodeFields()) {
|
||||
collector.add(new GrTraitField(field, clazz, PsiSubstitutor.EMPTY));
|
||||
List<GrField> result = ContainerUtil.newArrayList();
|
||||
|
||||
if (myDefinition.isTrait()) {
|
||||
for (GrField field : myDefinition.getCodeFields()) {
|
||||
result.add(new GrTraitField(field, myDefinition, PsiSubstitutor.EMPTY));
|
||||
}
|
||||
}
|
||||
|
||||
GrImplementsClause clause = clazz.getImplementsClause();
|
||||
if (clause == null) return;
|
||||
|
||||
GrImplementsClause clause = myDefinition.getImplementsClause();
|
||||
if (clause == null) return result;
|
||||
PsiClassType[] types = clause.getReferencedTypes();
|
||||
|
||||
List<PsiClassType.ClassResolveResult> traits = getSuperTraitsByCorrectOrder(types);
|
||||
@@ -295,21 +303,17 @@ public class GrTypeDefinitionMembersCache {
|
||||
}
|
||||
}.getResult();
|
||||
for (CandidateInfo candidateInfo : traitFields) {
|
||||
collector.add(new GrTraitField(((PsiField)candidateInfo.getElement()), clazz, candidateInfo.getSubstitutor()));
|
||||
result.add(new GrTraitField(((PsiField)candidateInfo.getElement()), myDefinition, candidateInfo.getSubstitutor()));
|
||||
}
|
||||
}
|
||||
|
||||
if (clazz.isTrait()) {
|
||||
for (GrField field : clazz.getCodeFields()) {
|
||||
collector.add(new GrTraitField(field, clazz, PsiSubstitutor.EMPTY));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<GrMethod> getExpandingMethods(@NotNull GrTypeDefinition clazz, @NotNull CandidateInfo candidateInfo) {
|
||||
private List<GrMethod> getExpandingMethods(@NotNull CandidateInfo candidateInfo) {
|
||||
PsiMethod method = (PsiMethod)candidateInfo.getElement();
|
||||
GrLightMethodBuilder implementation = GrTraitMethod.create(method, candidateInfo.getSubstitutor()).setContainingClass(clazz);
|
||||
GrLightMethodBuilder implementation = GrTraitMethod.create(method, candidateInfo.getSubstitutor()).setContainingClass(myDefinition);
|
||||
implementation.getModifierList().removeModifier(GrModifierFlags.ABSTRACT_MASK);
|
||||
|
||||
GrReflectedMethod[] reflectedMethods = implementation.getReflectedMethods();
|
||||
@@ -317,7 +321,7 @@ public class GrTypeDefinitionMembersCache {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<PsiClassType.ClassResolveResult> getSuperTraitsByCorrectOrder(@NotNull PsiClassType[] types) {
|
||||
private List<PsiClassType.ClassResolveResult> getSuperTraitsByCorrectOrder(@NotNull PsiClassType[] types) {
|
||||
List<PsiClassType.ClassResolveResult> traits = ContainerUtil.newArrayList();
|
||||
for (int i = types.length - 1; i >= 0; i--) {
|
||||
PsiClassType.ClassResolveResult resolveResult = types[i].resolveGenerics();
|
||||
|
||||
+28
-59
@@ -33,6 +33,7 @@ import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.hash.HashSet;
|
||||
import gnu.trove.TObjectIntHashMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -50,7 +51,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGd
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrReflectedMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrAnnotationUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
@@ -58,6 +58,7 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.typedef.GrTypeDefin
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrScriptField;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.CollectClassMembersUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ast.AstTransformContributor;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint;
|
||||
|
||||
import java.util.*;
|
||||
@@ -136,63 +137,15 @@ public class GrClassImplUtil {
|
||||
|
||||
@NotNull
|
||||
public static PsiClassType[] getImplementsListTypes(GrTypeDefinition grType) {
|
||||
Set<PsiClass> visited = new HashSet<PsiClass>();
|
||||
List<PsiClassType> result = new ArrayList<PsiClassType>();
|
||||
getImplementListsInner(grType, result, visited);
|
||||
return result.toArray(new PsiClassType[result.size()]);
|
||||
}
|
||||
|
||||
private static void getImplementListsInner(GrTypeDefinition grType, List<PsiClassType> result, Set<PsiClass> visited) {
|
||||
if (!visited.add(grType)) return;
|
||||
|
||||
final Collection<PsiClassType> result = ContainerUtil.newLinkedHashSet();
|
||||
final PsiClassType[] implementsTypes = getReferenceListTypes(grType.getImplementsClause());
|
||||
List<PsiClassType> fromDelegates = getImplementsFromDelegate(grType, visited);
|
||||
if (fromDelegates != null) {
|
||||
result.addAll(fromDelegates);
|
||||
}
|
||||
final PsiClassType[] extendsTypes = getReferenceListTypes(grType.getExtendsClause());
|
||||
result.addAll(Arrays.asList(implementsTypes));
|
||||
|
||||
if (!grType.isInterface() &&
|
||||
!ContainerUtil.or(implementsTypes, IS_GROOVY_OBJECT) &&
|
||||
!ContainerUtil.or(getReferenceListTypes(grType.getExtendsClause()), IS_GROOVY_OBJECT)) {
|
||||
result.addAll(AstTransformContributor.runContributors(grType).getImplementsTypes());
|
||||
if (!grType.isInterface() && !ContainerUtil.or(implementsTypes, IS_GROOVY_OBJECT) && !ContainerUtil.or(extendsTypes, IS_GROOVY_OBJECT)) {
|
||||
result.add(getGroovyObjectType(grType));
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static List<PsiClassType> getImplementsFromDelegate(@NotNull final GrTypeDefinition grType, final Set<PsiClass> visited) {
|
||||
return RecursionManager.doPreventingRecursion(grType, true, new Computable<List<PsiClassType>>() {
|
||||
@Override
|
||||
public List<PsiClassType> compute() {
|
||||
List<PsiClassType> result = new ArrayList<PsiClassType>();
|
||||
final GrField[] fields = grType.getCodeFields();
|
||||
for (GrField field : fields) {
|
||||
final PsiAnnotation delegate = PsiImplUtil.getAnnotation(field, GroovyCommonClassNames.GROOVY_LANG_DELEGATE);
|
||||
if (delegate == null) continue;
|
||||
|
||||
final boolean shouldImplement = shouldImplementDelegatedInterfaces(delegate);
|
||||
if (!shouldImplement) continue;
|
||||
|
||||
final PsiType type = field.getDeclaredType();
|
||||
if (!(type instanceof PsiClassType)) continue;
|
||||
|
||||
final PsiClass psiClass = ((PsiClassType)type).resolve();
|
||||
if (psiClass == null) continue;
|
||||
|
||||
if (psiClass instanceof GrTypeDefinition) {
|
||||
getImplementListsInner((GrTypeDefinition)psiClass, result, visited);
|
||||
}
|
||||
else {
|
||||
result.addAll(Arrays.asList(psiClass.getImplementsListTypes()));
|
||||
}
|
||||
if (psiClass.isInterface()) {
|
||||
result.add((PsiClassType)type);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
});
|
||||
return result.toArray(new PsiClassType[result.size()]);
|
||||
}
|
||||
|
||||
public static PsiClassType getGroovyObjectType(@NotNull PsiElement context) {
|
||||
@@ -640,11 +593,6 @@ public class GrClassImplUtil {
|
||||
return PsiClassImplUtil.isClassEquivalentTo(definition, another);
|
||||
}
|
||||
|
||||
private static boolean shouldImplementDelegatedInterfaces(PsiAnnotation delegate) {
|
||||
final Boolean result = GrAnnotationUtil.inferBooleanAttribute(delegate, "interfaces");
|
||||
return result == null || result.booleanValue();
|
||||
}
|
||||
|
||||
public static void addExpandingReflectedMethods(Collection<PsiMethod> result, PsiMethod method) {
|
||||
if (method instanceof GrMethod) {
|
||||
final GrReflectedMethod[] reflectedMethods = ((GrMethod)method).getReflectedMethods();
|
||||
@@ -667,4 +615,25 @@ public class GrClassImplUtil {
|
||||
ContainerUtil.addIfNotNull(result, field.getSetter());
|
||||
}
|
||||
}
|
||||
|
||||
public static Collection<PsiMethod> filterOutAccessors(Collection<PsiMethod> result) {
|
||||
final TObjectIntHashMap<String> map = new TObjectIntHashMap<String>();
|
||||
for (PsiMethod method : result) {
|
||||
if (method instanceof GrAccessorMethod || GroovyPropertyUtils.isSimplePropertyAccessor(method)) {
|
||||
final String methodName = method.getName();
|
||||
if (map.containsKey(methodName)) {
|
||||
map.adjustValue(methodName, 1);
|
||||
}
|
||||
else {
|
||||
map.put(methodName, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ContainerUtil.filter(result, new Condition<PsiMethod>() {
|
||||
@Override
|
||||
public boolean value(PsiMethod method) {
|
||||
return !(method instanceof GrAccessorMethod) || map.get(method.getName()) <= 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+20
-44
@@ -18,78 +18,54 @@ package org.jetbrains.plugins.groovy.lang.resolve.ast;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.RecursionManager;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public abstract class AstTransformContributor {
|
||||
|
||||
public static final ExtensionPointName<AstTransformContributor> EP_NAME = ExtensionPointName.create("org.intellij.groovy.astTransformContributor");
|
||||
|
||||
@Deprecated
|
||||
public void collectMethods(@NotNull final GrTypeDefinition clazz, Collection<PsiMethod> collector) {
|
||||
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void collectFields(@NotNull final GrTypeDefinition clazz, Collection<GrField> collector) {
|
||||
|
||||
}
|
||||
|
||||
public void collectClasses(@NotNull final GrTypeDefinition clazz, Collection<PsiClass> collector) {
|
||||
|
||||
/**
|
||||
* Subclasses should override this method.
|
||||
*/
|
||||
@NotNull
|
||||
@SuppressWarnings("deprecation")
|
||||
public Members collect(@NotNull final GrTypeDefinition clazz) {
|
||||
final Members members = Members.create();
|
||||
collectMethods(clazz, members.getMethods());
|
||||
collectFields(clazz, members.getFields());
|
||||
return members;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Collection<PsiMethod> runContributorsForMethods(@NotNull final GrTypeDefinition clazz) {
|
||||
Collection<PsiMethod> result = RecursionManager.doPreventingRecursion(clazz, true, new Computable<Collection<PsiMethod>>() {
|
||||
public static Members runContributors(@NotNull final GrTypeDefinition clazz) {
|
||||
Members result = RecursionManager.doPreventingRecursion(clazz, true, new Computable<Members>() {
|
||||
@Override
|
||||
public Collection<PsiMethod> compute() {
|
||||
Collection<PsiMethod> collector = new ArrayList<PsiMethod>();
|
||||
public Members compute() {
|
||||
Members members = Members.create();
|
||||
for (final AstTransformContributor contributor : EP_NAME.getExtensions()) {
|
||||
contributor.collectMethods(clazz, collector);
|
||||
members.addFrom(contributor.collect(clazz));
|
||||
}
|
||||
return collector;
|
||||
return members;
|
||||
}
|
||||
});
|
||||
return result == null ? Collections.<PsiMethod>emptyList() : result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<GrField> runContributorsForFields(@NotNull final GrTypeDefinition clazz) {
|
||||
List<GrField> fields = RecursionManager.doPreventingRecursion(clazz, true, new Computable<List<GrField>>() {
|
||||
@Override
|
||||
public List<GrField> compute() {
|
||||
List<GrField> collector = new ArrayList<GrField>();
|
||||
for (final AstTransformContributor contributor : EP_NAME.getExtensions()) {
|
||||
contributor.collectFields(clazz, collector);
|
||||
}
|
||||
return collector;
|
||||
}
|
||||
});
|
||||
return fields != null ? fields : Collections.<GrField>emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<PsiClass> runContributorsForClasses(@NotNull final GrTypeDefinition clazz) {
|
||||
List<PsiClass> fields = RecursionManager.doPreventingRecursion(clazz, true, new Computable<List<PsiClass>>() {
|
||||
@Override
|
||||
public List<PsiClass> compute() {
|
||||
List<PsiClass> collector = ContainerUtil.newArrayList();
|
||||
for (final AstTransformContributor contributor : EP_NAME.getExtensions()) {
|
||||
contributor.collectClasses(clazz, collector);
|
||||
}
|
||||
return collector;
|
||||
}
|
||||
});
|
||||
return fields != null ? fields : Collections.<PsiClass>emptyList();
|
||||
return result == null ? Members.EMPTY : result;
|
||||
}
|
||||
}
|
||||
|
||||
+38
-2
@@ -49,12 +49,21 @@ import java.util.*;
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public class DelegatedMethodsContributor extends AstTransformContributor {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public void collectMethods(@NotNull final GrTypeDefinition clazz, @NotNull Collection<PsiMethod> collector) {
|
||||
public Members collect(@NotNull GrTypeDefinition clazz) {
|
||||
final Members result = Members.create();
|
||||
doCollectMethods(clazz, result.getMethods());
|
||||
doCollectImplementsTypes(clazz, result.getImplementsTypes());
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void doCollectMethods(@NotNull final GrTypeDefinition clazz, @NotNull Collection<PsiMethod> collector) {
|
||||
Set<PsiClass> processed = new HashSet<PsiClass>();
|
||||
|
||||
if (!checkForDelegate(clazz)) return;
|
||||
|
||||
|
||||
Map<MethodSignature, PsiMethod> signatures = new THashMap<MethodSignature, PsiMethod>(MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY);
|
||||
initializeSignatures(clazz, PsiSubstitutor.EMPTY, signatures, processed);
|
||||
|
||||
@@ -334,4 +343,31 @@ public class DelegatedMethodsContributor extends AstTransformContributor {
|
||||
|
||||
private static final Set<String> OBJECT_METHODS = ContainerUtil.newHashSet("equals", "hashCode", "getClass", "clone", "toString", "notify", "notifyAll", "wait", "finalize");
|
||||
private static final Set<String> GROOVY_OBJECT_METHODS = ContainerUtil.newHashSet("invokeMethod", "getProperty", "setProperty", "getMetaClass", "setMetaClass");
|
||||
|
||||
private static void doCollectImplementsTypes(GrTypeDefinition grType, Collection<PsiClassType> result) {
|
||||
final GrField[] fields = grType.getCodeFields();
|
||||
for (GrField field : fields) {
|
||||
final PsiAnnotation delegate = PsiImplUtil.getAnnotation(field, GroovyCommonClassNames.GROOVY_LANG_DELEGATE);
|
||||
if (delegate == null) continue;
|
||||
|
||||
final boolean shouldImplement = shouldImplementDelegatedInterfaces(delegate);
|
||||
if (!shouldImplement) continue;
|
||||
|
||||
final PsiType type = field.getDeclaredType();
|
||||
if (!(type instanceof PsiClassType)) continue;
|
||||
|
||||
final PsiClass psiClass = ((PsiClassType)type).resolve();
|
||||
if (psiClass == null) continue;
|
||||
|
||||
result.addAll(Arrays.asList(psiClass.getImplementsListTypes()));
|
||||
if (psiClass.isInterface()) {
|
||||
result.add((PsiClassType)type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean shouldImplementDelegatedInterfaces(PsiAnnotation delegate) {
|
||||
final Boolean result = GrAnnotationUtil.inferBooleanAttribute(delegate, "interfaces");
|
||||
return result == null || result.booleanValue();
|
||||
}
|
||||
}
|
||||
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright 2000-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.plugins.groovy.lang.resolve.ast;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiClassType;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
public abstract class Members {
|
||||
|
||||
@NotNull
|
||||
public abstract Collection<PsiMethod> getMethods();
|
||||
|
||||
@NotNull
|
||||
public abstract Collection<GrField> getFields();
|
||||
|
||||
@NotNull
|
||||
public abstract Collection<PsiClass> getClasses();
|
||||
|
||||
@NotNull
|
||||
public abstract Collection<PsiClassType> getImplementsTypes();
|
||||
|
||||
public abstract void addFrom(@NotNull Members other);
|
||||
|
||||
public static final Members EMPTY = new Members() {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<PsiMethod> getMethods() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<GrField> getFields() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<PsiClass> getClasses() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<PsiClassType> getImplementsTypes() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFrom(@NotNull Members other) {
|
||||
// do nothing
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
public static Members create() {
|
||||
return new Members() {
|
||||
|
||||
private final Collection<PsiMethod> methods = ContainerUtil.newArrayList();
|
||||
private final Collection<GrField> fields = ContainerUtil.newArrayList();
|
||||
private final Collection<PsiClass> classes = ContainerUtil.newArrayList();
|
||||
private final Collection<PsiClassType> implementsTypes = ContainerUtil.newArrayList();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<PsiMethod> getMethods() {
|
||||
return methods;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<GrField> getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<PsiClass> getClasses() {
|
||||
return classes;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<PsiClassType> getImplementsTypes() {
|
||||
return implementsTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFrom(@NotNull Members other) {
|
||||
methods.addAll(other.getMethods());
|
||||
fields.addAll(other.getFields());
|
||||
classes.addAll(other.getClasses());
|
||||
implementsTypes.addAll(other.getImplementsTypes());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+42
-36
@@ -15,48 +15,54 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.resolve.ast.builder;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.psi.util.PsiModificationTracker;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ast.AstTransformContributor;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ast.builder.GrBuilderStrategySupport.Members;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ast.builder.strategy.DefaultBuilderStrategySupport;
|
||||
|
||||
import java.util.Collection;
|
||||
public abstract class BuilderAnnotationContributor extends AstTransformContributor {
|
||||
|
||||
public class BuilderAnnotationContributor extends AstTransformContributor {
|
||||
public static final String BUILDER_PACKAGE = "groovy.transform.builder";
|
||||
public static final String BUILDER_FQN = BUILDER_PACKAGE + ".Builder";
|
||||
public static final String ORIGIN_INFO = "via @Builder";
|
||||
public static final String STRATEGY_ATTRIBUTE = "builderStrategy";
|
||||
|
||||
@Override
|
||||
public void collectMethods(@NotNull GrTypeDefinition clazz, final Collection<PsiMethod> collector) {
|
||||
collector.addAll(collectAll(clazz).methods);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectClasses(@NotNull GrTypeDefinition clazz, Collection<PsiClass> collector) {
|
||||
collector.addAll(collectAll(clazz).classes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectFields(@NotNull GrTypeDefinition clazz, Collection<GrField> collector) {
|
||||
collector.addAll(collectAll(clazz).fields);
|
||||
}
|
||||
|
||||
private static Members collectAll(final GrTypeDefinition clazz) {
|
||||
return CachedValuesManager.getCachedValue(clazz, new CachedValueProvider<Members>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public Result<Members> compute() {
|
||||
final Members result = new Members();
|
||||
for (GrBuilderStrategySupport strategySupport : GrBuilderStrategySupport.EP.getExtensions()) {
|
||||
result.addFrom(strategySupport.process(clazz));
|
||||
}
|
||||
return Result.create(result, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
|
||||
@Nullable
|
||||
@Contract("null,_ -> null")
|
||||
public static PsiClass getClassAttributeValue(@Nullable PsiAnnotation annotation, @NotNull String attributeName) {
|
||||
if (annotation == null) return null;
|
||||
final PsiAnnotationMemberValue value = annotation.findAttributeValue(attributeName);
|
||||
if (value instanceof GrReferenceExpression) {
|
||||
final PsiElement element = ((GrReferenceExpression)value).resolve();
|
||||
return element instanceof PsiClass ? (PsiClass)element : null;
|
||||
}
|
||||
else if (value instanceof PsiClassObjectAccessExpression) {
|
||||
PsiType type = ((PsiClassObjectAccessExpression)value).getOperand().getType();
|
||||
if (type instanceof PsiClassType) {
|
||||
return ((PsiClassType)type).resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Contract("null, _ -> false")
|
||||
public static boolean isApplicable(@Nullable PsiAnnotation annotation, @NotNull String strategy) {
|
||||
if (annotation == null) return false;
|
||||
final PsiAnnotationMemberValue attributeValue = annotation.findDeclaredAttributeValue(STRATEGY_ATTRIBUTE);
|
||||
if (attributeValue == null) {
|
||||
return strategy == DefaultBuilderStrategySupport.DEFAULT_STRATEGY_NAME;
|
||||
}
|
||||
else {
|
||||
final String value = attributeValue.getText();
|
||||
return strategy.equals(value) || StringUtil.getQualifiedName(BUILDER_PACKAGE, strategy).equals(value);
|
||||
}
|
||||
}
|
||||
|
||||
public static PsiType createType(PsiClass clazz) {
|
||||
return JavaPsiFacade.getElementFactory(clazz.getProject()).createType(clazz);
|
||||
}
|
||||
}
|
||||
|
||||
+12
-7
@@ -16,6 +16,7 @@
|
||||
package org.jetbrains.plugins.groovy.lang.resolve.ast.builder;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiModifier;
|
||||
import com.intellij.psi.impl.light.LightPsiClassBuilder;
|
||||
@@ -24,24 +25,28 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefini
|
||||
|
||||
public class BuilderHelperLightPsiClass extends LightPsiClassBuilder {
|
||||
|
||||
private final @NotNull GrTypeDefinition myContainingClass;
|
||||
|
||||
public BuilderHelperLightPsiClass(@NotNull GrTypeDefinition containingClass, @NotNull String name) {
|
||||
super(containingClass, name);
|
||||
myContainingClass = containingClass;
|
||||
setScope(myContainingClass);
|
||||
setOriginInfo(GrBuilderStrategySupport.ORIGIN_INFO);
|
||||
setScope(containingClass);
|
||||
setContainingClass(containingClass);
|
||||
setOriginInfo(BuilderAnnotationContributor.ORIGIN_INFO);
|
||||
getModifierList().addModifier(PsiModifier.STATIC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getParent() {
|
||||
return getContainingClass();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClass getContainingClass() {
|
||||
return myContainingClass;
|
||||
//noinspection ConstantConditions
|
||||
return super.getContainingClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiFile getContainingFile() {
|
||||
return myContainingClass.getContainingFile();
|
||||
return getContainingClass().getContainingFile();
|
||||
}
|
||||
}
|
||||
|
||||
-64
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-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.plugins.groovy.lang.resolve.ast.builder;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ast.builder.strategy.DefaultBuilderStrategySupport;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public abstract class GrBuilderStrategySupport {
|
||||
|
||||
public static final ExtensionPointName<GrBuilderStrategySupport> EP = ExtensionPointName.create("org.intellij.groovy.builderStrategySupport");
|
||||
public static final String BUILDER_FQN = "groovy.transform.builder.Builder";
|
||||
public static final String ORIGIN_INFO = "by @Builder";
|
||||
|
||||
public static class Members {
|
||||
public final Collection<PsiMethod> methods = ContainerUtil.newArrayList();
|
||||
public final Collection<GrField> fields = ContainerUtil.newArrayList();
|
||||
public final Collection<PsiClass> classes = ContainerUtil.newArrayList();
|
||||
public void addFrom(Members other) {
|
||||
methods.addAll(other.methods);
|
||||
fields.addAll(other.fields);
|
||||
classes.addAll(other.classes);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public abstract Members process(GrTypeDefinition typeDefinition);
|
||||
|
||||
@Nullable
|
||||
public static String getStrategy(PsiModifierListOwner annotatedMember) {
|
||||
final PsiAnnotation annotation = PsiImplUtil.getAnnotation(annotatedMember, BUILDER_FQN);
|
||||
if (annotation == null) return null;
|
||||
|
||||
final PsiAnnotationMemberValue strategy = annotation.findDeclaredAttributeValue("builderStrategy");
|
||||
if (strategy instanceof GrReferenceExpression) {
|
||||
final PsiElement element = ((GrReferenceExpression)strategy).resolve();
|
||||
return element instanceof PsiClass ? ((PsiClass)element).getQualifiedName() : null;
|
||||
}
|
||||
|
||||
return DefaultBuilderStrategySupport.DEFAULT_STRATEGY_FQN;
|
||||
}
|
||||
}
|
||||
+59
-51
@@ -26,15 +26,17 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ast.Members;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ast.builder.BuilderAnnotationContributor;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ast.builder.BuilderHelperLightPsiClass;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ast.builder.GrBuilderStrategySupport;
|
||||
|
||||
public class DefaultBuilderStrategySupport extends GrBuilderStrategySupport {
|
||||
public class DefaultBuilderStrategySupport extends BuilderAnnotationContributor {
|
||||
|
||||
public static final String DEFAULT_STRATEGY_FQN = "groovy.transform.builder.DefaultStrategy";
|
||||
public static final String DEFAULT_STRATEGY_NAME = "DefaultStrategy";
|
||||
|
||||
@NotNull
|
||||
public Members process(@NotNull final GrTypeDefinition typeDefinition) {
|
||||
@Override
|
||||
public Members collect(@NotNull final GrTypeDefinition typeDefinition) {
|
||||
return new DefaultBuilderStrategyHandler(typeDefinition).doProcess();
|
||||
}
|
||||
|
||||
@@ -47,7 +49,7 @@ public class DefaultBuilderStrategySupport extends GrBuilderStrategySupport {
|
||||
private DefaultBuilderStrategyHandler(@NotNull GrTypeDefinition typeDefinition) {
|
||||
myContainingClass = typeDefinition;
|
||||
myElementFactory = PsiElementFactory.SERVICE.getInstance(typeDefinition.getProject());
|
||||
myMembers = new Members();
|
||||
myMembers = Members.create();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -64,11 +66,10 @@ public class DefaultBuilderStrategySupport extends GrBuilderStrategySupport {
|
||||
|
||||
private void processTypeDefinition() {
|
||||
final PsiAnnotation builderAnno = PsiImplUtil.getAnnotation(myContainingClass, BUILDER_FQN);
|
||||
if (builderAnno == null || !DEFAULT_STRATEGY_FQN.equals(getStrategy(myContainingClass))) return;
|
||||
if (!isApplicable(builderAnno, DEFAULT_STRATEGY_NAME)) return;
|
||||
final PsiClass builderClass = createBuilderClass(builderAnno, myContainingClass.getCodeFields());
|
||||
final LightMethodBuilder builderMethod = createBuilderMethod(builderClass, builderAnno);
|
||||
myMembers.classes.add(builderClass);
|
||||
myMembers.methods.add(builderMethod);
|
||||
myMembers.getMethods().add(createBuilderMethod(builderClass, builderAnno));
|
||||
myMembers.getClasses().add(builderClass);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -88,10 +89,9 @@ public class DefaultBuilderStrategySupport extends GrBuilderStrategySupport {
|
||||
builderClass.addMethod(createFieldSetter(builderClass, field, annotation));
|
||||
}
|
||||
|
||||
final LightMethodBuilder buildMethod = new LightMethodBuilder(getManager(), getBuildMethodName(annotation));
|
||||
buildMethod.setContainingClass(builderClass);
|
||||
buildMethod.setOriginInfo(ORIGIN_INFO);
|
||||
buildMethod.setMethodReturnType(builtType == null ? myElementFactory.createType(myContainingClass) : builtType);
|
||||
final LightMethodBuilder buildMethod = createBuildMethod(
|
||||
annotation, builtType == null ? myElementFactory.createType(myContainingClass) : builtType, builderClass
|
||||
);
|
||||
return builderClass.addMethod(buildMethod);
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ public class DefaultBuilderStrategySupport extends GrBuilderStrategySupport {
|
||||
|
||||
private void processMethod(@NotNull GrMethod method) {
|
||||
final PsiAnnotation annotation = PsiImplUtil.getAnnotation(method, BUILDER_FQN);
|
||||
if (annotation == null || !DEFAULT_STRATEGY_FQN.equals(getStrategy(method))) return;
|
||||
if (!isApplicable(annotation, DEFAULT_STRATEGY_NAME)) return;
|
||||
if (method.isConstructor()) {
|
||||
processConstructor(method, annotation);
|
||||
}
|
||||
@@ -125,52 +125,60 @@ public class DefaultBuilderStrategySupport extends GrBuilderStrategySupport {
|
||||
|
||||
private void processConstructor(@NotNull GrMethod method, PsiAnnotation annotation) {
|
||||
PsiClass builderClass = createBuilderClass(annotation, method.getParameters());
|
||||
LightMethodBuilder builderMethod = createBuilderMethod(builderClass, annotation);
|
||||
myMembers.methods.add(builderMethod);
|
||||
myMembers.classes.add(builderClass);
|
||||
myMembers.getMethods().add(createBuilderMethod(builderClass, annotation));
|
||||
myMembers.getClasses().add(builderClass);
|
||||
}
|
||||
|
||||
private void processFactoryMethod(@NotNull GrMethod method, PsiAnnotation annotation) {
|
||||
PsiClass builderClass = createBuilderClass(annotation, method.getParameters(), method.getReturnType());
|
||||
LightMethodBuilder builderMethod = createBuilderMethod(builderClass, annotation);
|
||||
myMembers.methods.add(builderMethod);
|
||||
myMembers.classes.add(builderClass);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private LightMethodBuilder createFieldSetter(@NotNull PsiClass builderClass, @NotNull GrVariable field, @NotNull PsiAnnotation annotation) {
|
||||
final String name = field.getName();
|
||||
final LightMethodBuilder fieldSetter = new LightMethodBuilder(getManager(), getFieldMethodName(annotation, name));
|
||||
fieldSetter.addModifier(PsiModifier.PUBLIC);
|
||||
fieldSetter.addParameter(name, field.getType(), false);
|
||||
fieldSetter.setContainingClass(builderClass);
|
||||
fieldSetter.setMethodReturnType(myElementFactory.createType(builderClass));
|
||||
fieldSetter.setNavigationElement(field);
|
||||
return fieldSetter;
|
||||
myMembers.getMethods().add(createBuilderMethod(builderClass, annotation));
|
||||
myMembers.getClasses().add(builderClass);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getBuilderMethodName(@NotNull PsiAnnotation annotation) {
|
||||
final String builderMethodName = AnnotationUtil.getDeclaredStringAttributeValue(annotation, "builderMethodName");
|
||||
return builderMethodName == null ? "builder" : builderMethodName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getBuilderClassName(@NotNull PsiAnnotation annotation, @NotNull GrTypeDefinition clazz) {
|
||||
final String builderClassName = AnnotationUtil.getDeclaredStringAttributeValue(annotation, "builderClassName");
|
||||
return builderClassName == null ? String.format("%s%s", clazz.getName(), "Builder") : builderClassName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getFieldMethodName(@NotNull PsiAnnotation annotation, @NotNull String fieldName) {
|
||||
final String prefix = AnnotationUtil.getDeclaredStringAttributeValue(annotation, "prefix");
|
||||
return prefix == null ? fieldName : String.format("%s%s", prefix, StringUtil.capitalize(fieldName));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getBuildMethodName(@NotNull PsiAnnotation annotation) {
|
||||
final String buildMethodName = AnnotationUtil.getDeclaredStringAttributeValue(annotation, "buildMethodName");
|
||||
return buildMethodName == null ? "build" : buildMethodName;
|
||||
return StringUtil.isEmpty(builderMethodName) ? "builder" : builderMethodName;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getBuilderClassName(@NotNull PsiAnnotation annotation, @NotNull GrTypeDefinition clazz) {
|
||||
final String builderClassName = AnnotationUtil.getDeclaredStringAttributeValue(annotation, "builderClassName");
|
||||
return builderClassName == null ? String.format("%s%s", clazz.getName(), "Builder") : builderClassName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static LightMethodBuilder createBuildMethod(@NotNull PsiAnnotation annotation, @NotNull PsiType builtType, PsiClass builderClass) {
|
||||
final LightMethodBuilder buildMethod = new LightMethodBuilder(annotation.getManager(), getBuildMethodName(annotation));
|
||||
buildMethod.setContainingClass(builderClass);
|
||||
buildMethod.setOriginInfo(ORIGIN_INFO);
|
||||
buildMethod.setMethodReturnType(builtType);
|
||||
return buildMethod;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static LightMethodBuilder createFieldSetter(@NotNull PsiClass builderClass, @NotNull GrVariable field, @NotNull PsiAnnotation annotation) {
|
||||
final String name = field.getName();
|
||||
final LightMethodBuilder fieldSetter = new LightMethodBuilder(builderClass.getManager(), getFieldMethodName(annotation, name));
|
||||
fieldSetter.addModifier(PsiModifier.PUBLIC);
|
||||
fieldSetter.addParameter(name, field.getType());
|
||||
fieldSetter.setContainingClass(builderClass);
|
||||
fieldSetter.setMethodReturnType(JavaPsiFacade.getElementFactory(builderClass.getProject()).createType(builderClass));
|
||||
fieldSetter.setNavigationElement(field);
|
||||
fieldSetter.setOriginInfo(ORIGIN_INFO);
|
||||
return fieldSetter;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getFieldMethodName(@NotNull PsiAnnotation annotation, @NotNull String fieldName) {
|
||||
final String prefix = AnnotationUtil.getDeclaredStringAttributeValue(annotation, "prefix");
|
||||
return StringUtil.isEmpty(prefix) ? fieldName : String.format("%s%s", prefix, StringUtil.capitalize(fieldName));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getBuildMethodName(@NotNull PsiAnnotation annotation) {
|
||||
final String buildMethodName = AnnotationUtil.getDeclaredStringAttributeValue(annotation, "buildMethodName");
|
||||
return StringUtil.isEmpty(buildMethodName) ? "build" : buildMethodName;
|
||||
}
|
||||
}
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2000-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.plugins.groovy.lang.resolve.ast.builder.strategy;
|
||||
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiAnnotation;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ast.Members;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ast.builder.BuilderAnnotationContributor;
|
||||
|
||||
import static org.jetbrains.plugins.groovy.lang.resolve.ast.builder.strategy.DefaultBuilderStrategySupport.createBuildMethod;
|
||||
import static org.jetbrains.plugins.groovy.lang.resolve.ast.builder.strategy.DefaultBuilderStrategySupport.createFieldSetter;
|
||||
|
||||
public class ExternalBuilderStrategySupport extends BuilderAnnotationContributor {
|
||||
|
||||
public static final String EXTERNAL_STRATEGY_NAME = "ExternalStrategy";
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Members collect(@NotNull GrTypeDefinition builderClass) {
|
||||
Pair<PsiAnnotation, GrTypeDefinition> definitionPair = getConstructedClass(builderClass);
|
||||
if (definitionPair == null) return Members.EMPTY;
|
||||
|
||||
final PsiAnnotation annotation = definitionPair.first;
|
||||
final GrTypeDefinition typeDefinition = definitionPair.second;
|
||||
final Members result = Members.create();
|
||||
for (GrField field : typeDefinition.getCodeFields()) {
|
||||
result.getMethods().add(createFieldSetter(builderClass, field, annotation));
|
||||
}
|
||||
result.getMethods().add(createBuildMethod(annotation, createType(typeDefinition), builderClass));
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Pair<PsiAnnotation, GrTypeDefinition> getConstructedClass(GrTypeDefinition builderClass) {
|
||||
final PsiAnnotation annotation = PsiImplUtil.getAnnotation(builderClass, BUILDER_FQN);
|
||||
if (!isApplicable(annotation, EXTERNAL_STRATEGY_NAME)) return null;
|
||||
final PsiClass constructedClass = getClassAttributeValue(annotation, "forClass");
|
||||
if (!(constructedClass instanceof GrTypeDefinition)) return null;
|
||||
return Pair.create(annotation, (GrTypeDefinition)constructedClass);
|
||||
}
|
||||
}
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright 2000-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.plugins.groovy.lang.resolve.ast.builder.strategy;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.light.LightMethodBuilder;
|
||||
import com.intellij.psi.impl.light.LightPsiClassBuilder;
|
||||
import com.intellij.psi.impl.light.LightTypeParameterBuilder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ast.Members;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ast.builder.BuilderAnnotationContributor;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ast.builder.BuilderHelperLightPsiClass;
|
||||
|
||||
import static org.jetbrains.plugins.groovy.lang.resolve.ast.builder.strategy.DefaultBuilderStrategySupport.getBuilderClassName;
|
||||
import static org.jetbrains.plugins.groovy.lang.resolve.ast.builder.strategy.DefaultBuilderStrategySupport.getFieldMethodName;
|
||||
|
||||
public class InitializerBuilderStrategySupport extends BuilderAnnotationContributor {
|
||||
|
||||
public static final String INITIALIZER_STRATEGY_NAME = "InitializerStrategy";
|
||||
public static final String SET_FQN = "groovy.transform.builder.InitializerStrategy.SET";
|
||||
public static final String UNSET_FQN = "groovy.transform.builder.InitializerStrategy.UNSET";
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Members collect(@NotNull GrTypeDefinition clazz) {
|
||||
return new InitializerBuilderStrategyHandler(clazz).doProcess();
|
||||
}
|
||||
|
||||
private static class InitializerBuilderStrategyHandler {
|
||||
|
||||
private final @NotNull GrTypeDefinition myContainingClass;
|
||||
private final @NotNull PsiElementFactory myElementFactory;
|
||||
private final Members myMembers;
|
||||
|
||||
private InitializerBuilderStrategyHandler(@NotNull GrTypeDefinition typeDefinition) {
|
||||
myContainingClass = typeDefinition;
|
||||
myElementFactory = PsiElementFactory.SERVICE.getInstance(typeDefinition.getProject());
|
||||
myMembers = Members.create();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private PsiManager getManager() {
|
||||
return myContainingClass.getManager();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Members doProcess() {
|
||||
processTypeDefinition();
|
||||
processConstructors();
|
||||
return myMembers;
|
||||
}
|
||||
|
||||
private void processTypeDefinition() {
|
||||
final PsiAnnotation builderAnno = PsiImplUtil.getAnnotation(myContainingClass, BUILDER_FQN);
|
||||
if (!isApplicable(builderAnno, INITIALIZER_STRATEGY_NAME)) return;
|
||||
|
||||
final PsiClass builderClass = createBuilderClass(builderAnno, myContainingClass.getCodeFields());
|
||||
myMembers.getMethods().add(createBuilderMethod(builderClass, builderAnno));
|
||||
myMembers.getMethods().add(createBuilderConstructor(myContainingClass, builderClass, builderAnno));
|
||||
myMembers.getClasses().add(builderClass);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private LightPsiClassBuilder createBuilderClass(@NotNull final PsiAnnotation annotation,
|
||||
@NotNull GrVariable[] setters) {
|
||||
final LightPsiClassBuilder builderClass = new BuilderHelperLightPsiClass(
|
||||
myContainingClass, getBuilderClassName(annotation, myContainingClass)
|
||||
);
|
||||
for (int i = 0; i < setters.length; i++) {
|
||||
builderClass.getTypeParameterList().addParameter(new InitializerTypeParameter(builderClass, i));
|
||||
}
|
||||
for (int i = 0; i < setters.length; i++) {
|
||||
builderClass.addMethod(createFieldSetter(builderClass, setters[i], annotation, i));
|
||||
}
|
||||
return builderClass.addMethod(createBuildMethod(annotation, builderClass));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private LightMethodBuilder createFieldSetter(@NotNull LightPsiClassBuilder builderClass,
|
||||
@NotNull GrVariable field,
|
||||
@NotNull PsiAnnotation annotation,
|
||||
int currentField) {
|
||||
final String name = field.getName();
|
||||
final LightMethodBuilder fieldSetter = new LightMethodBuilder(builderClass.getManager(), getFieldMethodName(annotation, name));
|
||||
final PsiSubstitutor substitutor = PsiSubstitutor.EMPTY.put(
|
||||
builderClass.getTypeParameters()[currentField],
|
||||
myElementFactory.createTypeByFQClassName(SET_FQN, annotation.getResolveScope())
|
||||
);
|
||||
fieldSetter.addModifier(PsiModifier.PUBLIC);
|
||||
fieldSetter.addParameter(name, field.getType());
|
||||
fieldSetter.setContainingClass(builderClass);
|
||||
fieldSetter.setMethodReturnType(myElementFactory.createType(builderClass, substitutor));
|
||||
fieldSetter.setNavigationElement(field);
|
||||
fieldSetter.setOriginInfo(ORIGIN_INFO);
|
||||
return fieldSetter;
|
||||
}
|
||||
|
||||
private LightMethodBuilder createBuildMethod(@NotNull PsiAnnotation annotation, @NotNull PsiClass builderClass) {
|
||||
LightMethodBuilder buildMethod = new LightMethodBuilder(annotation.getManager(), builderClass.getLanguage(), getBuildMethodName(annotation));
|
||||
buildMethod.addModifier(PsiModifier.STATIC);
|
||||
buildMethod.setContainingClass(builderClass);
|
||||
buildMethod.setOriginInfo(ORIGIN_INFO);
|
||||
buildMethod.setNavigationElement(annotation);
|
||||
buildMethod.setMethodReturnType(createAllSetUnsetType(builderClass, false));
|
||||
return buildMethod;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private LightMethodBuilder createBuilderMethod(@NotNull PsiClass builderClass, @NotNull PsiAnnotation annotation) {
|
||||
final LightMethodBuilder builderMethod = new LightMethodBuilder(getManager(), getBuilderMethodName(annotation));
|
||||
builderMethod.addModifier(PsiModifier.STATIC);
|
||||
builderMethod.setContainingClass(myContainingClass);
|
||||
builderMethod.setOriginInfo(ORIGIN_INFO);
|
||||
builderMethod.setNavigationElement(annotation);
|
||||
builderMethod.setMethodReturnType(createAllSetUnsetType(builderClass, false));
|
||||
return builderMethod;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private LightMethodBuilder createBuilderConstructor(@NotNull PsiClass constructedClass, @NotNull PsiClass builderClass, PsiAnnotation annotation) {
|
||||
final LightMethodBuilder constructor = new LightMethodBuilder(constructedClass, constructedClass.getLanguage()).addParameter(
|
||||
"builder", createAllSetUnsetType(builderClass, true)
|
||||
).setConstructor(true);
|
||||
constructor.setNavigationElement(annotation);
|
||||
constructor.setOriginInfo(ORIGIN_INFO);
|
||||
return constructor;
|
||||
}
|
||||
|
||||
private void processConstructors() {
|
||||
for (GrMethod method : myContainingClass.getCodeMethods()) {
|
||||
final PsiAnnotation annotation = PsiImplUtil.getAnnotation(method, BUILDER_FQN);
|
||||
if (!isApplicable(annotation, INITIALIZER_STRATEGY_NAME)) return;
|
||||
if (method.isConstructor()) {
|
||||
processConstructor(method, annotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processConstructor(@NotNull GrMethod method, PsiAnnotation annotation) {
|
||||
PsiClass builderClass = createBuilderClass(annotation, method.getParameters());
|
||||
myMembers.getMethods().add(createBuilderMethod(builderClass, annotation));
|
||||
myMembers.getMethods().add(createBuilderConstructor(myContainingClass, builderClass, annotation));
|
||||
myMembers.getClasses().add(builderClass);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getBuilderMethodName(@NotNull PsiAnnotation annotation) {
|
||||
final String builderMethodName = AnnotationUtil.getDeclaredStringAttributeValue(annotation, "builderMethodName");
|
||||
return StringUtil.isEmpty(builderMethodName) ? "createInitializer" : builderMethodName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getBuildMethodName(@NotNull PsiAnnotation annotation) {
|
||||
final String builderMethodName = AnnotationUtil.getDeclaredStringAttributeValue(annotation, "buildMethodName");
|
||||
return StringUtil.isEmpty(builderMethodName) ? "create" : builderMethodName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private PsiType createAllSetUnsetType(@NotNull PsiClass builderClass, boolean setUnset) {
|
||||
final PsiClassType type = myElementFactory.createTypeByFQClassName(
|
||||
setUnset ? SET_FQN : UNSET_FQN,
|
||||
builderClass.getResolveScope()
|
||||
);
|
||||
final PsiType[] mappings = PsiType.createArray(builderClass.getTypeParameters().length);
|
||||
for (int i = 0; i < mappings.length; i++) {
|
||||
mappings[i] = type;
|
||||
}
|
||||
return myElementFactory.createType(builderClass, mappings);
|
||||
}
|
||||
}
|
||||
|
||||
private static class InitializerTypeParameter extends LightTypeParameterBuilder {
|
||||
|
||||
public InitializerTypeParameter(PsiTypeParameterListOwner owner, int index) {
|
||||
super("T" + index, owner, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2000-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.plugins.groovy.lang.resolve.ast.builder.strategy;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiAnnotation;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiModifier;
|
||||
import com.intellij.psi.impl.light.LightMethodBuilder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ast.Members;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ast.builder.BuilderAnnotationContributor;
|
||||
|
||||
public class SimpleBuilderStrategySupport extends BuilderAnnotationContributor {
|
||||
|
||||
public static final String SIMPLE_STRATEGY_NAME = "SimpleStrategy";
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Members collect(@NotNull GrTypeDefinition typeDefinition) {
|
||||
final PsiAnnotation annotation = PsiImplUtil.getAnnotation(typeDefinition, BUILDER_FQN);
|
||||
if (!isApplicable(annotation, SIMPLE_STRATEGY_NAME)) return Members.EMPTY;
|
||||
final Members result = Members.create();
|
||||
for (GrField field : typeDefinition.getCodeFields()) {
|
||||
result.getMethods().add(createFieldSetter(typeDefinition, field, annotation));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static LightMethodBuilder createFieldSetter(@NotNull PsiClass builderClass, @NotNull GrVariable field, @NotNull PsiAnnotation annotation) {
|
||||
final String name = field.getName();
|
||||
final LightMethodBuilder fieldSetter = new LightMethodBuilder(builderClass.getManager(), getFieldMethodName(annotation, name));
|
||||
fieldSetter.addModifier(PsiModifier.PUBLIC);
|
||||
fieldSetter.addParameter(name, field.getType(), false);
|
||||
fieldSetter.setContainingClass(builderClass);
|
||||
fieldSetter.setMethodReturnType(createType(builderClass));
|
||||
fieldSetter.setNavigationElement(field);
|
||||
fieldSetter.setOriginInfo(ORIGIN_INFO);
|
||||
return fieldSetter;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getFieldMethodName(@NotNull PsiAnnotation annotation, @NotNull String fieldName) {
|
||||
final String prefix = AnnotationUtil.getDeclaredStringAttributeValue(annotation, "prefix");
|
||||
return prefix == null ? "set" + StringUtil.capitalize(fieldName)
|
||||
: prefix.isEmpty() ? fieldName
|
||||
: prefix + StringUtil.capitalize(fieldName);
|
||||
}
|
||||
}
|
||||
@@ -107,15 +107,16 @@
|
||||
|
||||
<closureMissingMethodContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.PluginXmlClosureMemberContributor"/>
|
||||
|
||||
<astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.psi.impl.statements.typedef.GrTypeDefinitionMembersCache$TraitCollector"/>
|
||||
<astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.DelegatedMethodsContributor"/>
|
||||
<astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.AutoExternalizeContributor"/>
|
||||
<astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.AutoCloneContributor"/>
|
||||
<astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.ConstructorAnnotationsProcessor"/>
|
||||
<astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.GrInheritConstructorContributor"/>
|
||||
<astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.LoggingContributor"/>
|
||||
<astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.builder.BuilderAnnotationContributor"/>
|
||||
<builderStrategySupport implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.builder.strategy.DefaultBuilderStrategySupport"/>
|
||||
<astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.builder.strategy.DefaultBuilderStrategySupport"/>
|
||||
<astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.builder.strategy.SimpleBuilderStrategySupport"/>
|
||||
<astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.builder.strategy.ExternalBuilderStrategySupport"/>
|
||||
<astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.builder.strategy.InitializerBuilderStrategySupport"/>
|
||||
|
||||
<positionManagerDelegate implementation="org.jetbrains.plugins.groovy.gant.GantPositionManagerHelper"/>
|
||||
|
||||
|
||||
+4
-4
@@ -263,9 +263,9 @@ public class CreateParameterForFieldIntention extends Intention {
|
||||
return findCandidatesCached(constructor, (GrTypeDefinition)clazz);
|
||||
}
|
||||
|
||||
private static List<GrField> findCandidates(GrMethod constructor, final GrTypeDefinition clazz) {
|
||||
private static List<GrField> findCandidates(PsiMethod constructor, final GrTypeDefinition clazz) {
|
||||
final List<GrField> usedFields = new ArrayList<GrField>();
|
||||
final GrOpenBlock block = constructor.getBlock();
|
||||
final GrOpenBlock block = constructor instanceof GrMethod ? ((GrMethod)constructor).getBlock() : null;
|
||||
if (block == null) {
|
||||
return usedFields;
|
||||
}
|
||||
@@ -308,7 +308,7 @@ public class CreateParameterForFieldIntention extends Intention {
|
||||
return fields;
|
||||
}
|
||||
|
||||
private static List<GrField> findCandidatesCached(final GrMethod constructor, final GrTypeDefinition clazz) {
|
||||
private static List<GrField> findCandidatesCached(final PsiMethod constructor, final GrTypeDefinition clazz) {
|
||||
final CachedValue<List<GrField>> value = constructor.getUserData(FIELD_CANDIDATES);
|
||||
if (value != null && value.getValue() != null) return value.getValue();
|
||||
final CachedValue<List<GrField>> cachedValue =
|
||||
@@ -335,7 +335,7 @@ public class CreateParameterForFieldIntention extends Intention {
|
||||
final PsiMethod[] constructors = psiClass.getConstructors();
|
||||
final PsiManager manager = field.getManager();
|
||||
for (PsiMethod constructor : constructors) {
|
||||
final List<GrField> fields = findCandidatesCached(((GrMethod)constructor), psiClass);
|
||||
final List<GrField> fields = findCandidatesCached(constructor, psiClass);
|
||||
if (ContainerUtil.find(fields, new Condition<GrField>() {
|
||||
@Override
|
||||
public boolean value(GrField grField) {
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2000-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.plugins.groovy.completion.builder
|
||||
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
import groovy.transform.CompileStatic
|
||||
import org.jetbrains.annotations.NotNull
|
||||
import org.jetbrains.plugins.groovy.GroovyLightProjectDescriptor
|
||||
import org.jetbrains.plugins.groovy.completion.CompletionResult
|
||||
import org.jetbrains.plugins.groovy.completion.GroovyCompletionTestBase
|
||||
|
||||
import static com.intellij.codeInsight.completion.CompletionType.BASIC
|
||||
|
||||
@CompileStatic
|
||||
abstract class GrBuilderTransformationCompletionTestBase extends GroovyCompletionTestBase {
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
return GroovyLightProjectDescriptor.GROOVY_2_3_9;
|
||||
}
|
||||
|
||||
void doVariantableTest(String text, String... args) {
|
||||
doVariantableTest(text, CompletionResult.contain, args)
|
||||
}
|
||||
|
||||
void doVariantableTest(String text, CompletionResult cr, String... args) {
|
||||
doVariantableTest(text, '', BASIC, cr, 1, args)
|
||||
}
|
||||
}
|
||||
+254
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
* Copyright 2000-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.plugins.groovy.completion.builder
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class GrDefaultBuilderStrategyOnConstructorTest extends GrBuilderTransformationCompletionTestBase {
|
||||
|
||||
void 'test no builder method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class PojoConstructor {
|
||||
@Builder(builderStrategy = DefaultStrategy)
|
||||
PojoConstructor(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
PojoConstructor.<caret>
|
||||
''', 'builder'
|
||||
}
|
||||
|
||||
void 'test custom builder method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class PojoConstructor {
|
||||
@Builder(builderStrategy = DefaultStrategy, builderMethodName = 'customBuilderMethod')
|
||||
PojoConstructor(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
PojoConstructor.<caret>
|
||||
''', 'customBuilderMethod'
|
||||
}
|
||||
|
||||
/**
|
||||
* The class even won't be compiled.
|
||||
* Separate inspection highlights such code and offers to remove the parameter.
|
||||
*/
|
||||
void 'test null builder method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class PojoConstructor {
|
||||
@Builder(builderStrategy = DefaultStrategy, builderMethodName = null)
|
||||
PojoConstructor(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
PojoConstructor.<caret>
|
||||
''', 'builder'
|
||||
}
|
||||
|
||||
/**
|
||||
* Class will be compiled but there will be runtime error.
|
||||
*/
|
||||
void 'test empty builder method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class PojoConstructor {
|
||||
@Builder(builderStrategy = DefaultStrategy, builderMethodName = '')
|
||||
PojoConstructor(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
PojoConstructor.<caret>
|
||||
''', 'builder'
|
||||
}
|
||||
|
||||
void 'test spaces builder method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class PojoConstructor {
|
||||
@Builder(builderStrategy = DefaultStrategy, builderMethodName = ' ')
|
||||
PojoConstructor(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
PojoConstructor.<caret>
|
||||
''', ' '
|
||||
}
|
||||
|
||||
void 'test no prefix'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class PojoConstructor {
|
||||
@Builder(builderStrategy = DefaultStrategy)
|
||||
PojoConstructor(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
PojoConstructor.builder().<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
|
||||
void 'test empty prefix'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class PojoConstructor {
|
||||
@Builder(builderStrategy = DefaultStrategy, prefix = '')
|
||||
PojoConstructor(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
PojoConstructor.builder().<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test custom prefix'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class PojoConstructor {
|
||||
@Builder(builderStrategy = DefaultStrategy, prefix = 'customPrefix')
|
||||
PojoConstructor(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
PojoConstructor.builder().<caret>
|
||||
''', 'build', 'customPrefixName', 'customPrefixDynamic', 'customPrefixCounter'
|
||||
}
|
||||
|
||||
void 'test spaces prefix'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class PojoConstructor {
|
||||
@Builder(builderStrategy = DefaultStrategy, prefix = ' ')
|
||||
PojoConstructor(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
PojoConstructor.builder().<caret>
|
||||
''', 'build', ' Name', ' Dynamic', ' Counter'
|
||||
}
|
||||
|
||||
void 'test null prefix'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class PojoConstructor {
|
||||
@Builder(builderStrategy = DefaultStrategy, prefix = null)
|
||||
PojoConstructor(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
PojoConstructor.builder().<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test custom build method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class PojoConstructor {
|
||||
@Builder(builderStrategy = DefaultStrategy, buildMethodName = 'customBuild')
|
||||
PojoConstructor(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
PojoConstructor.builder().<caret>
|
||||
''', 'customBuild', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test null build method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class PojoConstructor {
|
||||
@Builder(builderStrategy = DefaultStrategy, buildMethodName = null)
|
||||
PojoConstructor(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
PojoConstructor.builder().<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test empty build method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class PojoConstructor {
|
||||
@Builder(builderStrategy = DefaultStrategy, buildMethodName = '')
|
||||
PojoConstructor(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
PojoConstructor.builder().<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test spaces build method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class PojoConstructor {
|
||||
@Builder(builderStrategy = DefaultStrategy, buildMethodName = ' ')
|
||||
PojoConstructor(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
PojoConstructor.builder().<caret>
|
||||
''', ' ', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test next setter'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class PojoConstructor {
|
||||
@Builder(builderStrategy = DefaultStrategy)
|
||||
PojoConstructor(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
PojoConstructor.builder().counter(1).<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test one more setter further'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class PojoConstructor {
|
||||
@Builder(builderStrategy = DefaultStrategy)
|
||||
PojoConstructor(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
PojoConstructor.builder().counter(1).name("Janet").<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
}
|
||||
+260
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Copyright 2000-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.plugins.groovy.completion.builder
|
||||
|
||||
class GrDefaultBuilderStrategyOnFactoryMethodTest extends GrBuilderTransformationCompletionTestBase {
|
||||
|
||||
void 'test no builder method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = DefaultStrategy)
|
||||
static Pojo someLongMethodName(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
Pojo.<caret>
|
||||
''', 'builder'
|
||||
}
|
||||
|
||||
void 'test custom builder method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = DefaultStrategy, builderMethodName = 'customBuilderMethod')
|
||||
static Pojo someLongMethodName(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
Pojo.<caret>
|
||||
''', 'customBuilderMethod'
|
||||
}
|
||||
|
||||
void 'test null builder method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = DefaultStrategy, builderMethodName = null)
|
||||
static Pojo someLongMethodName(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
Pojo.<caret>
|
||||
''', 'builder'
|
||||
}
|
||||
|
||||
void 'test empty builder method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = DefaultStrategy, builderMethodName = '')
|
||||
static Pojo someLongMethodName(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
Pojo.<caret>
|
||||
''', 'builder'
|
||||
}
|
||||
|
||||
void 'test spaces builder method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = DefaultStrategy, builderMethodName = ' ')
|
||||
static Pojo someLongMethodName(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
Pojo.<caret>
|
||||
''', ' '
|
||||
}
|
||||
|
||||
void 'test no prefix'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = DefaultStrategy)
|
||||
static Pojo someLongMethodName(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
Pojo.builder().<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
|
||||
void 'test empty prefix'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = DefaultStrategy, prefix = '')
|
||||
static Pojo someLongMethodName(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
Pojo.builder().<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test custom prefix'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = DefaultStrategy, prefix = 'customPrefix')
|
||||
static Pojo someLongMethodName(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
Pojo.builder().<caret>
|
||||
''', 'build', 'customPrefixName', 'customPrefixDynamic', 'customPrefixCounter'
|
||||
}
|
||||
|
||||
void 'test spaces prefix'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = DefaultStrategy, prefix = ' ')
|
||||
static Pojo someLongMethodName(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
Pojo.builder().<caret>
|
||||
''', 'build', ' Name', ' Dynamic', ' Counter'
|
||||
}
|
||||
|
||||
void 'test null prefix'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = DefaultStrategy, prefix = null)
|
||||
static Pojo someLongMethodName(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
Pojo.builder().<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test custom build method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = DefaultStrategy, buildMethodName = 'customBuild')
|
||||
static Pojo someLongMethodName(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
Pojo.builder().<caret>
|
||||
''', 'customBuild', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test null build method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = DefaultStrategy, buildMethodName = null)
|
||||
static Pojo someLongMethodName(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
Pojo.builder().<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test empty build method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = DefaultStrategy, buildMethodName = '')
|
||||
static Pojo someLongMethodName(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
Pojo.builder().<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test spaces build method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = DefaultStrategy, buildMethodName = ' ')
|
||||
static Pojo someLongMethodName(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
Pojo.builder().<caret>
|
||||
''', ' ', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test next setter'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = DefaultStrategy)
|
||||
static Pojo someLongMethodName(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
Pojo.builder().counter(1).<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test one more setter further'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = DefaultStrategy)
|
||||
static Pojo someLongMethodName(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
Pojo.builder().counter(1).name("Janet").<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test other return type'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.DefaultStrategy
|
||||
|
||||
class OtherClass { def a,b,c }
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = DefaultStrategy)
|
||||
static OtherClass someLongMethodName(def dynamic, int counter, String name) {}
|
||||
}
|
||||
|
||||
Pojo.builder().build().<caret>
|
||||
''', 'a', 'b', 'c'
|
||||
}
|
||||
}
|
||||
+305
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
* Copyright 2000-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.plugins.groovy.completion.builder
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class GrDefaultBuilderStrategyTest extends GrBuilderTransformationCompletionTestBase {
|
||||
|
||||
void "test no builder method"() {
|
||||
doVariantableTest('''\
|
||||
import groovy.transform.builder.Builder
|
||||
|
||||
@Builder
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.<caret>
|
||||
''', 'builder')
|
||||
}
|
||||
|
||||
void 'test custom builder method'() {
|
||||
doVariantableTest('''\
|
||||
import groovy.transform.builder.Builder
|
||||
|
||||
@Builder(builderMethodName = 'customBuilderMethod')
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.<caret>
|
||||
''', 'customBuilderMethod')
|
||||
}
|
||||
|
||||
/**
|
||||
* The class even won't be compiled.
|
||||
* Separate inspection highlights such code and offers to remove the parameter.
|
||||
*/
|
||||
void 'test null builder method'() {
|
||||
doVariantableTest('''\
|
||||
import groovy.transform.builder.Builder
|
||||
|
||||
@Builder(builderMethodName = null)
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.b<caret>
|
||||
''', 'builder')
|
||||
}
|
||||
|
||||
/**
|
||||
* Class will be compiled but there will be runtime error.
|
||||
*/
|
||||
void 'test empty builder method'() {
|
||||
doVariantableTest('''\
|
||||
import groovy.transform.builder.Builder
|
||||
|
||||
@Builder(builderMethodName = '')
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.<caret>
|
||||
''', 'builder')
|
||||
}
|
||||
|
||||
/**
|
||||
* I do not know what to say here!
|
||||
*/
|
||||
void 'test spaces builder method'() {
|
||||
doVariantableTest('''\
|
||||
import groovy.transform.builder.Builder
|
||||
|
||||
@Builder(builderMethodName = ' ')
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.<caret>
|
||||
''', ' ')
|
||||
}
|
||||
|
||||
void 'test no prefix'() {
|
||||
doVariantableTest('''\
|
||||
import groovy.transform.builder.Builder
|
||||
|
||||
@Builder
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.builder().<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter')
|
||||
}
|
||||
|
||||
|
||||
void 'test empty prefix'() {
|
||||
doVariantableTest('''\
|
||||
import groovy.transform.builder.Builder
|
||||
|
||||
@Builder(prefix = '')
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.builder().<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter')
|
||||
}
|
||||
|
||||
void 'test custom prefix'() {
|
||||
doVariantableTest('''\
|
||||
import groovy.transform.builder.Builder
|
||||
|
||||
@Builder(prefix = 'customPrefix')
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.builder().<caret>
|
||||
''', 'build', 'customPrefixName', 'customPrefixDynamic', 'customPrefixCounter')
|
||||
}
|
||||
|
||||
void 'test spaces prefix'() {
|
||||
doVariantableTest('''\
|
||||
import groovy.transform.builder.Builder
|
||||
|
||||
@Builder(prefix = ' ')
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.builder().<caret>
|
||||
''', 'build', ' Name', ' Dynamic', ' Counter')
|
||||
}
|
||||
|
||||
void 'test null prefix'() {
|
||||
doVariantableTest('''\
|
||||
import groovy.transform.builder.Builder
|
||||
|
||||
@Builder(prefix = null)
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.builder().<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter')
|
||||
}
|
||||
|
||||
void 'test custom build method'() {
|
||||
doVariantableTest('''\
|
||||
import groovy.transform.builder.Builder
|
||||
|
||||
@Builder(buildMethodName = 'customBuild')
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.builder().<caret>
|
||||
''', 'customBuild', 'name', 'dynamic', 'counter')
|
||||
}
|
||||
|
||||
void 'test null build method'() {
|
||||
doVariantableTest('''\
|
||||
import groovy.transform.builder.Builder
|
||||
|
||||
@Builder(buildMethodName = null)
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.builder().<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter')
|
||||
}
|
||||
|
||||
void 'test empty build method'() {
|
||||
doVariantableTest('''\
|
||||
import groovy.transform.builder.Builder
|
||||
|
||||
@Builder(buildMethodName = '')
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.builder().<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter')
|
||||
}
|
||||
|
||||
void 'test spaces build method'() {
|
||||
doVariantableTest('''\
|
||||
import groovy.transform.builder.Builder
|
||||
|
||||
@Builder(buildMethodName = ' ')
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.builder().<caret>
|
||||
''', ' ', 'name', 'dynamic', 'counter')
|
||||
}
|
||||
|
||||
void 'test next setter'() {
|
||||
doVariantableTest('''\
|
||||
import groovy.transform.builder.Builder
|
||||
|
||||
@Builder
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.builder().counter(1).<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter')
|
||||
}
|
||||
|
||||
void 'test one more setter further'() {
|
||||
doVariantableTest('''\
|
||||
import groovy.transform.builder.Builder
|
||||
|
||||
@Builder
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.builder().counter(1).name("Janet").<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter')
|
||||
}
|
||||
}
|
||||
+266
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
* Copyright 2000-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.plugins.groovy.completion.builder
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import org.jetbrains.plugins.groovy.completion.CompletionResult
|
||||
|
||||
@CompileStatic
|
||||
class GrExternalBuilderStrategyTest extends GrBuilderTransformationCompletionTestBase {
|
||||
|
||||
void 'test no class'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.ExternalStrategy
|
||||
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
@Builder(builderStrategy = ExternalStrategy)
|
||||
class PojoBuilder {}
|
||||
|
||||
new PojoBuilder().<caret>
|
||||
''', CompletionResult.notContain, 'build', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test no prefix'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.ExternalStrategy
|
||||
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
@Builder(builderStrategy = ExternalStrategy, forClass = Pojo)
|
||||
class PojoBuilder {}
|
||||
|
||||
new PojoBuilder().<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
|
||||
void 'test empty prefix'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.ExternalStrategy
|
||||
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
@Builder(builderStrategy = ExternalStrategy, forClass = Pojo, prefix = '')
|
||||
class PojoBuilder {}
|
||||
|
||||
new PojoBuilder().<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test custom prefix'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.ExternalStrategy
|
||||
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
@Builder(builderStrategy = ExternalStrategy, forClass = Pojo, prefix = 'customPrefix')
|
||||
class PojoBuilder {}
|
||||
|
||||
new PojoBuilder().<caret>
|
||||
''', 'build', 'customPrefixName', 'customPrefixDynamic', 'customPrefixCounter'
|
||||
}
|
||||
|
||||
void 'test spaces prefix'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.ExternalStrategy
|
||||
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
@Builder(builderStrategy = ExternalStrategy, forClass = Pojo, prefix = ' ')
|
||||
class PojoBuilder {}
|
||||
|
||||
new PojoBuilder().<caret>
|
||||
''', 'build', ' Name', ' Dynamic', ' Counter'
|
||||
}
|
||||
|
||||
void 'test null prefix'() {
|
||||
doVariantableTest('''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.ExternalStrategy
|
||||
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
@Builder(builderStrategy = ExternalStrategy, forClass = Pojo, prefix = null)
|
||||
class PojoBuilder {}
|
||||
|
||||
new PojoBuilder().<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter')
|
||||
}
|
||||
|
||||
void 'test custom build method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.ExternalStrategy
|
||||
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
@Builder(builderStrategy = ExternalStrategy, forClass = Pojo, buildMethodName = 'customBuild')
|
||||
class PojoBuilder {}
|
||||
|
||||
new PojoBuilder().<caret>
|
||||
''', 'customBuild', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test null build method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.ExternalStrategy
|
||||
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
@Builder(builderStrategy = ExternalStrategy, forClass = Pojo, buildMethodName = null)
|
||||
class PojoBuilder {}
|
||||
|
||||
new PojoBuilder().<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test empty build method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.ExternalStrategy
|
||||
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
@Builder(builderStrategy = ExternalStrategy, forClass = Pojo, buildMethodName = '')
|
||||
class PojoBuilder {}
|
||||
|
||||
new PojoBuilder().<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test spaces build method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.ExternalStrategy
|
||||
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
@Builder(builderStrategy = ExternalStrategy, forClass = Pojo, buildMethodName = ' ')
|
||||
class PojoBuilder {}
|
||||
|
||||
new PojoBuilder().<caret>
|
||||
''', ' ', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test next setter'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.ExternalStrategy
|
||||
|
||||
@Builder
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
@Builder(builderStrategy = ExternalStrategy, forClass = Pojo)
|
||||
class PojoBuilder {}
|
||||
|
||||
new PojoBuilder().counter(1).<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test one more setter further'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.ExternalStrategy
|
||||
|
||||
@Builder
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
@Builder(builderStrategy = ExternalStrategy, forClass = Pojo)
|
||||
class PojoBuilder {}
|
||||
|
||||
new PojoBuilder().counter(1).name("Janet").<caret>
|
||||
''', 'build', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
}
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright 2000-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.plugins.groovy.completion.builder
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class GrInitializerBuilderStrategyOnConstructorTest extends GrBuilderTransformationCompletionTestBase {
|
||||
|
||||
void 'test no builder method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.InitializerStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = InitializerStrategy)
|
||||
Pojo(name, dynamic, counter) {}
|
||||
}
|
||||
|
||||
Pojo.<caret>
|
||||
''', 'createInitializer'
|
||||
}
|
||||
|
||||
void 'test custom builder method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.InitializerStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = InitializerStrategy, builderMethodName = 'customBuilderMethod')
|
||||
Pojo(name, dynamic, counter) {}
|
||||
}
|
||||
|
||||
Pojo.<caret>
|
||||
''', 'customBuilderMethod'
|
||||
}
|
||||
|
||||
void 'test null builder method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.InitializerStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = InitializerStrategy, builderMethodName = null)
|
||||
Pojo(name, dynamic, counter) {}
|
||||
}
|
||||
|
||||
Pojo.<caret>
|
||||
''', 'createInitializer'
|
||||
}
|
||||
|
||||
void 'test empty builder method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.InitializerStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = InitializerStrategy, builderMethodName = '')
|
||||
Pojo(name, dynamic, counter) {}
|
||||
}
|
||||
|
||||
Pojo.<caret>
|
||||
''', 'createInitializer'
|
||||
}
|
||||
|
||||
void 'test spaces builder method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.InitializerStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = InitializerStrategy, builderMethodName = ' ')
|
||||
Pojo(name, dynamic, counter) {}
|
||||
}
|
||||
|
||||
Pojo.<caret>
|
||||
''', ' '
|
||||
}
|
||||
|
||||
void 'test empty prefix'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.InitializerStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = InitializerStrategy, prefix = '')
|
||||
Pojo(name, dynamic, counter) {}
|
||||
}
|
||||
|
||||
Pojo.createInitializer().<caret>
|
||||
''', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test custom prefix'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.InitializerStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = InitializerStrategy, prefix = 'customPrefix')
|
||||
Pojo(name, dynamic, counter) {}
|
||||
}
|
||||
|
||||
Pojo.createInitializer().<caret>
|
||||
''', 'customPrefixName', 'customPrefixDynamic', 'customPrefixCounter'
|
||||
}
|
||||
|
||||
void 'test spaces prefix'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.InitializerStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = InitializerStrategy, prefix = ' ')
|
||||
Pojo(name, dynamic, counter) {}
|
||||
}
|
||||
|
||||
|
||||
Pojo.createInitializer().<caret>
|
||||
''', ' Name', ' Dynamic', ' Counter'
|
||||
}
|
||||
|
||||
void 'test null prefix'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.InitializerStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = InitializerStrategy, prefix = null)
|
||||
Pojo(name, dynamic, counter) {}
|
||||
}
|
||||
|
||||
|
||||
Pojo.createInitializer().<caret>
|
||||
''', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test next setter'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.InitializerStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = InitializerStrategy)
|
||||
Pojo(name, dynamic, counter) {}
|
||||
}
|
||||
|
||||
|
||||
Pojo.createInitializer().counter(1).<caret>
|
||||
''', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test one more setter further'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.InitializerStrategy
|
||||
|
||||
class Pojo {
|
||||
@Builder(builderStrategy = InitializerStrategy)
|
||||
Pojo(name, dynamic, counter) {}
|
||||
}
|
||||
|
||||
|
||||
Pojo.createInitializer().counter(1).name("Janet").<caret>
|
||||
''', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
}
|
||||
+220
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright 2000-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.plugins.groovy.completion.builder
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class GrInitializerBuilderStrategyTest extends GrBuilderTransformationCompletionTestBase {
|
||||
|
||||
void 'test no builder method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.InitializerStrategy
|
||||
|
||||
@Builder(builderStrategy = InitializerStrategy)
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.<caret>
|
||||
''', 'createInitializer'
|
||||
}
|
||||
|
||||
void 'test custom builder method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.InitializerStrategy
|
||||
|
||||
@Builder(builderStrategy = InitializerStrategy, builderMethodName = 'customBuilderMethod')
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.<caret>
|
||||
''', 'customBuilderMethod'
|
||||
}
|
||||
|
||||
void 'test null builder method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.InitializerStrategy
|
||||
|
||||
@Builder(builderStrategy = InitializerStrategy, builderMethodName = null)
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.<caret>
|
||||
''', 'createInitializer'
|
||||
}
|
||||
|
||||
void 'test empty builder method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.InitializerStrategy
|
||||
|
||||
@Builder(builderStrategy = InitializerStrategy, builderMethodName = '')
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.<caret>
|
||||
''', 'createInitializer'
|
||||
}
|
||||
|
||||
void 'test spaces builder method'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.InitializerStrategy
|
||||
|
||||
@Builder(builderStrategy = InitializerStrategy, builderMethodName = ' ')
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.<caret>
|
||||
''', ' '
|
||||
}
|
||||
|
||||
void 'test empty prefix'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.InitializerStrategy
|
||||
|
||||
@Builder(builderStrategy = InitializerStrategy, prefix = '')
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.createInitializer().<caret>
|
||||
''', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test custom prefix'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.InitializerStrategy
|
||||
|
||||
@Builder(builderStrategy = InitializerStrategy, prefix = 'customPrefix')
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.createInitializer().<caret>
|
||||
''', 'customPrefixName', 'customPrefixDynamic', 'customPrefixCounter'
|
||||
}
|
||||
|
||||
void 'test spaces prefix'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.InitializerStrategy
|
||||
|
||||
@Builder(builderStrategy = InitializerStrategy, prefix = ' ')
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.createInitializer().<caret>
|
||||
''', ' Name', ' Dynamic', ' Counter'
|
||||
}
|
||||
|
||||
void 'test null prefix'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.InitializerStrategy
|
||||
|
||||
@Builder(builderStrategy = InitializerStrategy, prefix = null)
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.createInitializer().<caret>
|
||||
''', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test next setter'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.InitializerStrategy
|
||||
|
||||
@Builder(builderStrategy = InitializerStrategy)
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.createInitializer().counter(1).<caret>
|
||||
''', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
|
||||
void 'test one more setter further'() {
|
||||
doVariantableTest '''\
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.InitializerStrategy
|
||||
|
||||
@Builder(builderStrategy = InitializerStrategy)
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
Pojo.createInitializer().counter(1).name("Janet").<caret>
|
||||
''', 'name', 'dynamic', 'counter'
|
||||
}
|
||||
}
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright 2000-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.plugins.groovy.completion.builder
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import org.jetbrains.plugins.groovy.completion.CompletionResult
|
||||
|
||||
@CompileStatic
|
||||
class GrSimpleBuilderStrategyTest extends GrBuilderTransformationCompletionTestBase {
|
||||
|
||||
void 'test no prefix'() {
|
||||
doVariantableTest('''
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.SimpleStrategy
|
||||
|
||||
@Builder(builderStrategy = SimpleStrategy)
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
new Pojo().<caret>
|
||||
''', 'setName', 'setDynamic', 'setCounter', 'method')
|
||||
|
||||
doVariantableTest('''
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.SimpleStrategy
|
||||
|
||||
@Builder(builderStrategy = SimpleStrategy)
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
new Pojo().<caret>
|
||||
''', CompletionResult.notContain, 'build')
|
||||
}
|
||||
|
||||
void 'test empty prefix'() {
|
||||
doVariantableTest('''
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.SimpleStrategy
|
||||
|
||||
@Builder(builderStrategy = SimpleStrategy, prefix = '')
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
new Pojo().<caret>
|
||||
''', 'name', 'dynamic', 'counter', 'method')
|
||||
}
|
||||
|
||||
void 'test custom prefix'() {
|
||||
doVariantableTest '''
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.SimpleStrategy
|
||||
|
||||
@Builder(builderStrategy = SimpleStrategy, prefix = 'custom')
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
new Pojo().<caret>
|
||||
''', 'customName', 'customDynamic', 'customCounter', 'method'
|
||||
}
|
||||
|
||||
void 'test null prefix'() {
|
||||
doVariantableTest '''
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.SimpleStrategy
|
||||
|
||||
@Builder(builderStrategy = SimpleStrategy, prefix = null)
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
new Pojo().<caret>
|
||||
''', 'setName', 'setDynamic', 'setCounter', 'method'
|
||||
}
|
||||
|
||||
void 'test spaces prefix'() {
|
||||
doVariantableTest '''
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.SimpleStrategy
|
||||
|
||||
@Builder(builderStrategy = SimpleStrategy, prefix = ' ')
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
new Pojo().<caret>
|
||||
''', ' Name', ' Dynamic', ' Counter', 'method'
|
||||
}
|
||||
|
||||
void 'test next setter'() {
|
||||
doVariantableTest '''
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.SimpleStrategy
|
||||
|
||||
@Builder(builderStrategy = SimpleStrategy)
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
new Pojo().setName("Janet").<caret>
|
||||
''', 'setName', 'setDynamic', 'setCounter', 'method'
|
||||
}
|
||||
|
||||
void 'test one more setter further'() {
|
||||
doVariantableTest '''
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.SimpleStrategy
|
||||
|
||||
@Builder(builderStrategy = SimpleStrategy)
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
new Pojo().setName("Janet").setCounter(35).<caret>
|
||||
''', 'setName', 'setDynamic', 'setCounter', 'method'
|
||||
}
|
||||
|
||||
void 'test next setter with prefix'() {
|
||||
doVariantableTest '''
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.SimpleStrategy
|
||||
|
||||
@Builder(builderStrategy = SimpleStrategy, prefix = 'lol')
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
new Pojo().lolName("Janet").<caret>
|
||||
''', 'lolName', 'lolDynamic', 'lolCounter', 'method'
|
||||
}
|
||||
|
||||
void 'test one more setter further with prefix'() {
|
||||
doVariantableTest '''
|
||||
import groovy.transform.builder.Builder
|
||||
import groovy.transform.builder.SimpleStrategy
|
||||
|
||||
@Builder(builderStrategy = SimpleStrategy, prefix = 'lol')
|
||||
class Pojo {
|
||||
String name
|
||||
def dynamic
|
||||
int counter
|
||||
|
||||
def method() {}
|
||||
}
|
||||
|
||||
new Pojo().lolName("Janet").lolCounter(35).<caret>
|
||||
''', 'lolName', 'lolDynamic', 'lolCounter', 'method'
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -36,7 +36,7 @@ abstract class TypeInferenceTestBase extends GroovyResolveTestCase {
|
||||
myFixture.addClass("package java.math; public class BigDecimal extends Number implements Comparable<BigDecimal> {}");
|
||||
}
|
||||
|
||||
protected void doTest(@Language("Groovy") String text, @Nullable String type) {
|
||||
protected void doTest(String text, @Nullable String type) {
|
||||
def file = myFixture.configureByText('_.groovy', text)
|
||||
def ref = file.findReferenceAt(myFixture.editor.caretModel.offset) as GrReferenceExpression
|
||||
def actual = ref.type
|
||||
|
||||
@@ -21,12 +21,13 @@ import com.intellij.ide.util.PsiElementListCellRenderer;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiNamedElement;
|
||||
import com.jetbrains.python.psi.PyElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class PyGotoTargetRendererProvider implements GotoTargetRendererProvider {
|
||||
public PsiElementListCellRenderer getRenderer(final PsiElement element, GotoTargetHandler.GotoData gotoData) {
|
||||
public PsiElementListCellRenderer getRenderer(@NotNull final PsiElement element, @NotNull GotoTargetHandler.GotoData gotoData) {
|
||||
if (element instanceof PyElement && element instanceof PsiNamedElement) return new PyElementListCellRenderer();
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.impl.source.xml.XmlTagImpl;
|
||||
import com.intellij.psi.xml.XmlAttribute;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA.
|
||||
@@ -31,7 +32,7 @@ import com.intellij.psi.xml.XmlAttribute;
|
||||
*/
|
||||
public class GotoXmlSchemaTypeRendererProvider implements GotoTargetRendererProvider {
|
||||
@Override
|
||||
public PsiElementListCellRenderer getRenderer(PsiElement element, GotoTargetHandler.GotoData gotoData) {
|
||||
public PsiElementListCellRenderer getRenderer(@NotNull PsiElement element, @NotNull GotoTargetHandler.GotoData gotoData) {
|
||||
if (element instanceof XmlTagImpl) {
|
||||
if (SchemaDefinitionsSearch.isTypeElement((XmlTagImpl)element)) {
|
||||
return new MyRenderer("");
|
||||
|
||||
Reference in New Issue
Block a user