Merge remote-tracking branch 'origin/master'

This commit is contained in:
Vladimir Krivosheev
2015-01-09 13:13:10 +01:00
123 changed files with 1178 additions and 679 deletions
Binary file not shown.
Binary file not shown.
+2 -2
View File
@@ -17,8 +17,6 @@ import static org.jetbrains.jps.idea.IdeaProjectLoader.guessHome
def home = guessHome(this)
setProperty("testcases", ["com.intellij.AllTests"])
includeTargets << new File("${home}/build/scripts/common_tests.gant")
if ("GIT_TESTS".equalsIgnoreCase(System.getProperty("idea.test.group"))) {
@@ -40,3 +38,5 @@ if (System.getProperty("os.name").toLowerCase().startsWith("mac")) {
};
setProperty("jvm_args", args)
setProperty("testcases", ["com.intellij.AllTests"])
@@ -420,21 +420,24 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
if (!FileModificationService.getInstance().preparePsiElementForWrite(element)) return;
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class);
if (lambdaExpression == null) return;
final PsiType functionalInterfaceType = lambdaExpression.getFunctionalInterfaceType();
PsiType functionalInterfaceType = lambdaExpression.getFunctionalInterfaceType();
if (functionalInterfaceType == null || !functionalInterfaceType.isValid()) return;
final String methodRefText = createMethodReferenceText(element, functionalInterfaceType,
lambdaExpression.getParameterList().getParameters());
if (methodRefText != null) {
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
final PsiExpression psiExpression =
factory.createExpressionFromText(methodRefText, lambdaExpression);
final PsiExpression psiExpression = factory.createExpressionFromText(methodRefText, lambdaExpression);
final SmartTypePointer typePointer = SmartTypePointerManager.getInstance(project).createSmartTypePointer(functionalInterfaceType);
PsiElement replace = lambdaExpression.replace(psiExpression);
if (((PsiMethodReferenceExpression)replace).getFunctionalInterfaceType() == null) { //ambiguity
final PsiTypeCastExpression cast = (PsiTypeCastExpression)factory.createExpressionFromText("(A)a", replace);
cast.getCastType().replace(factory.createTypeElement(functionalInterfaceType));
cast.getOperand().replace(replace);
replace = replace.replace(cast);
functionalInterfaceType = typePointer.getType();
if (functionalInterfaceType != null) {
cast.getCastType().replace(factory.createTypeElement(functionalInterfaceType));
cast.getOperand().replace(replace);
replace = replace.replace(cast);
}
}
JavaCodeStyleManager.getInstance(project).shortenClassReferences(replace);
}
@@ -1,162 +0,0 @@
/*
* Copyright 2001-2007 the original author or authors.
*
* 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.generate.tostring.util;
/**
* String utility methods.
*/
public class StringUtil {
/**
* Private constructor, to prevent instances of this class, since it only has static members.
*/
private StringUtil() {
}
/**
* Is the string empty (null, or contains just whitespace)
*
* @param s string to test.
* @return true if it's an empty string.
*/
public static boolean isEmpty(String s) {
return s == null || s.trim().length() == 0;
}
/**
* Does the string contain some chars (whitespace is consideres as empty)
*
* @param s string to test.
* @return true if it's NOT an empty string.
*/
public static boolean isNotEmpty(String s) {
return ! isEmpty(s);
}
/**
* Does the string have an uppercase character?
* @param s the string to test.
* @return true if the string has an uppercase character, false if not.
*/
public static boolean hasUpperCaseChar(String s) {
char[] chars = s.toCharArray();
for (char c : chars) {
if (Character.isUpperCase(c)) {
return true;
}
}
return false;
}
/**
* Does the string have a lowercase character?
* @param s the string to test.
* @return true if the string has a lowercase character, false if not.
*/
public static boolean hasLowerCaseChar(String s) {
char[] chars = s.toCharArray();
for (char c : chars) {
if (Character.isLowerCase(c)) {
return true;
}
}
return false;
}
/**
* Returns the part of s after the token.
* <p/>
* <br/>Example: after("helloWorldThisIsMe", "World") will return "ThisIsMe".
* <br/>Example: after("helloWorldThisIsMe", "Dog") will return null.
*
* @param s the string to test.
* @param token the token.
* @return the part of s that is after the token.
*/
public static String after(String s, String token) {
if (s == null) {
return null;
}
int i = s.indexOf(token);
if (i == -1) {
return s;
}
return s.substring(i + token.length());
}
/**
* Returns the part of s before the token.
* <p/>
* <br/>Example: before("helloWorldThisIsMe", "World") will return "hello".
* <br/>Example: before("helloWorldThisIsMe", "Dog") will return "helloWorldThisIsMe".
* <p/>
* If the token is not in the string, the entire string is returned.
*
* @param s the string to test.
* @param token the token.
* @return the part of s that is before the token.
*/
public static String before(String s, String token) {
if (s == null) {
return null;
}
int i = s.indexOf(token);
if (i == -1) {
return s;
}
return s.substring(0, i);
}
/**
* Returns the middle part of s between before and after tokens.
* <p/>
* <br/>Example: middle("helloWorldThisIsMe", "World", "Me") will return "ThisIs".
* <br/>Example: middle("helloWorldThisIsMe", "World", Dog") will return "ThisIsMe".
*
* @param s the string to test
* @param before the before token
* @param after the after token
* @return the middle part
*/
public static String middle(String s, String before, String after) {
String first = after(s, before);
return before(first, after);
}
/**
* Converts the first letter to lowercase
* <p/>
* <br/>Example: FirstName => firstName
* <br/>Example: name => name
* <br/>Example: S => s
*
* @param s the string
* @return the string with the first letter in lowercase.
*/
public static String firstLetterToLowerCase(String s) {
if (s.length() > 1) {
return Character.toLowerCase(s.charAt(0)) + s.substring(1);
} else if (s.length() == 1) {
return String.valueOf(Character.toLowerCase(s.charAt(0)));
} else {
return s;
}
}
}
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring;
package org.jetbrains.java.generate;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
@@ -13,10 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring;
package org.jetbrains.java.generate;
import com.intellij.openapi.components.*;
import org.jetbrains.generate.tostring.config.Config;
import org.jetbrains.java.generate.config.Config;
/**
* Application context for this plugin.
@@ -13,13 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring;
package org.jetbrains.java.generate;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.generate.tostring.config.FilterPattern;
import org.jetbrains.generate.tostring.psi.PsiAdapter;
import org.jetbrains.java.generate.config.FilterPattern;
import org.jetbrains.java.generate.psi.PsiAdapter;
import java.util.ArrayList;
import java.util.List;
@@ -29,12 +29,12 @@ import java.util.List;
*/
public class GenerateToStringUtils {
private static final Logger log = Logger.getInstance("#org.jetbrains.generate.tostring.GenerateToStringUtils");
private static final Logger log = Logger.getInstance("#GenerateToStringUtils");
private GenerateToStringUtils() {}
/**
* Filters the list of fields from the class with the given parameters from the {@link org.jetbrains.generate.tostring.config.Config config} settings.
* Filters the list of fields from the class with the given parameters from the {@link org.jetbrains.java.generate.config.Config config} settings.
*
* @param clazz the class to filter it's fields
* @param pattern the filter pattern to filter out unwanted fields
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.config;
package org.jetbrains.java.generate.config;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiClass;
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.config;
package org.jetbrains.java.generate.config;
/**
* The configuration is stored standard xmlb.XmlSerializer that automatically stores the
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.config;
package org.jetbrains.java.generate.config;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiClass;
@@ -17,7 +17,7 @@
/*
* @author max
*/
package org.jetbrains.generate.tostring.config;
package org.jetbrains.java.generate.config;
public enum DuplicationPolicy {
ASK("Ask"),
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.config;
package org.jetbrains.java.generate.config;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
@@ -23,7 +23,7 @@ import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiType;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.generate.tostring.psi.PsiAdapter;
import org.jetbrains.java.generate.psi.PsiAdapter;
import java.util.Collections;
import java.util.Set;
@@ -35,7 +35,7 @@ import java.util.regex.PatternSyntaxException;
*/
public class FilterPattern {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.generate.tostring.config.FilterPattern");
private static final Logger LOG = Logger.getInstance("#FilterPattern");
private static final Set<String> loggerNames = new THashSet<String>();
static {
Collections.addAll(loggerNames,
@@ -13,14 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.config;
package org.jetbrains.java.generate.config;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.generate.tostring.psi.PsiAdapter;
import org.jetbrains.java.generate.psi.PsiAdapter;
/**
* Inserts the method last in the javafile.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.config;
package org.jetbrains.java.generate.config;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiClass;
@@ -17,7 +17,7 @@
/*
* @author max
*/
package org.jetbrains.generate.tostring.config;
package org.jetbrains.java.generate.config;
public enum InsertWhere {
AT_CARET("At caret"),
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.config;
package org.jetbrains.java.generate.config;
/**
* Options for the various policies.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.exception;
package org.jetbrains.java.generate.exception;
/**
* Error generating the javacode for the <code>toString</code> method.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.exception;
package org.jetbrains.java.generate.exception;
/**
* Base plugin exception.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.inspection;
package org.jetbrains.java.generate.inspection;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.openapi.diagnostic.Logger;
@@ -23,7 +23,7 @@ import org.jetbrains.annotations.NotNull;
* Base class for inspection support.
*/
public abstract class AbstractToStringInspection extends LocalInspectionTool {
protected static final Logger log = Logger.getInstance("#org.jetbrains.generate.tostring.inspection.AbstractToStringInspection");
protected static final Logger log = Logger.getInstance("#AbstractToStringInspection");
@Override
@NotNull
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.inspection;
package org.jetbrains.java.generate.inspection;
import com.intellij.codeInsight.TestFrameworks;
import com.intellij.codeInspection.ProblemHighlightType;
@@ -26,8 +26,8 @@ import com.intellij.ui.DocumentAdapter;
import com.intellij.util.ui.CheckBox;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.generate.tostring.GenerateToStringContext;
import org.jetbrains.generate.tostring.GenerateToStringUtils;
import org.jetbrains.java.generate.GenerateToStringContext;
import org.jetbrains.java.generate.GenerateToStringUtils;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.inspection;
package org.jetbrains.java.generate.inspection;
import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.codeInspection.ProblemsHolder;
@@ -22,8 +22,8 @@ import com.intellij.psi.util.PropertyUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.generate.tostring.GenerateToStringContext;
import org.jetbrains.generate.tostring.GenerateToStringUtils;
import org.jetbrains.java.generate.GenerateToStringContext;
import org.jetbrains.java.generate.GenerateToStringUtils;
import java.util.Collections;
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.inspection;
package org.jetbrains.java.generate.inspection;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
@@ -22,7 +22,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.generate.tostring.GenerateToStringActionHandler;
import org.jetbrains.java.generate.GenerateToStringActionHandler;
/**
* Quick fix to run Generate toString() to fix any code inspection problems.
@@ -13,9 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.psi;
package org.jetbrains.java.generate.psi;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
@@ -28,7 +29,6 @@ import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.generate.tostring.util.StringUtil;
import static com.intellij.psi.CommonClassNames.*;
@@ -137,7 +137,7 @@ public class PsiAdapter {
* @return true if it's a Map type.
*/
public static boolean isMapType(PsiElementFactory factory, PsiType type) {
return isTypeOf(factory, type, CommonClassNames.JAVA_UTIL_MAP);
return isTypeOf(factory, type, JAVA_UTIL_MAP);
}
/**
@@ -148,7 +148,7 @@ public class PsiAdapter {
* @return true if it's a Map type.
*/
public static boolean isSetType(PsiElementFactory factory, PsiType type) {
return isTypeOf(factory, type, CommonClassNames.JAVA_UTIL_SET);
return isTypeOf(factory, type, JAVA_UTIL_SET);
}
/**
@@ -159,7 +159,7 @@ public class PsiAdapter {
* @return true if it's a Map type.
*/
public static boolean isListType(PsiElementFactory factory, PsiType type) {
return isTypeOf(factory, type, CommonClassNames.JAVA_UTIL_LIST);
return isTypeOf(factory, type, JAVA_UTIL_LIST);
}
/**
@@ -517,7 +517,7 @@ public class PsiAdapter {
* @return true if class is an exception.
*/
public static boolean isExceptionClass(PsiClass clazz) {
return InheritanceUtil.isInheritor(clazz, CommonClassNames.JAVA_LANG_THROWABLE);
return InheritanceUtil.isInheritor(clazz, JAVA_LANG_THROWABLE);
}
/**
@@ -689,6 +689,9 @@ public class PsiAdapter {
case JDK_1_8:
version = 8;
break;
case JDK_1_9:
version = 9;
break;
}
return version;
}
@@ -0,0 +1,60 @@
/*
* 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.codeInsight.generation;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.components.StoragePathMacros;
import org.jetbrains.java.generate.exception.TemplateResourceException;
import org.jetbrains.java.generate.template.TemplateResource;
import org.jetbrains.java.generate.template.TemplatesManager;
import java.io.IOException;
@State(
name = "EqualsHashCodeTemplates",
storages = {
@Storage(
file = StoragePathMacros.APP_CONFIG + "/equalsHashCodeTemplates.xml"
)}
)
public class EqualsHashCodeTemplatesManager extends TemplatesManager {
private static final String DEFAULT_EQUALS = "com/intellij/codeInsight/generation/defaultEquals.vm";
private static final String DEFAULT_HASH_CODE = "com/intellij/codeInsight/generation/defaultHashCode.vm";
public static TemplatesManager getInstance() {
return ServiceManager.getService(EqualsHashCodeTemplatesManager.class);
}
@Override
public TemplateResource[] getDefaultTemplates() {
try {
return new TemplateResource[] {
new TemplateResource("Default equals", readFile(DEFAULT_EQUALS), true),
new TemplateResource("Default hashCode", readFile(DEFAULT_HASH_CODE), true),
};
}
catch (IOException e) {
throw new TemplateResourceException("Error loading default templates", e);
}
}
private static String readFile(String resourceName) throws IOException {
return readFile(resourceName, EqualsHashCodeTemplatesManager.class);
}
}
@@ -0,0 +1,2 @@
//todo
//equals template to place here
@@ -0,0 +1,2 @@
//todo
//hashCode template to place here
@@ -32,7 +32,6 @@ import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.generate.tostring.util.StringUtil;
/**
* @author peter
@@ -81,7 +80,7 @@ public class EditContractIntention extends BaseIntentionAction {
@Nullable
@Override
public String getErrorText(String inputString) {
if (StringUtil.isEmpty(inputString)) return null;
if (com.intellij.openapi.util.text.StringUtil.isEmpty(inputString)) return null;
return ContractInspection.checkContract(method, inputString);
}
@@ -102,7 +101,7 @@ public class EditContractIntention extends BaseIntentionAction {
try {
ExternalAnnotationsManager manager = ExternalAnnotationsManager.getInstance(project);
manager.deannotate(method, ControlFlowAnalyzer.ORG_JETBRAINS_ANNOTATIONS_CONTRACT);
if (StringUtil.isNotEmpty(newContract)) {
if (!com.intellij.openapi.util.text.StringUtil.isEmpty(newContract)) {
PsiAnnotation mockAnno = JavaPsiFacade.getElementFactory(project).createAnnotationFromText("@Foo(\"" + newContract + "\")", null);
manager.annotateExternally(method, ControlFlowAnalyzer.ORG_JETBRAINS_ANNOTATIONS_CONTRACT, file,
mockAnno.getParameterList().getAttributes());
@@ -33,7 +33,6 @@ import com.intellij.openapi.ui.Messages;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.generate.tostring.util.StringUtil;
import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
/**
@@ -99,7 +98,7 @@ public class CreatePackageInfoAction extends CreateFromTemplateActionBase implem
final PsiPackage aPackage = directoryService.getPackage(directory);
if (aPackage != null) {
final String qualifiedName = aPackage.getQualifiedName();
if (StringUtil.isEmpty(qualifiedName) || nameHelper.isQualifiedName(qualifiedName)) {
if (com.intellij.openapi.util.text.StringUtil.isEmpty(qualifiedName) || nameHelper.isQualifiedName(qualifiedName)) {
return true;
}
}
@@ -15,6 +15,7 @@
*/
package com.intellij.refactoring.wrapreturnvalue;
import com.intellij.psi.util.PsiUtil;
import com.intellij.ui.ListCellRendererWrapper;
import com.intellij.ide.util.TreeClassChooser;
import com.intellij.ide.util.TreeClassChooserFactory;
@@ -215,12 +216,18 @@ class WrapReturnValueDialog extends RefactoringDialog {
final PsiClass currentClass = facade.findClass(existingClassField.getText(), GlobalSearchScope.allScope(myProject));
if (currentClass != null) {
model.removeAllElements();
final PsiType returnType = sourceMethod.getReturnType();
assert returnType != null;
for (PsiField field : currentClass.getFields()) {
final PsiType returnType = sourceMethod.getReturnType();
assert returnType != null;
if (TypeConversionUtil.isAssignable(field.getType(), returnType)) {
final PsiType fieldType = field.getType();
if (TypeConversionUtil.isAssignable(fieldType, returnType)) {
model.addElement(field);
}
else {
if (WrapReturnValueProcessor.getInferredType(fieldType, returnType, currentClass, sourceMethod) != null) {
model.addElement(field);
}
}
}
}
}
@@ -31,6 +31,7 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.OverridingMethodsSearch;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PropertyUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.refactoring.MoveDestination;
import com.intellij.refactoring.RefactorJBundle;
@@ -157,9 +158,32 @@ public class WrapReturnValueProcessor extends FixableUsagesRefactoringProcessor
}, ","));
returnTypeBuffer.append('>');
}
else if (myDelegateField != null) {
final PsiType type = myDelegateField.getType();
final PsiType returnType = myMethod.getReturnType();
final PsiClass containingClass = myDelegateField.getContainingClass();
final PsiType inferredType = getInferredType(type, returnType, containingClass, myMethod);
if (inferredType != null) {
returnTypeBuffer.append("<").append(inferredType.getCanonicalText()).append(">");
}
}
return returnTypeBuffer.toString();
}
protected static PsiType getInferredType(PsiType type, PsiType returnType, PsiClass containingClass, PsiMethod method) {
if (containingClass != null && containingClass.getTypeParameters().length == 1) {
final PsiSubstitutor substitutor = PsiResolveHelper.SERVICE.getInstance(method.getProject())
.inferTypeArguments(containingClass.getTypeParameters(), new PsiType[]{type}, new PsiType[]{returnType}, PsiUtil.getLanguageLevel(
method));
final PsiTypeParameter typeParameter = containingClass.getTypeParameters()[0];
final PsiType substituted = substitutor.substitute(typeParameter);
if (substituted != null && !typeParameter.equals(PsiUtil.resolveClassInClassTypeOnly(substituted))) {
return substituted;
}
}
return null;
}
@Override
protected boolean preprocessUsages(final Ref<UsageInfo[]> refUsages) {
MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
@@ -198,7 +222,7 @@ public class WrapReturnValueProcessor extends FixableUsagesRefactoringProcessor
final PsiParameter parameter = parameters[0];
final PsiType parameterType = parameter.getType();
for (PsiType returnType : returnTypes) {
if (!TypeConversionUtil.isAssignable(parameterType, returnType)) {
if (getInferredType(parameterType, returnType, existingClass, myMethod) == null && !TypeConversionUtil.isAssignable(parameterType, returnType)) {
continue constr;
}
}
@@ -28,4 +28,8 @@ public interface PsiClassObjectAccessExpression extends PsiExpression {
*/
@NotNull
PsiTypeElement getOperand();
@NotNull
@Override
PsiType getType();
}
@@ -260,7 +260,11 @@ public class TypesDistinctProver {
}
else if (bound instanceof PsiWildcardType) {
final PsiType boundBound = ((PsiWildcardType)bound).getBound();
return boundBound != null && !boundBound.equals(type);
if (boundBound != null && !boundBound.equals(type)) {
final PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(boundBound);
return psiClass == null || !(((PsiWildcardType)bound).isExtends() && possibleClasses.contains(psiClass));
}
return false;
}
return true;
}
@@ -273,6 +273,7 @@ public class PsiImplUtil {
return types;
}
@NotNull
public static PsiType getType(@NotNull PsiClassObjectAccessExpression classAccessExpression) {
GlobalSearchScope resolveScope = classAccessExpression.getResolveScope();
PsiManager manager = classAccessExpression.getManager();
@@ -37,6 +37,7 @@ public class PsiClassObjectAccessExpressionImpl extends ExpressionPsiElement imp
super(CLASS_OBJECT_ACCESS_EXPRESSION);
}
@NotNull
@Override
public PsiType getType() {
return PsiImplUtil.getType(this);
@@ -0,0 +1,24 @@
import java.io.Serializable;
class B {}
abstract class A {
abstract Class<?> get();
abstract Class<? extends Object> get1();
abstract Class<? super Object> get2();
abstract Class<? extends B> get3();
abstract Class<? super B> get4();
abstract Class<? extends Serializable> get5();
abstract Class<? super Serializable> get6();
{
if (get() == byte[].class);
if (get1() == byte[].class);
if (<error descr="Operator '==' cannot be applied to 'java.lang.Class<capture<? super java.lang.Object>>', 'java.lang.Class<byte[]>'">get2() == byte[].class</error>);
if (<error descr="Operator '==' cannot be applied to 'java.lang.Class<capture<? extends B>>', 'java.lang.Class<byte[]>'">get3() == byte[].class</error>);
if (<error descr="Operator '==' cannot be applied to 'java.lang.Class<capture<? super B>>', 'java.lang.Class<byte[]>'">get4() == byte[].class</error>);
if (get5() == byte[].class);
if (<error descr="Operator '==' cannot be applied to 'java.lang.Class<capture<? super java.io.Serializable>>', 'java.lang.Class<byte[]>'">get6() == byte[].class</error>);
}
}
@@ -0,0 +1,16 @@
// "Replace lambda with method reference" "true"
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
class Test {
public Test(String s) {}
public static void define(Supplier<?> moduleConstructor){}
public static void define(Function<?, ?> moduleConstructor){}
public static void define(BiFunction<?, ?, ?> moduleConstructor){}
{
define((Function<String, Object>) Test::new);
}
}
@@ -0,0 +1,16 @@
// "Replace lambda with method reference" "true"
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
class Test {
public Test(String s) {}
public static void define(Supplier<?> moduleConstructor){}
public static void define(Function<?, ?> moduleConstructor){}
public static void define(BiFunction<?, ?, ?> moduleConstructor){}
{
define((String s) -> new Test<caret>(s));
}
}
@@ -0,0 +1,10 @@
class Test {
Wrapper<String> foo() {
return new Wrapper<String>("");
}
void bar() {
String s = foo().getMyField();
}
}
@@ -0,0 +1,10 @@
class Wrapper<T> {
T myField;
Wrapper(T s) {
myField = s;
}
String getMyField() {
return myField;
}
}
@@ -0,0 +1,10 @@
class Test {
String foo() {
return "";
}
void bar() {
String s = foo();
}
}
@@ -0,0 +1,10 @@
class Wrapper<T> {
T myField;
Wrapper(T s) {
myField = s;
}
String getMyField() {
return myField;
}
}
@@ -0,0 +1,12 @@
import java.util.List;
class Test {
Wrapper<String> foo() {
return new Wrapper<String>(null);
}
void bar() {
List<String> s = foo().getMyField();
}
}
@@ -0,0 +1,11 @@
import java.util.List;
class Wrapper<T> {
List<T> myField;
Wrapper(List<T> s) {
myField = s;
}
List<T> getMyField() {
return myField;
}
}
@@ -0,0 +1,12 @@
import java.util.List;
class Test {
List<String> foo() {
return null;
}
void bar() {
List<String> s = foo();
}
}
@@ -0,0 +1,11 @@
import java.util.List;
class Wrapper<T> {
List<T> myField;
Wrapper(List<T> s) {
myField = s;
}
List<T> getMyField() {
return myField;
}
}
@@ -450,6 +450,10 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false);
}
public void testAssignabilityBetweenWildcardsAndArrays() throws Exception {
doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false);
}
public void testJavaUtilCollections_NoVerify() throws Exception {
PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule()));
assertNotNull(collectionsClass);
@@ -213,8 +213,8 @@ public class BytecodeAnalysisTest extends JavaCodeInsightFixtureTestCase {
Assert.assertEquals(asmKey, psiKey);
}
private void setUpDataClasses() throws IOException {
File classesDir = new File(Test01.class.getResource("/" + Test01.class.getPackage().getName().replace('.', '/')).getFile());
private void setUpDataClasses() throws Exception {
File classesDir = new File(Test01.class.getResource("/" + Test01.class.getPackage().getName().replace('.', '/')).toURI());
File destDir = new File(myModule.getProject().getBaseDir().getPath() + myClassesProjectRelativePath);
FileUtil.copyDir(classesDir, destDir);
VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(destDir);
@@ -51,6 +51,8 @@ public class WrapReturnValueTest extends MultiFileTestCase {
public void testHierarchy() { doTest(false, null, true); }
public void testAnonymous() { doTest(true, null, false); }
public void testWrongFieldAssignment() { doTest(true, "Existing class does not have appropriate constructor", false); }
public void testInferFieldType() { doTest(true, null, false); }
public void testInferFieldTypeArg() { doTest(true, null, false); }
public void testWrongFieldType() { doTest(true, "Existing class does not have appropriate constructor", false); }
public void testStaticMethodInnerClass() { doTest(false, null, true); }
public void testRawReturnType() { doTest(true, "Existing class does not have appropriate constructor"); }
@@ -0,0 +1,63 @@
/*
* 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.run
import com.intellij.application.options.PathMacrosCollector
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
public class JavaPathMacroCollectorTest extends LightCodeInsightFixtureTestCase {
public void testJunitConfiguration() {
String text = '''
<component name="RunManager" selected="JUnit.FooWithComments.test$withDollar$2">
<configuration default="false" name="FooWithComments.test$withDollar$2" type="JUnit" factoryName="JUnit" temporary="true" nameIsGenerated="true">
<module name="idea.folding.problem" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="PACKAGE_NAME" value="idea.folding.problem" />
<option name="MAIN_CLASS_NAME" value="idea.folding.problem.FooWithComments" />
<option name="METHOD_NAME" value="test$withDollar$2" />
<option name="TEST_OBJECT" value="method" />
<option name="VM_PARAMETERS" />
<option name="PARAMETERS" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="moduleWithDependencies" />
</option>
<envs />
<patterns />
<method />
</configuration>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="Application.Foo" />
<item index="1" class="java.lang.String" itemvalue="Application.FooWithComments" />
<item index="2" class="java.lang.String" itemvalue="Application.A" />
<item index="3" class="java.lang.String" itemvalue="JUnit.FooWithComments.test$withDollar$2" />
</list>
<recent_temporary>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="JUnit.FooWithComments.test$withDollar$2" />
</list>
</recent_temporary>
</component>
'''
def element = JDOMUtil.loadDocument(text).rootElement
assert PathMacrosCollector.getMacroNames(element).empty
}
}
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0">
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
</assembly>
Binary file not shown.
@@ -89,6 +89,9 @@
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Manifest>
<EnableDPIAwareness>true</EnableDPIAwareness>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
@@ -101,6 +104,9 @@
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Manifest>
<EnableDPIAwareness>true</EnableDPIAwareness>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
@@ -118,6 +124,9 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Manifest>
<EnableDPIAwareness>true</EnableDPIAwareness>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
@@ -136,6 +145,9 @@
<OptimizeReferences>true</OptimizeReferences>
<OutputFile>$(OutDir)WinLauncher64.exe</OutputFile>
</Link>
<Manifest>
<EnableDPIAwareness>true</EnableDPIAwareness>
</Manifest>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="ReadMe.txt" />
@@ -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.
@@ -15,5 +15,10 @@
*/
package com.intellij.codeInspection;
/**
* Marker interface for inspections which can be executed as part of "Code Cleanup" action.
* Such inspections need to provide some quickfixes which can run without user input and
* are generally safe to apply.
*/
public interface CleanupLocalInspectionTool {
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 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.
@@ -109,6 +109,9 @@ public class InspectionEP extends LanguageExtensionPoint implements InspectionPr
@Attribute("applyToDialects")
public boolean applyToDialects = true;
/**
* If true, the inspection can run as part of the code cleanup action.
*/
@Attribute("cleanupTool")
public boolean cleanupTool = false;
@@ -239,7 +239,7 @@ org.intellij.lang.xpath.validation.inspections.ImplicitTypeConversion
org.intellij.lang.xpath.validation.inspections.RedundantTypeConversion
org.intellij.plugins.intelliLang.inject.java.validation.LanguageMismatch
org.intellij.plugins.intelliLang.pattern.PatternValidator
org.jetbrains.generate.tostring.inspection.ClassHasNoToStringMethodInspection
org.jetbrains.java.generate.inspection.ClassHasNoToStringMethodInspection
org.jetbrains.idea.devkit.inspections.ComponentNotRegisteredInspection
org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignmentCanBeOperatorAssignmentInspection
org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyOverlyComplexArithmeticExpressionInspection
@@ -432,20 +432,21 @@ public interface PsiElement extends UserDataHolder, Iconable {
boolean isWritable();
/**
* Returns the reference associated with this PSI element. If the element has multiple
* associated references (see {@link #getReferences()} for an example), returns the first
* associated reference.
* Returns the reference from this PSI element to another PSI element (or elements), if one exists.
* If the element has multiple associated references (see {@link #getReferences()}
* for an example), returns the first associated reference.
*
* @return the reference instance, or null if the PSI element does not have any
* associated references.
* @see com.intellij.psi.search.searches.ReferencesSearch
*/
@Nullable
@Contract(pure=true)
PsiReference getReference();
/**
* Returns all references associated with this PSI element. An element can be associated
* with multiple references when, for example, the element is a string literal containing
* Returns all references from this PSI element to other PSI elements. An element can
* have multiple references when, for example, the element is a string literal containing
* multiple sub-strings which are valid full-qualified class names. If an element
* contains only one text fragment which acts as a reference but the reference has
* multiple possible targets, {@link PsiPolyVariantReference} should be used instead
@@ -457,6 +458,7 @@ public interface PsiElement extends UserDataHolder, Iconable {
* @return the array of references, or an empty array if the element has no associated
* references.
* @see com.intellij.psi.PsiReferenceService#getReferences
* @see com.intellij.psi.search.searches.ReferencesSearch
*/
@NotNull
@Contract(pure=true)
@@ -33,6 +33,7 @@ import org.jetbrains.annotations.Nullable;
* @see com.intellij.psi.PsiReferenceService#getReferences(PsiElement, com.intellij.psi.PsiReferenceService.Hints)
* @see com.intellij.psi.PsiReferenceBase
* @see com.intellij.psi.PsiReferenceContributor
* @see com.intellij.psi.search.searches.ReferencesSearch
*/
public interface PsiReference {
@@ -26,6 +26,9 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Locates all references to a specified PSI element.
*
* @see com.intellij.psi.PsiReference
* @author max
*/
public class ReferencesSearch extends ExtensibleQueryFactory<PsiReference, ReferencesSearch.SearchParameters> {
@@ -96,21 +99,50 @@ public class ReferencesSearch extends ExtensibleQueryFactory<PsiReference, Refer
}
}
/**
* Searches for references to the specified element in the scope in which such references are expected to be found, according to
* dependencies and access rules.
*
* @param element the element (declaration) the references to which are requested.
* @return the query allowing to enumerate the references.
*/
@NotNull
public static Query<PsiReference> search(@NotNull PsiElement element) {
return search(element, GlobalSearchScope.allScope(PsiUtilCore.getProjectInReadAction(element)), false);
}
/**
* Searches for references to the specified element in the specified scope.
*
* @param element the element (declaration) the references to which are requested.
* @param searchScope the scope in which the search is performed.
* @return the query allowing to enumerate the references.
*/
@NotNull
public static Query<PsiReference> search(@NotNull PsiElement element, @NotNull SearchScope searchScope) {
return search(element, searchScope, false);
}
/**
* Searches for references to the specified element in the specified scope, optionally returning also references which
* are invalid because of access rules (e.g. references to a private method from a different class).
*
* @param element the element (declaration) the references to which are requested.
* @param searchScope the scope in which the search is performed.
* @param ignoreAccessScope if true, references which are invalid because of access rules are included in the results.
* @return the query allowing to enumerate the references.
*/
@NotNull
public static Query<PsiReference> search(@NotNull PsiElement element, @NotNull SearchScope searchScope, boolean ignoreAccessScope) {
return search(new SearchParameters(element, searchScope, ignoreAccessScope));
}
/**
* Searches for references to the specified element according to the specified parameters.
*
* @param parameters the parameters for the search (contain also the element the references to which are requested).
* @return the query allowing to enumerate the references.
*/
@NotNull
public static Query<PsiReference> search(@NotNull final SearchParameters parameters) {
final Query<PsiReference> result = INSTANCE.createQuery(parameters);
@@ -90,7 +90,7 @@ public class CopyHandler extends EditorActionHandler {
List<TextBlockTransferableData> transferableDatas = new ArrayList<TextBlockTransferableData>();
CopyPastePostProcessor<? extends TextBlockTransferableData>[] postProcessors = Extensions.getExtensions(CopyPastePostProcessor.EP_NAME);
for (CopyPastePostProcessor<? extends TextBlockTransferableData> processor : DumbService.getInstance(project).filterByDumbAwareness( Arrays.asList(postProcessors))) {
for (CopyPastePostProcessor<? extends TextBlockTransferableData> processor : DumbService.getInstance(project).filterByDumbAwareness(Arrays.asList(postProcessors))) {
transferableDatas.addAll(processor.collectTransferableData(file, editor, startOffsets, endOffsets));
}
@@ -19,6 +19,7 @@ package com.intellij.codeInsight.editorActions;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiFile;
@@ -29,6 +30,10 @@ import java.util.Collections;
import java.util.List;
/**
* An extension to collect and apply additional transferable data when performing copy-paste in editors.<p/>
*
* Can be {@link DumbAware}
*
* @author yole
*/
public abstract class CopyPastePostProcessor<T extends TextBlockTransferableData> {
@@ -380,17 +380,17 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp
final List<LocalInspectionToolWrapper> lTools = getWrappersFromTools(localTools, file);
pass.doInspectInBatch(this, inspectionManager, lTools);
JobLauncher.getInstance().invokeConcurrentlyUnderProgress(globalSimpleTools, myProgressIndicator, false, new Processor<Tools>() {
final List<GlobalInspectionToolWrapper> tools = getWrappersFromTools(globalSimpleTools, file);
JobLauncher.getInstance().invokeConcurrentlyUnderProgress(tools, myProgressIndicator, false, new Processor<GlobalInspectionToolWrapper>() {
@Override
public boolean process(Tools tools) {
GlobalInspectionToolWrapper toolWrapper = (GlobalInspectionToolWrapper)tools.getTool();
GlobalSimpleInspectionTool tool = (GlobalSimpleInspectionTool)toolWrapper.getTool();
ProblemsHolder problemsHolder = new ProblemsHolder(inspectionManager, file, false);
ProblemDescriptionsProcessor problemDescriptionProcessor = getProblemDescriptionProcessor(toolWrapper, wrappersMap);
tool.checkFile(file, inspectionManager, problemsHolder, GlobalInspectionContextImpl.this, problemDescriptionProcessor);
InspectionToolPresentation toolPresentation = getPresentation(toolWrapper);
LocalDescriptorsUtil.addProblemDescriptors(problemsHolder.getResults(), false, GlobalInspectionContextImpl.this, null,
CONVERT, toolPresentation);
public boolean process(GlobalInspectionToolWrapper toolWrapper) {
GlobalSimpleInspectionTool tool = (GlobalSimpleInspectionTool)toolWrapper.getTool();
ProblemsHolder problemsHolder = new ProblemsHolder(inspectionManager, file, false);
ProblemDescriptionsProcessor problemDescriptionProcessor = getProblemDescriptionProcessor(toolWrapper, wrappersMap);
tool.checkFile(file, inspectionManager, problemsHolder, GlobalInspectionContextImpl.this, problemDescriptionProcessor);
InspectionToolPresentation toolPresentation = getPresentation(toolWrapper);
LocalDescriptorsUtil.addProblemDescriptors(problemsHolder.getResults(), false, GlobalInspectionContextImpl.this, null,
CONVERT, toolPresentation);
return true;
}
});
@@ -575,10 +575,10 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp
}
}
private static List<LocalInspectionToolWrapper> getWrappersFromTools(List<Tools> localTools, PsiFile file) {
final List<LocalInspectionToolWrapper> lTools = new ArrayList<LocalInspectionToolWrapper>();
private static <T extends InspectionToolWrapper> List<T> getWrappersFromTools(List<Tools> localTools, PsiFile file) {
final List<T> lTools = new ArrayList<T>();
for (Tools tool : localTools) {
final LocalInspectionToolWrapper enabledTool = (LocalInspectionToolWrapper)tool.getEnabledTool(file);
final T enabledTool = (T)tool.getEnabledTool(file);
if (enabledTool != null) {
lTools.add(enabledTool);
}
@@ -28,9 +28,23 @@ public class RunConfigurationPathMacroFilter extends PathMacroFilter {
final Element parent = attribute.getParent();
final String attrName = attribute.getName();
String tagName = parent.getName();
return tagName.equals(EnvironmentVariablesComponent.ENV) &&
(attrName.equals(EnvironmentVariablesComponent.NAME) || attrName.equals(EnvironmentVariablesComponent.VALUE))
|| tagName.equals("option") && "MAIN_CLASS_NAME".equals(parent.getAttributeValue("name"));
if (tagName.equals(EnvironmentVariablesComponent.ENV) &&
(attrName.equals(EnvironmentVariablesComponent.NAME) || attrName.equals(EnvironmentVariablesComponent.VALUE))) {
return true;
}
if (tagName.equals("configuration") && attrName.equals("name")) {
return true;
}
if (tagName.equals("option")) {
String optionName = parent.getAttributeValue("name");
if ("MAIN_CLASS_NAME".equals(optionName) || "METHOD_NAME".equals(optionName)) {
return true;
}
}
return false;
}
@Override
@@ -0,0 +1,45 @@
package com.intellij.execution.filters;
import org.jetbrains.annotations.NotNull;
public class FileHyperlinkParsedData {
private final String myFilePath;
private final int myDocumentLine;
private final int myDocumentColumn;
private final int myHyperlinkStartOffset;
private final int myHyperlinkEndOffset;
public FileHyperlinkParsedData(@NotNull String filePath,
int documentLine,
int documentColumn,
int hyperlinkStartOffset,
int hyperlinkEndOffset) {
myFilePath = filePath;
myDocumentLine = documentLine;
myDocumentColumn = documentColumn;
myHyperlinkStartOffset = hyperlinkStartOffset;
myHyperlinkEndOffset = hyperlinkEndOffset;
}
@NotNull
public String getFilePath() {
return myFilePath;
}
public int getDocumentLine() {
return myDocumentLine;
}
public int getDocumentColumn() {
return myDocumentColumn;
}
public int getHyperlinkStartOffset() {
return myHyperlinkStartOffset;
}
public int getHyperlinkEndOffset() {
return myHyperlinkEndOffset;
}
}
@@ -134,20 +134,13 @@ public class SafeDeleteDialog extends DialogWrapper {
panel.add(myCbSearchTextOccurrences, gbc);
}
if (myDelegate == null) {
final RefactoringSettings refactoringSettings = RefactoringSettings.getInstance();
myCbSearchInComments.setSelected(refactoringSettings.SAFE_DELETE_SEARCH_IN_COMMENTS);
if (myCbSearchTextOccurrences != null) {
myCbSearchTextOccurrences.setSelected(refactoringSettings.SAFE_DELETE_SEARCH_IN_NON_JAVA);
}
if (myCbSafeDelete != null) {
myCbSafeDelete.setSelected(refactoringSettings.SAFE_DELETE_WHEN_DELETE);
}
} else {
myCbSearchInComments.setSelected(myDelegate.isToSearchInComments(myElements[0]));
if (myCbSearchTextOccurrences != null) {
myCbSearchTextOccurrences.setSelected(myDelegate.isToSearchForTextOccurrences(myElements[0]));
}
final RefactoringSettings refactoringSettings = RefactoringSettings.getInstance();
if (myCbSafeDelete != null) {
myCbSafeDelete.setSelected(refactoringSettings.SAFE_DELETE_WHEN_DELETE);
}
myCbSearchInComments.setSelected(myDelegate != null ? myDelegate.isToSearchInComments(myElements[0]) : refactoringSettings.SAFE_DELETE_SEARCH_IN_COMMENTS);
if (myCbSearchTextOccurrences != null) {
myCbSearchTextOccurrences.setSelected(myDelegate != null ? myDelegate.isToSearchForTextOccurrences(myElements[0]) : refactoringSettings.SAFE_DELETE_SEARCH_IN_NON_JAVA);
}
updateControls(myCbSearchTextOccurrences);
updateControls(myCbSearchInComments);
@@ -203,20 +196,22 @@ public class SafeDeleteDialog extends DialogWrapper {
super.doOKAction();
}
if (myDelegate == null) {
final RefactoringSettings refactoringSettings = RefactoringSettings.getInstance();
refactoringSettings.SAFE_DELETE_SEARCH_IN_COMMENTS = isSearchInComments();
if (myCbSearchTextOccurrences != null) {
refactoringSettings.SAFE_DELETE_SEARCH_IN_NON_JAVA = isSearchForTextOccurences();
}
if (myCbSafeDelete != null) {
refactoringSettings.SAFE_DELETE_WHEN_DELETE = myCbSafeDelete.isSelected();
}
} else {
myDelegate.setToSearchInComments(myElements[0], isSearchInComments());
if (myCbSearchTextOccurrences != null) {
myDelegate.setToSearchForTextOccurrences(myElements[0], isSearchForTextOccurences());
final RefactoringSettings refactoringSettings = RefactoringSettings.getInstance();
if (myCbSafeDelete != null) {
refactoringSettings.SAFE_DELETE_WHEN_DELETE = myCbSafeDelete.isSelected();
}
if (isSafeDelete()) {
if (myDelegate == null) {
refactoringSettings.SAFE_DELETE_SEARCH_IN_COMMENTS = isSearchInComments();
if (myCbSearchTextOccurrences != null) {
refactoringSettings.SAFE_DELETE_SEARCH_IN_NON_JAVA = isSearchForTextOccurences();
}
} else {
myDelegate.setToSearchInComments(myElements[0], isSearchInComments());
if (myCbSearchTextOccurrences != null) {
myDelegate.setToSearchForTextOccurrences(myElements[0], isSearchForTextOccurences());
}
}
}
}
@@ -18,7 +18,6 @@ package com.intellij.ui;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.command.undo.UndoConstants;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
@@ -58,7 +57,7 @@ public class StringComboboxEditor extends EditorComboBoxEditor {
if (usePlainMatcher) {
document.putUserData(USE_PLAIN_PREFIX_MATCHER, true);
}
document.putUserData(UndoConstants.DONT_RECORD_UNDO, true);
super.setItem(document);
}
@@ -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.
@@ -20,6 +20,8 @@ import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.util.xmlb.annotations.Attribute;
/**
* Allows to define a project template in plugin.xml.
*
* @author Dmitry Avdeev
* Date: 07.11.13
*/
@@ -27,12 +29,31 @@ public class ProjectTemplateEP extends AbstractExtensionPointBean {
public static final ExtensionPointName<ProjectTemplateEP> EP_NAME = ExtensionPointName.create("com.intellij.projectTemplate");
/**
* If the category attribute is set to true, specifies the title under which the template appears in the first page
* of the new project dialog. If the category attribute is set to false, specifies the module type ID for which
* the template is displayed in the "Create project from template" list.
*/
@Attribute("projectType")
public String projectType;
/**
* The path to a .zip file containing the template contents of the project. The top level directory of the archive
* is ignored (i.e. the contents of the archive must be a single directory, which is going to be renamed to the
* name of the project the user is creating). Under that directory, .idea/description.html specifies the description
* of the template and .idea/project-template.xml specifies additional metadata for the template.
*/
@Attribute("templatePath")
public String templatePath;
/**
* If true, this template will be offered on the first page of the new project wizard dialog, and the value
* of the projectType attribute will define the top-level category under which the template will appear.
*
* If false, the template will be offered on the second page of the dialog, under the "[x] Create project from template"
* option, and the projectType attribute is the module type ID for which the template will be available
* (for example, "JAVA_MODULE" for a regular Java module).
*/
@Attribute("category")
public boolean category;
}
@@ -39,9 +39,7 @@ public class GlobalMatchingVisitor extends AbstractMatchingVisitor {
// context of matching
private MatchContext matchContext;
private MatchingHandler myLastHandler;
private Map<Language, PsiElementVisitor> myLanguage2MatchingVisitor = new HashMap<Language, PsiElementVisitor>(1);
private final Map<Language, PsiElementVisitor> myLanguage2MatchingVisitor = new HashMap<Language, PsiElementVisitor>(1);
public PsiElement getElement() {
return myElement;
@@ -162,8 +160,7 @@ public class GlobalMatchingVisitor extends AbstractMatchingVisitor {
return nodes.hasNext() == nodes2.hasNext();
}
myLastHandler = matchContext.getPattern().getHandler(nodes.current());
return myLastHandler.matchSequentially(
return matchContext.getPattern().getHandler(nodes.current()).matchSequentially(
nodes,
nodes2,
matchContext
@@ -3063,6 +3063,36 @@ public class StringUtil extends StringUtilRt {
return builder.toString().replaceAll("\\.{4,}", "...");
}
/**
* Does the string have an uppercase character?
* @param s the string to test.
* @return true if the string has an uppercase character, false if not.
*/
public static boolean hasUpperCaseChar(String s) {
char[] chars = s.toCharArray();
for (char c : chars) {
if (Character.isUpperCase(c)) {
return true;
}
}
return false;
}
/**
* Does the string have a lowercase character?
* @param s the string to test.
* @return true if the string has a lowercase character, false if not.
*/
public static boolean hasLowerCaseChar(String s) {
char[] chars = s.toCharArray();
for (char c : chars) {
if (Character.isLowerCase(c)) {
return true;
}
}
return false;
}
/**
* Expirable CharSequence. Very useful to control external library execution time,
* i.e. when java.util.regex.Pattern match goes out of control.
@@ -15,6 +15,7 @@
*/
package com.siyeh.ig.style;
import com.intellij.codeInspection.CleanupLocalInspectionTool;
import com.intellij.codeInspection.canBeFinal.CanBeFinalHandler;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiModifier;
@@ -26,7 +27,7 @@ import com.siyeh.ig.fixes.MakeFieldFinalFix;
import com.siyeh.ig.psiutils.FinalUtils;
import org.jetbrains.annotations.NotNull;
public class FieldMayBeFinalInspection extends BaseInspection {
public class FieldMayBeFinalInspection extends BaseInspection implements CleanupLocalInspectionTool {
@Override
@NotNull
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2007 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2015 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,7 +46,6 @@ class VariableAccessVisitor extends JavaRecursiveElementVisitor {
private final boolean countGettersAndSetters;
VariableAccessVisitor(PsiClass aClass, boolean countGettersAndSetters) {
super();
this.aClass = aClass;
this.countGettersAndSetters = countGettersAndSetters;
}
@@ -54,7 +53,12 @@ class VariableAccessVisitor extends JavaRecursiveElementVisitor {
@Override
public void visitClass(PsiClass classToVisit) {
calculatePrivateMethodUsagesIfNecessary();
final boolean wasInSync = m_inSynchronizedContext;
if (!classToVisit.equals(aClass)) {
m_inSynchronizedContext = false;
}
super.visitClass(classToVisit);
m_inSynchronizedContext = wasInSync;
}
@Override
@@ -131,11 +135,11 @@ class VariableAccessVisitor extends JavaRecursiveElementVisitor {
return;
}
}
final boolean methodIsSynchonized =
final boolean methodIsSynchronized =
method.hasModifierProperty(PsiModifier.SYNCHRONIZED)
|| methodIsAlwaysUsedSynchronized(method);
boolean wasInSync = false;
if (methodIsSynchonized) {
if (methodIsSynchronized) {
wasInSync = m_inSynchronizedContext;
m_inSynchronizedContext = true;
}
@@ -144,7 +148,7 @@ class VariableAccessVisitor extends JavaRecursiveElementVisitor {
m_inInitializer = true;
}
super.visitMethod(method);
if (methodIsSynchonized) {
if (methodIsSynchronized) {
m_inSynchronizedContext = wasInSync;
}
if (isConstructor) {
@@ -1,27 +0,0 @@
package com.siyeh.igtest.threading;
public class FieldAccessedSynchronizedAndUnsynchronized
{
private final Object m_lock = new Object();
private Object m_contents = new Object();
public void foo()
{
synchronized(m_lock)
{
m_contents = new Object();
}
getContents();
}
private Object getContents()
{
getContents2();
return m_contents;
}
private void getContents2() {
getContents();
}
}
@@ -0,0 +1,42 @@
package com.siyeh.igtest.threading.field_accessed_synchronized_and_unsynchronized;
public class FieldAccessedSynchronizedAndUnsynchronized
{
private final Object m_lock = new Object();
private Object <warning descr="Field 'm_contents' is accessed in both synchronized and unsynchronized contexts">m_contents</warning> = new Object();
public void foo()
{
synchronized(m_lock)
{
m_contents = new Object();
}
getContents();
}
private Object getContents()
{
getContents2();
return m_contents;
}
private void getContents2() {
getContents();
}
}
class Test {
private Object <warning descr="Field 'object' is accessed in both synchronized and unsynchronized contexts">object</warning>;
synchronized Runnable method() {
return new Runnable() {
@Override public void run() {
System.out.println(object);
}
};
}
synchronized void setObject(Object object) {
this.object = object;
}
}
@@ -0,0 +1,36 @@
/*
* 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.siyeh.ig.threading;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.siyeh.ig.LightInspectionTestCase;
import org.jetbrains.annotations.Nullable;
/**
* @author Bas Leijdekkers
*/
public class FieldAccessedSynchronizedAndUnsynchronizedInspectionTest extends LightInspectionTestCase {
public void testFieldAccessedSynchronizedAndUnsynchronized() {
doTest();
}
@Nullable
@Override
protected InspectionProfileEntry getInspection() {
return new FieldAccessedSynchronizedAndUnsynchronizedInspection();
}
}
@@ -1,76 +0,0 @@
/*
* Copyright 2001-2013 the original author or authors.
*
* 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.generate.tostring.template;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import org.jetbrains.generate.tostring.exception.TemplateResourceException;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* Resource locator for default method body templates.
*/
public class TemplateResourceLocator {
private static final String DEFAULT_CONCAT = "/org/jetbrains/generate/tostring/template/DefaultConcatMember.vm";
private static final String DEFAULT_CONCAT_GROOVY = "/org/jetbrains/generate/tostring/template/DefaultConcatMemberGroovy.vm";
private static final String DEFAULT_CONCAT_SUPER = "/org/jetbrains/generate/tostring/template/DefaultConcatMemberSuper.vm";
private static final String DEFAULT_BUFFER = "/org/jetbrains/generate/tostring/template/DefaultBuffer.vm";
private static final String DEFAULT_BUILDER = "/org/jetbrains/generate/tostring/template/DefaultBuilder.vm";
private static final String DEFAULT_TOSTRINGBUILDER = "/org/jetbrains/generate/tostring/template/DefaultToStringBuilder.vm";
private static final String DEFAULT_TOSTRINGBUILDER3 = "/org/jetbrains/generate/tostring/template/DefaultToStringBuilder3.vm";
private static final String DEFAULT_GUAVA = "/org/jetbrains/generate/tostring/template/DefaultGuava.vm";
private TemplateResourceLocator() {}
/**
* Get the default templates.
*/
public static TemplateResource[] getDefaultTemplates() {
try {
return new TemplateResource[]{
new TemplateResource("String concat (+)", readFile(DEFAULT_CONCAT), true),
new TemplateResource("String concat (+) and super.toString()", readFile(DEFAULT_CONCAT_SUPER), true),
new TemplateResource("StringBuffer", readFile(DEFAULT_BUFFER), true),
new TemplateResource("StringBuilder (JDK 1.5)", readFile(DEFAULT_BUILDER), true),
new TemplateResource("ToStringBuilder (Apache commons-lang)", readFile(DEFAULT_TOSTRINGBUILDER), true),
new TemplateResource("ToStringBuilder (Apache commons-lang 3)", readFile(DEFAULT_TOSTRINGBUILDER3), true),
new TemplateResource("Objects.toStringHelper (Guava)", readFile(DEFAULT_GUAVA), true),
new TemplateResource("Groovy: String concat (+)", readFile(DEFAULT_CONCAT_GROOVY), true),
};
}
catch (IOException e) {
throw new TemplateResourceException("Error loading default templates", e);
}
}
/**
* Reads the content of the resource and return it as a String.
* <p/>Uses the class loader that loaded this class to find the resource in its classpath.
*
* @param resource the resource name. Will lookup using the classpath.
* @return the content if the resource
* @throws IOException error reading the file.
*/
private static String readFile(String resource) throws IOException {
BufferedInputStream in = new BufferedInputStream(TemplateResourceLocator.class.getResourceAsStream(resource));
return StringUtil.convertLineSeparators(FileUtil.loadTextAndClose(new InputStreamReader(in, CharsetToolkit.UTF8_CHARSET)));
}
}
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring;
package org.jetbrains.java.generate;
import com.intellij.openapi.editor.actionSystem.EditorAction;
@@ -13,12 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring;
package org.jetbrains.java.generate;
import com.intellij.codeInsight.generation.PsiElementClassMember;
import com.intellij.codeInsight.hint.HintManager;
import com.intellij.ide.util.MemberChooser;
import com.intellij.ide.util.MemberChooserBuilder;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
@@ -39,10 +38,11 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.generate.tostring.config.Config;
import org.jetbrains.generate.tostring.template.TemplateResource;
import org.jetbrains.generate.tostring.template.TemplatesManager;
import org.jetbrains.generate.tostring.view.TemplatesPanel;
import org.jetbrains.generate.tostring.GenerateToStringClassFilter;
import org.jetbrains.java.generate.config.Config;
import org.jetbrains.java.generate.template.TemplateResource;
import org.jetbrains.java.generate.template.toString.ToStringTemplatesManager;
import org.jetbrains.java.generate.view.TemplatesPanel;
import javax.swing.*;
import java.awt.*;
@@ -57,7 +57,7 @@ import java.util.List;
* The action-handler that does the code generation.
*/
public class GenerateToStringActionHandlerImpl extends EditorWriteActionHandler implements GenerateToStringActionHandler {
private static final Logger logger = Logger.getInstance("#org.jetbrains.generate.tostring.GenerateToStringActionHandlerImpl");
private static final Logger logger = Logger.getInstance("#GenerateToStringActionHandlerImpl");
public void executeWriteAction(Editor editor, DataContext dataContext) {
final Project project = CommonDataKeys.PROJECT.getData(dataContext);
@@ -107,7 +107,7 @@ public class GenerateToStringActionHandlerImpl extends EditorWriteActionHandler
Collection<PsiMember> selectedMembers = GenerationUtil.convertClassMembersToPsiMembers(chooser.getSelectedElements());
final TemplateResource template = header.getSelectedTemplate();
TemplatesManager.getInstance().setDefaultTemplate(template);
ToStringTemplatesManager.getInstance().setDefaultTemplate(template);
if (template.isValidTemplate()) {
GenerateToStringWorker.executeGenerateActionLater(clazz, editor, selectedMembers, template,
@@ -183,7 +183,7 @@ public class GenerateToStringActionHandlerImpl extends EditorWriteActionHandler
public MemberChooserHeaderPanel(final PsiClass clazz) {
super(new GridBagLayout());
final Collection<TemplateResource> templates = TemplatesManager.getInstance().getAllTemplates();
final Collection<TemplateResource> templates = ToStringTemplatesManager.getInstance().getAllTemplates();
final TemplateResource[] all = templates.toArray(new TemplateResource[templates.size()]);
final JButton settingsButton = new JButton("Settings");
@@ -216,23 +216,23 @@ public class GenerateToStringActionHandlerImpl extends EditorWriteActionHandler
updateDialog(clazz, chooser);
comboBox.removeAllItems();
for (TemplateResource resource : TemplatesManager.getInstance().getAllTemplates()) {
for (TemplateResource resource : ToStringTemplatesManager.getInstance().getAllTemplates()) {
comboBox.addItem(resource);
}
comboBox.setSelectedItem(TemplatesManager.getInstance().getDefaultTemplate());
comboBox.setSelectedItem(ToStringTemplatesManager.getInstance().getDefaultTemplate());
}
};
ShowSettingsUtil.getInstance().editConfigurable(MemberChooserHeaderPanel.this, composite, new Runnable() {
public void run() {
ui.selectItem(TemplatesManager.getInstance().getDefaultTemplate());
ui.selectItem(ToStringTemplatesManager.getInstance().getDefaultTemplate());
}
});
Disposer.dispose(disposable);
}
});
comboBox.setSelectedItem(TemplatesManager.getInstance().getDefaultTemplate());
comboBox.setSelectedItem(ToStringTemplatesManager.getInstance().getDefaultTemplate());
final JLabel templatesLabel = new JLabel("Template: ");
templatesLabel.setDisplayedMnemonic('T');
@@ -13,14 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring;
package org.jetbrains.java.generate;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import org.jetbrains.generate.tostring.config.Config;
import org.jetbrains.generate.tostring.view.ConfigUI;
import org.jetbrains.java.generate.config.Config;
import org.jetbrains.java.generate.view.ConfigUI;
import javax.swing.*;
@@ -28,7 +28,7 @@ import javax.swing.*;
* @author yole
*/
public class GenerateToStringConfigurable implements Configurable {
private static final Logger log = Logger.getInstance("#org.jetbrains.generate.tostring.GenerateToStringConfigurable");
private static final Logger log = Logger.getInstance("#GenerateToStringConfigurable");
private ConfigUI configUI;
private final Project myProject;
@@ -17,7 +17,7 @@
/*
* @author max
*/
package org.jetbrains.generate.tostring;
package org.jetbrains.java.generate;
import com.intellij.codeInsight.hint.HintManager;
import com.intellij.openapi.application.ApplicationManager;
@@ -32,22 +32,17 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.util.IncorrectOperationException;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.generate.tostring.config.*;
import org.jetbrains.generate.tostring.element.*;
import org.jetbrains.generate.tostring.exception.GenerateCodeException;
import org.jetbrains.generate.tostring.psi.PsiAdapter;
import org.jetbrains.generate.tostring.template.TemplateResource;
import org.jetbrains.generate.tostring.velocity.VelocityFactory;
import org.jetbrains.generate.tostring.view.MethodExistsDialog;
import org.jetbrains.java.generate.config.*;
import org.jetbrains.java.generate.exception.GenerateCodeException;
import org.jetbrains.java.generate.psi.PsiAdapter;
import org.jetbrains.java.generate.template.TemplateResource;
import org.jetbrains.java.generate.view.MethodExistsDialog;
import java.io.StringWriter;
import java.util.*;
public class GenerateToStringWorker {
private static final Logger logger = Logger.getInstance("#org.jetbrains.generate.tostring.GenerateToStringWorker");
private static final Logger logger = Logger.getInstance("#" + GenerateToStringWorker.class.getName());
private final Editor editor;
private final PsiClass clazz;
@@ -61,6 +56,70 @@ public class GenerateToStringWorker {
this.hasOverrideAnnotation = insertAtOverride;
}
/**
* Creates the <code>toString</code> method.
*
* @param selectedMembers the selected members as both {@link com.intellij.psi.PsiField} and {@link com.intellij.psi.PsiMethod}.
* @param policy conflict resolution policy
* @param params additional parameters stored with key/value in the map.
* @param template the template to use
* @return the created method, null if the method is not created due the user cancels this operation
* @throws GenerateCodeException is thrown when there is an error generating the javacode.
* @throws IncorrectOperationException is thrown by IDEA.
*/
@Nullable
private PsiMethod createToStringMethod(Collection<PsiMember> selectedMembers,
ConflictResolutionPolicy policy,
Map<String, String> params,
TemplateResource template) throws IncorrectOperationException, GenerateCodeException {
// generate code using velocity
String body = GenerationUtil.velocityGenerateCode(clazz, selectedMembers, params, template.getMethodBody(), config.getSortElements(), config.isUseFullyQualifiedName());
if (logger.isDebugEnabled()) logger.debug("Method body generated from Velocity:\n" + body);
// fix weird linebreak problem in IDEA #3296 and later
body = StringUtil.convertLineSeparators(body);
// create psi newMethod named toString()
final JVMElementFactory topLevelFactory = JVMElementFactories.getFactory(clazz.getLanguage(), clazz.getProject());
if (topLevelFactory == null) {
return null;
}
PsiMethod newMethod;
try {
newMethod = topLevelFactory.createMethodFromText(template.getMethodSignature() + " { " + body + " }", clazz);
CodeStyleManager.getInstance(clazz.getProject()).reformat(newMethod);
} catch (IncorrectOperationException ignore) {
HintManager.getInstance().showErrorHint(editor, "'toString()' method could not be created from template '" +
template.getFileName() + '\'');
return null;
}
// insertNewMethod conflict resolution policy (add/replace, duplicate, cancel)
PsiMethod existingMethod = clazz.findMethodBySignature(newMethod, false);
PsiMethod toStringMethod = policy.applyMethod(clazz, existingMethod, newMethod, editor);
if (toStringMethod == null) {
return null; // user cancelled so return null
}
if (hasOverrideAnnotation) {
toStringMethod.getModifierList().addAnnotation("java.lang.Override");
}
// applyJavaDoc conflict resolution policy (add or keep existing)
String existingJavaDoc = params.get("existingJavaDoc");
String newJavaDoc = template.getJavaDoc();
if (existingJavaDoc != null || newJavaDoc != null) {
// generate javadoc using velocity
newJavaDoc = GenerationUtil.velocityGenerateCode(clazz, selectedMembers, params, newJavaDoc, config.getSortElements(), config.isUseFullyQualifiedName());
if (logger.isDebugEnabled()) logger.debug("JavaDoc body generated from Velocity:\n" + newJavaDoc);
GenerationUtil.applyJavaDoc(toStringMethod, existingJavaDoc, newJavaDoc);
}
// return the created method
return toStringMethod;
}
public void execute(Collection<PsiMember> members, TemplateResource template) throws IncorrectOperationException, GenerateCodeException {
// decide what to do if the method already exists
ConflictResolutionPolicy resolutionPolicy = exitsMethodDialog(template);
@@ -74,7 +133,8 @@ public class GenerateToStringWorker {
beforeCreateToStringMethod(params, template);
// generate method
PsiMethod method = createToStringMethod(members, resolutionPolicy, params, template);
PsiMethod method =
createToStringMethod(members, resolutionPolicy, params, template);
// after, if method was generated (not cancel policy)
if (method != null) {
@@ -135,75 +195,6 @@ public class GenerateToStringWorker {
}
}
/**
* Creates the <code>toString</code> method.
*
* @param selectedMembers the selected members as both {@link com.intellij.psi.PsiField} and {@link com.intellij.psi.PsiMethod}.
* @param policy conflict resolution policy
* @param params additional parameters stored with key/value in the map.
* @param template the template to use
* @return the created method, null if the method is not created due the user cancels this operation
* @throws GenerateCodeException is thrown when there is an error generating the javacode.
* @throws IncorrectOperationException is thrown by IDEA.
*/
@Nullable
private PsiMethod createToStringMethod(Collection<PsiMember> selectedMembers,
ConflictResolutionPolicy policy,
Map<String, String> params,
TemplateResource template) throws IncorrectOperationException, GenerateCodeException {
// generate code using velocity
String body = velocityGenerateCode(selectedMembers, params, template.getMethodBody());
if (logger.isDebugEnabled()) logger.debug("Method body generated from Velocity:\n" + body);
// fix weird linebreak problem in IDEA #3296 and later
body = StringUtil.convertLineSeparators(body);
// create psi newMethod named toString()
final JVMElementFactory topLevelFactory = JVMElementFactories.getFactory(clazz.getLanguage(), clazz.getProject());
if (topLevelFactory == null) {
return null;
}
PsiMethod newMethod;
try {
newMethod = topLevelFactory.createMethodFromText(template.getMethodSignature() + " { " + body + " }", clazz);
CodeStyleManager.getInstance(clazz.getProject()).reformat(newMethod);
} catch (IncorrectOperationException ignore) {
HintManager.getInstance().showErrorHint(editor, "'toString()' method could not be created from template '" +
template.getFileName() + '\'');
return null;
}
// insertNewMethod conflict resolution policy (add/replace, duplicate, cancel)
PsiMethod existingMethod = clazz.findMethodBySignature(newMethod, false);
PsiMethod toStringMethod = policy.applyMethod(clazz, existingMethod, newMethod, editor);
if (toStringMethod == null) {
return null; // user cancelled so return null
}
if (hasOverrideAnnotation) {
toStringMethod.getModifierList().addAnnotation("java.lang.Override");
}
// applyJavaDoc conflict resolution policy (add or keep existing)
String existingJavaDoc = params.get("existingJavaDoc");
String newJavaDoc = template.getJavaDoc();
if (existingJavaDoc != null || newJavaDoc != null) {
// generate javadoc using velocity
newJavaDoc = velocityGenerateCode(selectedMembers, params, newJavaDoc);
if (logger.isDebugEnabled()) logger.debug("JavaDoc body generated from Velocity:\n" + newJavaDoc);
applyJavaDoc(toStringMethod, existingJavaDoc, newJavaDoc);
}
// return the created method
return toStringMethod;
}
private static void applyJavaDoc(PsiMethod newMethod, String existingJavaDoc, String newJavaDoc) {
String text = newJavaDoc != null ? newJavaDoc : existingJavaDoc; // prefer to use new javadoc
PsiAdapter.addOrReplaceJavadoc(newMethod, text, true);
}
/**
* This method is executed just after the <code>toString</code> method is created or updated.
@@ -253,75 +244,6 @@ public class GenerateToStringWorker {
}
}
/**
* Generates the code using Velocity.
* <p/>
* This is used to create the <code>toString</code> method body and it's javadoc.
*
* @param selectedMembers the selected members as both {@link com.intellij.psi.PsiField} and {@link com.intellij.psi.PsiMethod}.
* @param params additional parameters stored with key/value in the map.
* @param templateMacro the velocity macro template
* @return code (usually javacode). Returns null if templateMacro is null.
* @throws GenerateCodeException is thrown when there is an error generating the javacode.
*/
private String velocityGenerateCode(Collection<PsiMember> selectedMembers, Map<String, String> params, String templateMacro)
throws GenerateCodeException {
if (templateMacro == null) {
return null;
}
StringWriter sw = new StringWriter();
try {
VelocityContext vc = new VelocityContext();
vc.put("java_version", PsiAdapter.getJavaVersion(clazz));
// field information
logger.debug("Velocity Context - adding fields");
vc.put("fields", ElementUtils.getOnlyAsFieldElements(selectedMembers));
// method information
logger.debug("Velocity Context - adding methods");
vc.put("methods", ElementUtils.getOnlyAsMethodElements(selectedMembers));
// element information (both fields and methods)
logger.debug("Velocity Context - adding members (fields and methods)");
List<Element> elements = ElementUtils.getOnlyAsFieldAndMethodElements(selectedMembers);
// sort elements if enabled and not using chooser dialog
if (config.getSortElements() != 0) {
Collections.sort(elements, new ElementComparator(config.getSortElements()));
}
vc.put("members", elements);
// class information
ClassElement ce = ElementFactory.newClassElement(clazz);
vc.put("class", ce);
if (logger.isDebugEnabled()) logger.debug("Velocity Context - adding class: " + ce);
// information to keep as it is to avoid breaking compatibility with prior releases
vc.put("classname", config.isUseFullyQualifiedName() ? ce.getQualifiedName() : ce.getName());
vc.put("FQClassname", ce.getQualifiedName());
if (logger.isDebugEnabled()) logger.debug("Velocity Macro:\n" + templateMacro);
// velocity
VelocityEngine velocity = VelocityFactory.getVelocityEngine();
logger.debug("Executing velocity +++ START +++");
velocity.evaluate(vc, sw, this.getClass().getName(), templateMacro);
logger.debug("Executing velocity +++ END +++");
// any additional packages to import returned from velocity?
if (vc.get("autoImportPackages") != null) {
params.put("autoImportPackages", (String)vc.get("autoImportPackages"));
}
}
catch (Exception e) {
throw new GenerateCodeException("Error in Velocity code generator", e);
}
return sw.getBuffer().toString();
}
/**
* Generates the toString() code for the specified class and selected
* fields, doing the work through a WriteAction ran by a CommandProcessor.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring;
package org.jetbrains.java.generate;
import com.intellij.codeInsight.generation.PsiElementClassMember;
import com.intellij.codeInsight.generation.PsiFieldMember;
@@ -21,19 +21,25 @@ import com.intellij.codeInsight.generation.PsiMethodMember;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiMember;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.generate.tostring.exception.GenerateCodeException;
import org.jetbrains.generate.tostring.exception.PluginException;
import org.jetbrains.java.generate.element.*;
import org.jetbrains.java.generate.exception.GenerateCodeException;
import org.jetbrains.java.generate.exception.PluginException;
import org.jetbrains.java.generate.psi.PsiAdapter;
import org.jetbrains.java.generate.velocity.VelocityFactory;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.io.StringWriter;
import java.util.*;
public class GenerationUtil {
private static final Logger log = Logger.getInstance("#org.jetbrains.generate.tostring.GenerationUtil");
private static final Logger logger = Logger.getInstance("#" + GenerationUtil.class.getName());
/**
* Handles any exception during the executing on this plugin.
@@ -43,7 +49,7 @@ public class GenerationUtil {
* @throws RuntimeException is thrown for severe exceptions
*/
public static void handleException(Project project, Exception e) throws RuntimeException {
log.info(e);
logger.info(e);
if (e instanceof GenerateCodeException) {
// code generation error - display velocity error in error dialog so user can identify problem quicker
@@ -105,4 +111,84 @@ public class GenerationUtil {
return psiMemberList;
}
public static void applyJavaDoc(PsiMethod newMethod, String existingJavaDoc, String newJavaDoc) {
String text = newJavaDoc != null ? newJavaDoc : existingJavaDoc; // prefer to use new javadoc
PsiAdapter.addOrReplaceJavadoc(newMethod, text, true);
}
/**
* Generates the code using Velocity.
* <p/>
* This is used to create the <code>toString</code> method body and it's javadoc.
*
* @param selectedMembers the selected members as both {@link com.intellij.psi.PsiField} and {@link com.intellij.psi.PsiMethod}.
* @param params additional parameters stored with key/value in the map.
* @param templateMacro the velocity macro template
* @return code (usually javacode). Returns null if templateMacro is null.
* @throws org.jetbrains.java.generate.exception.GenerateCodeException is thrown when there is an error generating the javacode.
*/
public static String velocityGenerateCode(PsiClass clazz,
Collection<? extends PsiMember> selectedMembers,
Map<String, String> params,
String templateMacro,
int sortElements,
boolean useFullyQualifiedName)
throws GenerateCodeException {
if (templateMacro == null) {
return null;
}
StringWriter sw = new StringWriter();
try {
VelocityContext vc = new VelocityContext();
vc.put("java_version", PsiAdapter.getJavaVersion(clazz));
// field information
logger.debug("Velocity Context - adding fields");
vc.put("fields", ElementUtils.getOnlyAsFieldElements(selectedMembers));
// method information
logger.debug("Velocity Context - adding methods");
vc.put("methods", ElementUtils.getOnlyAsMethodElements(selectedMembers));
// element information (both fields and methods)
logger.debug("Velocity Context - adding members (fields and methods)");
List<Element> elements = ElementUtils.getOnlyAsFieldAndMethodElements(selectedMembers);
// sort elements if enabled and not using chooser dialog
if (sortElements != 0) {
Collections.sort(elements, new ElementComparator(sortElements));
}
vc.put("members", elements);
// class information
ClassElement ce = ElementFactory.newClassElement(clazz);
vc.put("class", ce);
if (logger.isDebugEnabled()) logger.debug("Velocity Context - adding class: " + ce);
// information to keep as it is to avoid breaking compatibility with prior releases
vc.put("classname", useFullyQualifiedName ? ce.getQualifiedName() : ce.getName());
vc.put("FQClassname", ce.getQualifiedName());
vc.put("settings", CodeStyleSettingsManager.getSettings(clazz.getProject()));
if (logger.isDebugEnabled()) logger.debug("Velocity Macro:\n" + templateMacro);
// velocity
VelocityEngine velocity = VelocityFactory.getVelocityEngine();
logger.debug("Executing velocity +++ START +++");
velocity.evaluate(vc, sw, GenerateToStringWorker.class.getName(), templateMacro);
logger.debug("Executing velocity +++ END +++");
// any additional packages to import returned from velocity?
if (vc.get("autoImportPackages") != null) {
params.put("autoImportPackages", (String)vc.get("autoImportPackages"));
}
}
catch (Exception e) {
throw new GenerateCodeException("Error in Velocity code generator", e);
}
return sw.getBuffer().toString();
}
}
@@ -13,12 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.config;
package org.jetbrains.java.generate.config;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
/**
@@ -13,13 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.config;
package org.jetbrains.java.generate.config;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.generate.tostring.psi.PsiAdapter;
import org.jetbrains.java.generate.psi.PsiAdapter;
/**
* Inserts the method after the hashCode/equals methods in the javafile.
@@ -13,15 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.config;
package org.jetbrains.java.generate.config;
import com.intellij.codeInsight.generation.GenerateMembersUtil;
import com.intellij.codeInsight.generation.OverrideImplementUtil;
import com.intellij.codeInsight.generation.PsiGenerationInfo;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.config;
package org.jetbrains.java.generate.config;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiClass;
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.element;
package org.jetbrains.java.generate.element;
/**
* Base class to extends for Elements.
@@ -38,6 +38,13 @@ public abstract class AbstractElement implements Element {
protected boolean isDate;
protected boolean isCalendar;
protected boolean isBoolean;
protected boolean isLong;
protected boolean isFloat;
protected boolean isDouble;
protected boolean isVoid;
protected boolean isChar;
protected boolean isByte;
protected boolean isShort;
protected String typeName;
protected String typeQualifiedName;
protected boolean isModifierStatic;
@@ -119,6 +126,69 @@ public abstract class AbstractElement implements Element {
return isBoolean;
}
@Override
public boolean isLong() {
return isLong;
}
public void setLong(boolean isLong) {
this.isLong = isLong;
}
@Override
public boolean isFloat() {
return isFloat;
}
public void setFloat(boolean isFloat) {
this.isFloat = isFloat;
}
@Override
public boolean isDouble() {
return isDouble;
}
public void setDouble(boolean isDouble) {
this.isDouble = isDouble;
}
@Override
public boolean isVoid() {
return isVoid;
}
public void setVoid(boolean isVoid) {
this.isVoid = isVoid;
}
@Override
public boolean isChar() {
return isChar;
}
public void setChar(boolean isChar) {
this.isChar = isChar;
}
@Override
public boolean isByte() {
return isByte;
}
public void setByte(boolean isByte) {
this.isByte = isByte;
}
@Override
public boolean isShort() {
return isShort;
}
public void setShort(boolean isShort) {
this.isShort = isShort;
}
public void setBoolean(boolean aBoolean) {
isBoolean = aBoolean;
}
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.element;
package org.jetbrains.java.generate.element;
import com.intellij.openapi.util.text.StringUtil;
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.element;
package org.jetbrains.java.generate.element;
/**
* This is an Element.
@@ -146,6 +146,14 @@ public interface Element {
*/
boolean isBoolean();
boolean isLong();
boolean isShort();
boolean isChar();
boolean isFloat();
boolean isDouble();
boolean isByte();
boolean isVoid();
/**
* Get's the elements type classname (etc. Object, String, List)
*
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.element;
package org.jetbrains.java.generate.element;
import java.util.Comparator;
@@ -13,18 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.element;
package org.jetbrains.java.generate.element;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
import org.jetbrains.generate.tostring.psi.PsiAdapter;
import org.jetbrains.java.generate.psi.PsiAdapter;
/**
* Factory for creating {@link FieldElement} or {@link ClassElement} objects.
*/
public class ElementFactory {
private static final Logger log = Logger.getInstance("#org.jetbrains.generate.tostring.element.ElementFactory");
private static final Logger log = Logger.getInstance("#ElementFactory");
private ElementFactory() {
}
@@ -170,6 +170,13 @@ public class ElementFactory {
if (PsiAdapter.isDateType(factory, type)) element.setDate(true);
if (PsiAdapter.isCalendarType(factory, type)) element.setCalendar(true);
if (PsiAdapter.isBooleanType(factory, type)) element.setBoolean(true);
if (PsiType.VOID.equals(type)) element.setVoid(true);
if (PsiType.LONG.equals(type)) element.setLong(true);
if (PsiType.FLOAT.equals(type)) element.setFloat(true);
if (PsiType.DOUBLE.equals(type)) element.setDouble(true);
if (PsiType.BYTE.equals(type)) element.setByte(true);
if (PsiType.CHAR.equals(type)) element.setChar(true);
if (PsiType.SHORT.equals(type)) element.setShort(true);
// modifiers
if (modifiers != null) {
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.element;
package org.jetbrains.java.generate.element;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiMember;
@@ -36,7 +36,7 @@ public class ElementUtils {
* @param members a list of {@link com.intellij.psi.PsiMember} objects.
* @return a filtered list of only the fields as {@link FieldElement} objects.
*/
public static List<FieldElement> getOnlyAsFieldElements(Collection<PsiMember> members) {
public static List<FieldElement> getOnlyAsFieldElements(Collection<? extends PsiMember> members) {
List<FieldElement> fieldElementList = new ArrayList<FieldElement>();
for (PsiMember member : members) {
@@ -56,7 +56,7 @@ public class ElementUtils {
* @param members a list of {@link com.intellij.psi.PsiMember} objects.
* @return a filtered list of only the methods as a {@link MethodElement} objects.
*/
public static List<MethodElement> getOnlyAsMethodElements(Collection<PsiMember> members) {
public static List<MethodElement> getOnlyAsMethodElements(Collection<? extends PsiMember> members) {
List<MethodElement> methodElementList = new ArrayList<MethodElement>();
for (PsiMember member : members) {
@@ -76,7 +76,7 @@ public class ElementUtils {
* @param members a list of {@link com.intellij.psi.PsiMember} objects.
* @return a filtered list of only the methods as a {@link FieldElement} or {@link MethodElement} objects.
*/
public static List<Element> getOnlyAsFieldAndMethodElements(Collection<PsiMember> members) {
public static List<Element> getOnlyAsFieldAndMethodElements(Collection<? extends PsiMember> members) {
List<Element> elementList = new ArrayList<Element>();
for (PsiMember member : members) {
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.element;
package org.jetbrains.java.generate.element;
import com.intellij.openapi.util.text.StringUtil;
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.element;
package org.jetbrains.java.generate.element;
import com.intellij.openapi.util.text.StringUtil;
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.exception;
package org.jetbrains.java.generate.exception;
/**
* Template resource related exceptions.
@@ -13,10 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.template;
package org.jetbrains.java.generate.template;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.generate.tostring.util.StringUtil;
import java.io.Serializable;
@@ -42,6 +41,54 @@ public class TemplateResource implements Serializable {
isDefault = false;
}
/**
* Returns the part of s after the token.
* <p/>
* <br/>Example: after("helloWorldThisIsMe", "World") will return "ThisIsMe".
* <br/>Example: after("helloWorldThisIsMe", "Dog") will return null.
*
* @param s the string to test.
* @param token the token.
* @return the part of s that is after the token.
*/
public static String after(String s, String token) {
if (s == null) {
return null;
}
int i = s.indexOf(token);
if (i == -1) {
return s;
}
return s.substring(i + token.length());
}
/**
* Returns the part of s before the token.
* <p/>
* <br/>Example: before("helloWorldThisIsMe", "World") will return "hello".
* <br/>Example: before("helloWorldThisIsMe", "Dog") will return "helloWorldThisIsMe".
* <p/>
* If the token is not in the string, the entire string is returned.
*
* @param s the string to test.
* @param token the token.
* @return the part of s that is before the token.
*/
public static String before(String s, String token) {
if (s == null) {
return null;
}
int i = s.indexOf(token);
if (i == -1) {
return s;
}
return s.substring(0, i);
}
public String getTemplate() {
return template;
}
@@ -89,7 +136,7 @@ public class TemplateResource implements Serializable {
@Nullable
private static String getMethodBody(String template) {
String signature = getMethodSignature(template);
String s = StringUtil.after(template, signature);
String s = after(template, signature);
if (s == null) {
return null;
@@ -110,7 +157,7 @@ public class TemplateResource implements Serializable {
}
private static String getMethodSignature(String template) {
String s = StringUtil.after(template, "*/").trim();
String s = after(template, "*/").trim();
StringBuffer signature = new StringBuffer();
@@ -136,7 +183,7 @@ public class TemplateResource implements Serializable {
*/
public String getTargetMethodName() {
String s = getMethodSignature();
s = StringUtil.before(s, "(");
s = before(s, "(");
int i = s.lastIndexOf(" ");
return s.substring(i).trim();
}
@@ -17,34 +17,38 @@
/*
* @author max
*/
package org.jetbrains.generate.tostring.template;
package org.jetbrains.java.generate.template;
import com.intellij.openapi.components.*;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
@State(
name = "ToStringTemplates",
storages = {
@Storage(
file = StoragePathMacros.APP_CONFIG + "/toStringTemplates.xml"
)}
)
public class TemplatesManager implements PersistentStateComponent<TemplatesState> {
public static TemplatesManager getInstance() {
return ServiceManager.getService(TemplatesManager.class);
}
public abstract class TemplatesManager implements PersistentStateComponent<TemplatesState> {
private TemplatesState myState = new TemplatesState();
private TemplatesState myState = new TemplatesState();
public TemplatesManager() {
for (TemplateResource o : TemplateResourceLocator.getDefaultTemplates()) {
addTemplate(o);
}
}
public abstract TemplateResource[] getDefaultTemplates();
/**
* Reads the content of the resource and return it as a String.
* <p/>Uses the class loader that loaded this class to find the resource in its classpath.
*
* @param resource the resource name. Will lookup using the classpath.
* @return the content if the resource
* @throws java.io.IOException error reading the file.
*/
protected static String readFile(String resource, Class<? extends TemplatesManager> templatesManagerClass) throws IOException {
BufferedInputStream in = new BufferedInputStream(templatesManagerClass.getResourceAsStream(resource));
return StringUtil.convertLineSeparators(FileUtil.loadTextAndClose(new InputStreamReader(in, CharsetToolkit.UTF8_CHARSET)));
}
public TemplatesState getState() {
public TemplatesState getState() {
return myState;
}
@@ -67,14 +71,10 @@ public class TemplatesManager implements PersistentStateComponent<TemplatesState
}
public Collection<TemplateResource> getAllTemplates() {
TemplateResource[] defaultTemplates = TemplateResourceLocator.getDefaultTemplates();
HashSet<String> names = new HashSet<String>();
for (TemplateResource defaultTemplate : defaultTemplates) {
names.add(defaultTemplate.getFileName());
}
Collection<TemplateResource> templates = new LinkedHashSet<TemplateResource>(Arrays.asList(defaultTemplates));
Collection<TemplateResource> templates = new LinkedHashSet<TemplateResource>(Arrays.asList(getDefaultTemplates()));
for (TemplateResource template : myState.templates) {
if (!names.contains(template.getFileName())) {
if (names.add(template.getFileName())) {
templates.add(template);
}
}
@@ -17,7 +17,7 @@
/*
* @author max
*/
package org.jetbrains.generate.tostring.template;
package org.jetbrains.java.generate.template;
import java.util.ArrayList;
import java.util.List;

Some files were not shown because too many files have changed in this diff Show More