Merge remote branch 'origin/master'

This commit is contained in:
irengrig
2012-10-08 11:44:17 +04:00
267 changed files with 8038 additions and 3112 deletions
+2 -2
View File
@@ -1,11 +1,11 @@
<component name="libraryTable">
<library name="Netty">
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/netty-3.5.7.Final.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/netty-3.5.8.Final.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/netty-3.5.7.Final-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/src/netty-3.5.8.Final-sources.jar!/" />
</SOURCES>
</library>
</component>
+1 -1
View File
@@ -233,7 +233,7 @@ libraryLicense(name: "XML-RPC", libraryName: "XmlRPC", version: "2.0", license:
libraryLicense(name: "XStream", version: "1.2.1", license: "BSD", url: "http://xstream.codehaus.org/", licenseUrl: "http://xstream.codehaus.org/license.html")
libraryLicense(name: "YourKit Java Profiler", libraryName: "yjp-controller-api-redist.jar", version: "8.0.x", license: "link (commercial license)", url: "http://yourkit.com/", licenseUrl: "http://www.yourkit.com/purchase/license.html")
libraryLicense(name: "protobuf", version: "2.3.0", license: "New BSD", url: "http://code.google.com/p/protobuf/", licenseUrl: "http://code.google.com/p/protobuf/source/browse/trunk/COPYING.txt?r=367")
libraryLicense(name: "Netty", libraryName: "Netty", version: "3.5.7", license: "Apache 2.0", url: "http://netty.io", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
libraryLicense(name: "Netty", libraryName: "Netty", version: "3.5.8", license: "Apache 2.0", url: "http://netty.io", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
libraryLicense(name: "Kryo", libraryName: "Kryo", version: "1.04", license: "New BSD License", url: "http://code.google.com/p/kryo/", licenseUrl: "http://www.opensource.org/licenses/bsd-license.php")
libraryLicense(name: "Snappy-Java", libraryName: "Snappy-Java", version: "1.0.4.1", license: "Apache 2.0", url: "http://code.google.com/p/snappy-java/", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0")
libraryLicense(name: "Cucumber-JVM", libraryName: "cucumber-jvm", version: "1.0.11", license: "MIT License", url: "https://github.com/cucumber/cucumber-jvm/", licenseUrl: "http://www.opensource.org/licenses/mit-license.html")
@@ -42,6 +42,7 @@ import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.wm.*;
@@ -67,7 +68,7 @@ public class NewProjectUtil {
}
}, ProjectBundle.message("project.new.wizard.progress.title"), true, null);
if (!proceed) return;
AddModuleWizard dialog = new AddModuleWizard(null, ModulesProvider.EMPTY_MODULES_PROVIDER, defaultPath);
final AddModuleWizard dialog = new AddModuleWizard(null, ModulesProvider.EMPTY_MODULES_PROVIDER, defaultPath);
dialog.show();
if (!dialog.isOK()) {
return;
@@ -92,8 +93,18 @@ public class NewProjectUtil {
}
}
final Project newProject =
projectBuilder == null || !projectBuilder.isUpdate() ? projectManager.newProject(dialog.getProjectName(), projectFilePath, true, false) : projectToClose;
final Project newProject;
if (projectBuilder == null || !projectBuilder.isUpdate()) {
newProject = ProgressManager.getInstance().runProcessWithProgressSynchronously(new ThrowableComputable<Project, RuntimeException>() {
@Override
public Project compute() throws RuntimeException {
return projectManager.newProject(dialog.getProjectName(), projectFilePath, true, false);
}
}, "Creating Project", true, null);
}
else {
newProject = projectToClose;
}
if (newProject == null) return;
@@ -20,6 +20,7 @@ import com.intellij.ide.util.projectWizard.ProjectBuilder;
import com.intellij.ide.util.projectWizard.WizardContext;
import com.intellij.openapi.module.ModifiableModuleModel;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.util.Condition;
@@ -95,7 +96,7 @@ public class ArchivedProjectTemplate implements ProjectTemplate {
try {
File dir = new File(path);
ZipInputStream zipInputStream = getStream();
ZipUtil.unzip(null, dir, zipInputStream);
ZipUtil.unzip(ProgressManager.getInstance().getProgressIndicator(), dir, zipInputStream);
VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(dir);
RefreshQueue.getInstance().refresh(false, true, null, virtualFile);
iml = ContainerUtil.find(dir.list(), new Condition<String>() {
@@ -86,18 +86,17 @@ public class CreateClassDialog extends DialogWrapper {
public CreateClassDialog(@NotNull Project project,
@NotNull String title,
String targetClassName,
String targetPackageName,
@NotNull String targetClassName,
@NotNull String targetPackageName,
@NotNull CreateClassKind kind,
boolean classNameEditable,
Module defaultModule) {
@Nullable Module defaultModule) {
super(project, true);
myClassNameEditable = classNameEditable;
myModule = defaultModule;
myClassName = targetClassName;
myProject = project;
final String normalizedPackageName = targetPackageName != null ? targetPackageName : "";
myPackageComponent = new PackageNameReferenceEditorCombo(normalizedPackageName, myProject, RECENTS_KEY, CodeInsightBundle.message("dialog.create.class.package.chooser.title"));
myPackageComponent = new PackageNameReferenceEditorCombo(targetPackageName, myProject, RECENTS_KEY, CodeInsightBundle.message("dialog.create.class.package.chooser.title"));
myPackageComponent.setTextFieldPreferredWidth(40);
init();
@@ -111,7 +110,7 @@ public class CreateClassDialog extends DialogWrapper {
}
myTfClassName.setText(myClassName);
myDestinationCB.setData(myProject, getBaseDir(normalizedPackageName), new Pass<String>() {
myDestinationCB.setData(myProject, getBaseDir(targetPackageName), new Pass<String>() {
@Override
public void pass(String s) {
setErrorText(s);
@@ -278,6 +277,7 @@ public class CreateClassDialog extends DialogWrapper {
return myModule == null? null : PackageUtil.findPossiblePackageDirectoryInModule(myModule, packageName);
}
@NotNull
public String getClassName() {
if (myClassNameEditable) {
return myTfClassName.getText();
@@ -31,6 +31,7 @@ import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
import com.intellij.psi.util.PsiFormatUtil;
import com.intellij.psi.util.PsiFormatUtilBase;
import com.intellij.util.Function;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -38,6 +39,8 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import static com.intellij.psi.util.PsiFormatUtilBase.*;
public class PsiMethodTreeElement extends JavaClassTreeElementBase<PsiMethod> implements SortableTreeElement, LocationPresentation {
private String myLocation;
@@ -67,19 +70,17 @@ public class PsiMethodTreeElement extends JavaClassTreeElementBase<PsiMethod> im
if (!(aClass instanceof PsiAnonymousClass) && !(aClass instanceof PsiTypeParameter)) {
result.add(new JavaClassTreeElement(aClass, isInherited(), new HashSet<PsiClass>(Arrays.asList(aClass.getSupers()))));
}
}
});
return result;
}
public String getPresentableText() {
return StringUtil.replace(PsiFormatUtil.formatMethod(
getElement(),
PsiSubstitutor.EMPTY, PsiFormatUtilBase.SHOW_NAME |
PsiFormatUtilBase.SHOW_TYPE | PsiFormatUtilBase.TYPE_AFTER | PsiFormatUtilBase.SHOW_PARAMETERS,
PsiFormatUtilBase.SHOW_TYPE
), ":", ": ");
String method = PsiFormatUtil.formatMethod(getElement(),
PsiSubstitutor.EMPTY,
SHOW_NAME | SHOW_TYPE | TYPE_AFTER | SHOW_PARAMETERS,
SHOW_TYPE);
return StringUtil.replace(method, ":", ": ");
}
@@ -104,15 +105,16 @@ public class PsiMethodTreeElement extends JavaClassTreeElementBase<PsiMethod> im
//some searchers (EJB) require indices. What shall we do?
}
if (myLocation == null) {
if (StringUtil.isEmpty(myLocation)) {
myLocation = "";
} else {
char upArrow = '\u2191';
myLocation = UIUtil.getLabelFont().canDisplay(upArrow) ? upArrow + myLocation : myLocation;
}
}
return StringUtil.isEmpty(myLocation) ? null : myLocation;
}
@Override
public TextAttributesKey getTextAttributesKey() {
if (isInherited()) return CodeInsightColors.NOT_USED_ELEMENT_ATTRIBUTES;
@@ -139,7 +141,7 @@ public class PsiMethodTreeElement extends JavaClassTreeElementBase<PsiMethod> im
@Override
public String getLocationPrefix() {
return " \u2191";
return " ";
}
@Override
@@ -1186,7 +1186,7 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
@Override
public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) {
if ((myRole1 == ChildRole.DOUBLE_COLON && myRole2 == ChildRole.EXPRESSION) ||
if ((myRole1 == ChildRole.DOUBLE_COLON && myRole2 == ChildRole.REFERENCE_NAME) ||
(myRole1 == ChildRole.EXPRESSION && myRole2 == ChildRole.DOUBLE_COLON)) {
createSpaceInCode(mySettings.SPACE_AROUND_METHOD_REF_DBL_COLON);
}
@@ -35,8 +35,8 @@ public class JavaCodeFragmentFactoryImpl extends JavaCodeFragmentFactory {
@NotNull
@Override
public PsiExpressionCodeFragment createExpressionCodeFragment(@NotNull final String text,
final PsiElement context,
final PsiType expectedType,
@Nullable final PsiElement context,
@Nullable final PsiType expectedType,
final boolean isPhysical) {
return new PsiExpressionCodeFragmentImpl(myProject, isPhysical, "fragment.java", text, expectedType, context);
}
@@ -62,7 +62,7 @@ public class JavaCodeFragmentFactoryImpl extends JavaCodeFragmentFactory {
@NotNull
@Override
public PsiJavaCodeReferenceCodeFragment createReferenceCodeFragment(@NotNull final String text,
final PsiElement context,
@Nullable final PsiElement context,
final boolean isPhysical,
final boolean isClassesAccepted) {
return new PsiJavaCodeReferenceCodeFragmentImpl(myProject, isPhysical, "fragment.java", text, isClassesAccepted, context);
@@ -39,6 +39,7 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.testFramework.LightVirtualFile;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.LinkedHashMap;
import java.util.StringTokenizer;
@@ -59,7 +60,7 @@ public class PsiCodeFragmentImpl extends PsiFileImpl implements JavaCodeFragment
boolean isPhysical,
@NonNls String name,
CharSequence text,
PsiElement context) {
@Nullable PsiElement context) {
super(TokenType.CODE_FRAGMENT,
contentElementType,
((PsiManagerEx)PsiManager.getInstance(project)).getFileManager().createFileViewProvider(
@@ -25,6 +25,7 @@ import com.intellij.psi.PsiType;
import com.intellij.psi.impl.source.tree.ElementType;
import com.intellij.psi.impl.source.tree.JavaElementType;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
public class PsiExpressionCodeFragmentImpl extends PsiCodeFragmentImpl implements PsiExpressionCodeFragment {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiExpressionCodeFragmentImpl");
@@ -34,12 +35,13 @@ public class PsiExpressionCodeFragmentImpl extends PsiCodeFragmentImpl implement
boolean isPhysical,
@NonNls String name,
CharSequence text,
final PsiType expectedType,
PsiElement context) {
@Nullable final PsiType expectedType,
@Nullable PsiElement context) {
super(project, JavaElementType.EXPRESSION_TEXT, isPhysical, name, text, context);
setExpectedType(expectedType);
}
@Nullable
@Override
public PsiExpression getExpression() {
ASTNode exprChild = calcTreeElement().findChildByType(ElementType.EXPRESSION_BIT_SET);
@@ -57,7 +59,7 @@ public class PsiExpressionCodeFragmentImpl extends PsiCodeFragmentImpl implement
}
@Override
public void setExpectedType(PsiType type) {
public void setExpectedType(@Nullable PsiType type) {
myExpectedType = type;
if (type != null) {
LOG.assertTrue(type.isValid());
@@ -23,6 +23,7 @@ import com.intellij.psi.PsiJavaCodeReferenceElement;
import com.intellij.psi.impl.source.tree.CompositeElement;
import com.intellij.psi.impl.source.tree.JavaElementType;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
/**
* @author ven
@@ -36,7 +37,7 @@ public class PsiJavaCodeReferenceCodeFragmentImpl extends PsiCodeFragmentImpl im
@NonNls final String name,
final CharSequence text,
boolean isClassesAccepted,
PsiElement context) {
@Nullable PsiElement context) {
super(project, JavaElementType.REFERENCE_TEXT, isPhysical, name, text, context);
myIsClassesAccepted = isClassesAccepted;
}
@@ -80,7 +80,7 @@ import static com.intellij.refactoring.changeSignature.ChangeSignatureHandler.RE
/**
* @author Konstantin Bulenkov
*/
public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase<ParameterInfoImpl, PsiMethod, String, JavaMethodDescriptor> {
public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase<ParameterInfoImpl, PsiMethod, String, JavaMethodDescriptor, ParameterTableModelItemBase<ParameterInfoImpl>, JavaParameterTableModel> {
private ExceptionsTableModel myExceptionsModel;
protected Set<PsiMethod> myMethodsToPropagateExceptions;
private AnActionButton myPropExceptionsButton;
@@ -192,8 +192,8 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase<Paramet
}
@Override
protected ParameterTableModelBase<ParameterInfoImpl> createParametersInfoModel(MethodDescriptor<ParameterInfoImpl, String> descriptor) {
final PsiParameterList parameterList = ((JavaMethodDescriptor)descriptor).getMethod().getParameterList();
protected JavaParameterTableModel createParametersInfoModel(JavaMethodDescriptor descriptor) {
final PsiParameterList parameterList = descriptor.getMethod().getParameterList();
return new JavaParameterTableModel(parameterList, myDefaultValueContext, this);
}
@@ -45,7 +45,7 @@ import java.awt.event.KeyEvent;
import java.util.LinkedHashSet;
import java.util.Set;
public class JavaParameterTableModel extends ParameterTableModelBase<ParameterInfoImpl> {
public class JavaParameterTableModel extends ParameterTableModelBase<ParameterInfoImpl, ParameterTableModelItemBase<ParameterInfoImpl>> {
private final Project myProject;
public JavaParameterTableModel(final PsiElement typeContext,
@@ -54,12 +54,13 @@ public class JavaParameterTableModel extends ParameterTableModelBase<ParameterIn
this(typeContext, defaultValueContext,
new JavaTypeColumn(typeContext.getProject()),
new JavaNameColumn(typeContext.getProject()),
new DefaultValueColumn<ParameterInfoImpl>(typeContext.getProject(), StdFileTypes.JAVA) {
new DefaultValueColumn<ParameterInfoImpl, ParameterTableModelItemBase<ParameterInfoImpl>>(typeContext.getProject(), StdFileTypes.JAVA) {
@Override
public TableCellEditor doCreateEditor(ParameterTableModelItemBase<ParameterInfoImpl> item) {
return new EditorWithExpectedType(typeContext);
}
}, new AnyVarColumn<ParameterInfoImpl>() {
},
new AnyVarColumn<ParameterInfoImpl, ParameterTableModelItemBase<ParameterInfoImpl>>() {
@Override
public boolean isCellEditable(ParameterTableModelItemBase<ParameterInfoImpl> item) {
boolean isGenerateDelegate = ((ChangeSignatureDialogBase)dialog).isGenerateDelegate();
@@ -128,8 +129,7 @@ public class JavaParameterTableModel extends ParameterTableModelBase<ParameterIn
boolean isSelected,
final int row,
int column) {
final EditorTextField textField =
(EditorTextField)super.getTableCellEditorComponent(table, value, isSelected, row, column);
final EditorTextField textField = (EditorTextField)super.getTableCellEditorComponent(table, value, isSelected, row, column);
textField.registerKeyboardAction(new ActionListener() {
public void actionPerformed(ActionEvent e) {
PsiType type = getRowType(table, row);
@@ -171,12 +171,9 @@ public class JavaParameterTableModel extends ParameterTableModelBase<ParameterIn
}
}
public static class JavaTypeColumn extends TypeColumn<ParameterInfoImpl> {
private final Project myProject;
public static class JavaTypeColumn extends TypeColumn<ParameterInfoImpl, ParameterTableModelItemBase<ParameterInfoImpl>> {
public JavaTypeColumn(Project project) {
super(project, StdFileTypes.JAVA);
myProject = project;
}
@Override
@@ -185,7 +182,7 @@ public class JavaParameterTableModel extends ParameterTableModelBase<ParameterIn
}
}
public static class JavaNameColumn extends NameColumn<ParameterInfoImpl> {
public static class JavaNameColumn extends NameColumn<ParameterInfoImpl, ParameterTableModelItemBase<ParameterInfoImpl>> {
private final Project myProject;
public JavaNameColumn(Project project) {
@@ -323,7 +323,7 @@ public class CanonicalTypes {
}
}
public static Type createTypeWrapper(final PsiType type) {
public static Type createTypeWrapper(@NotNull final PsiType type) {
return type.accept(Creator.INSTANCE);
}
}
@@ -59,7 +59,7 @@ public class LambdaUtil {
}
@Nullable
public static PsiMethod getFunctionalInterfaceMethod(PsiType functionalInterfaceType) {
public static PsiMethod getFunctionalInterfaceMethod(@Nullable PsiType functionalInterfaceType) {
return getFunctionalInterfaceMethod(PsiUtil.resolveGenericsClassInType(functionalInterfaceType));
}
@@ -224,8 +224,12 @@ public class LambdaUtil {
if (checkReturnType) {
final String uniqueVarName =
JavaCodeStyleManager.getInstance(lambdaExpression.getProject()).suggestUniqueVariableName("l", lambdaExpression, true);
String canonicalText = leftType.getCanonicalText();
if (leftType instanceof PsiEllipsisType) {
canonicalText = ((PsiEllipsisType)leftType).toArrayType().getCanonicalText();
}
final PsiStatement assignmentFromText = JavaPsiFacade.getElementFactory(lambdaExpression.getProject())
.createStatementFromText(leftType.getCanonicalText() + " " + uniqueVarName + " = " + lambdaExpression.getText(), lambdaExpression);
.createStatementFromText(canonicalText + " " + uniqueVarName + " = " + lambdaExpression.getText(), lambdaExpression);
final PsiLocalVariable localVariable = (PsiLocalVariable)((PsiDeclarationStatement)assignmentFromText).getDeclaredElements()[0];
LOG.assertTrue(psiClass != null);
PsiType methodReturnType = getReturnType(psiClass, methodSignature);
@@ -75,7 +75,7 @@ public interface PsiAnnotation extends PsiAnnotationMemberValue, PsiMetaOwner {
* the element and the element has no default value.
*/
@Nullable
PsiAnnotationMemberValue findAttributeValue(@NonNls String attributeName);
PsiAnnotationMemberValue findAttributeValue(@Nullable @NonNls String attributeName);
/**
* Returns the value of the annotation element with the specified name.
@@ -28,6 +28,7 @@ public interface PsiExpressionCodeFragment extends JavaCodeFragment {
*
* @return the expression contained in the fragment.
*/
@Nullable
PsiExpression getExpression();
/**
@@ -85,7 +85,7 @@ public class PsiImplUtil {
}
@Nullable
public static PsiAnnotationMemberValue findAttributeValue(@NotNull PsiAnnotation annotation, @NonNls String attributeName) {
public static PsiAnnotationMemberValue findAttributeValue(@NotNull PsiAnnotation annotation, @Nullable @NonNls String attributeName) {
final PsiAnnotationMemberValue value = findDeclaredAttributeValue(annotation, attributeName);
if (value != null) return value;
@@ -38,7 +38,10 @@ public abstract class JavaCodeFragmentFactory {
* @return the created code fragment.
*/
@NotNull
public abstract PsiExpressionCodeFragment createExpressionCodeFragment(@NotNull String text, PsiElement context, final PsiType expectedType, boolean isPhysical);
public abstract PsiExpressionCodeFragment createExpressionCodeFragment(@NotNull String text,
@Nullable PsiElement context,
@Nullable final PsiType expectedType,
boolean isPhysical);
/**
* Creates a Java code fragment from the text of a Java code block.
@@ -77,7 +80,7 @@ public abstract class JavaCodeFragmentFactory {
* @return the created code fragment.
*/
@NotNull
public abstract PsiTypeCodeFragment createTypeCodeFragment(@NotNull String text, PsiElement context, boolean isPhysical);
public abstract PsiTypeCodeFragment createTypeCodeFragment(@NotNull String text, @Nullable PsiElement context, boolean isPhysical);
/**
* Creates a Java type code fragment from the text of the name of a Java type (the name
@@ -91,11 +94,12 @@ public abstract class JavaCodeFragmentFactory {
* @param flags types allowed to present in text.
* @return the created code fragment.
*/
@NotNull
public abstract PsiTypeCodeFragment createTypeCodeFragment(@NotNull String text, PsiElement context, boolean isPhysical,
@MagicConstant(flags = {ALLOW_VOID, ALLOW_ELLIPSIS, ALLOW_DISJUNCTION})
int flags);
@NotNull
public abstract PsiTypeCodeFragment createTypeCodeFragment(@NotNull String text,
@Nullable PsiElement context,
boolean isPhysical,
@MagicConstant(flags = {ALLOW_VOID, ALLOW_ELLIPSIS, ALLOW_DISJUNCTION}) int flags);
/**
* Creates a Java reference code fragment from the text of a Java reference to a
* package or class.
@@ -110,7 +114,7 @@ public abstract class JavaCodeFragmentFactory {
*/
@NotNull
public abstract PsiJavaCodeReferenceCodeFragment createReferenceCodeFragment(@NotNull String text,
PsiElement context,
@Nullable PsiElement context,
boolean isPhysical,
boolean isClassesAccepted);
@@ -1,6 +1,7 @@
package org.jetbrains.jps.builders;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
import java.io.File;
import java.util.Collection;
@@ -22,7 +23,7 @@ public abstract class AdditionalRootsProviderService<R extends BuildRootDescript
}
@NotNull
public List<R> getAdditionalRoots(@NotNull BuildTarget<R> target, File dataStorageRoot) {
public List<R> getAdditionalRoots(@NotNull BuildTarget<R> target, BuildDataPaths dataPaths) {
return Collections.emptyList();
}
}
@@ -2,6 +2,7 @@ package org.jetbrains.jps.builders;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
import org.jetbrains.jps.indices.IgnoredFileIndex;
import org.jetbrains.jps.indices.ModuleExcludeIndex;
import org.jetbrains.jps.model.JpsModel;
@@ -32,7 +33,10 @@ public abstract class BuildTarget<R extends BuildRootDescriptor> {
}
@NotNull
public abstract List<R> computeRootDescriptors(JpsModel model, ModuleExcludeIndex index, IgnoredFileIndex ignoredFileIndex);
public abstract List<R> computeRootDescriptors(JpsModel model,
ModuleExcludeIndex index,
IgnoredFileIndex ignoredFileIndex,
BuildDataPaths dataPaths);
@Nullable
public abstract BuildRootDescriptor findRootDescriptor(String rootId, BuildRootIndex rootIndex);
@@ -15,7 +15,7 @@ public abstract class BuildTargetType<T extends BuildTarget<?>> {
myTypeId = typeId;
}
public String getTypeId() {
public final String getTypeId() {
return myTypeId;
}
@@ -0,0 +1,39 @@
package org.jetbrains.jps.builders.impl;
import com.intellij.util.PathUtilRt;
import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.builders.BuildTargetType;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
import java.io.File;
/**
* @author nik
*/
public class BuildDataPathsImpl implements BuildDataPaths {
private final File myDataStorageRoot;
public BuildDataPathsImpl(File dataStorageRoot) {
myDataStorageRoot = dataStorageRoot;
}
@Override
public File getDataStorageRoot() {
return myDataStorageRoot;
}
@Override
public File getTargetsDataRoot() {
return new File(myDataStorageRoot, "targets");
}
@Override
public File getTargetTypeDataRoot(BuildTargetType<?> targetType) {
return new File(getTargetsDataRoot(), targetType.getTypeId());
}
@Override
public File getTargetDataRoot(BuildTarget<?> target) {
return new File(getTargetTypeDataRoot(target.getTargetType()), PathUtilRt.suggestFileName(target.getId(), true, true));
}
}
@@ -11,6 +11,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.builders.*;
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
import org.jetbrains.jps.incremental.BuilderRegistry;
import org.jetbrains.jps.incremental.CompileContext;
import org.jetbrains.jps.indices.IgnoredFileIndex;
@@ -33,32 +34,30 @@ public class BuildRootIndexImpl implements BuildRootIndex {
private THashMap<File,List<BuildRootDescriptor>> myRootToDescriptor;
private ConcurrentMap<BuildRootDescriptor, FileFilter> myFileFilters;
public BuildRootIndexImpl(BuildTargetIndex targetIndex,
JpsModel model,
ModuleExcludeIndex index,
File dataStorageRoot, final IgnoredFileIndex ignoredFileIndex) {
public BuildRootIndexImpl(BuildTargetIndex targetIndex, JpsModel model, ModuleExcludeIndex index,
BuildDataPaths dataPaths, final IgnoredFileIndex ignoredFileIndex) {
myRootsByTarget = new HashMap<BuildTarget<?>, List<? extends BuildRootDescriptor>>();
myRootToDescriptor = new THashMap<File, List<BuildRootDescriptor>>(FileUtil.FILE_HASHING_STRATEGY);
myFileFilters = new ConcurrentHashMap<BuildRootDescriptor, FileFilter>();
final Iterable<AdditionalRootsProviderService> rootsProviders = JpsServiceManager.getInstance().getExtensions(AdditionalRootsProviderService.class);
for (BuildTargetType<?> targetType : BuilderRegistry.getInstance().getTargetTypes()) {
for (BuildTarget<?> target : targetIndex.getAllTargets(targetType)) {
addRoots(dataStorageRoot, rootsProviders, targetType, target, model, index, ignoredFileIndex);
addRoots(dataPaths, rootsProviders, targetType, target, model, index, ignoredFileIndex);
}
}
}
private <R extends BuildRootDescriptor> void addRoots(File dataStorageRoot, Iterable<AdditionalRootsProviderService> rootsProviders,
private <R extends BuildRootDescriptor> void addRoots(BuildDataPaths dataPaths, Iterable<AdditionalRootsProviderService> rootsProviders,
BuildTargetType<?> targetType, BuildTarget<R> target,
JpsModel model,
ModuleExcludeIndex index,
IgnoredFileIndex ignoredFileIndex) {
List<R> descriptors = target.computeRootDescriptors(model, index, ignoredFileIndex);
List<R> descriptors = target.computeRootDescriptors(model, index, ignoredFileIndex, dataPaths);
for (AdditionalRootsProviderService<?> provider : rootsProviders) {
if (provider.getTargetTypes().contains(targetType)) {
//noinspection unchecked
AdditionalRootsProviderService<R> providerService = (AdditionalRootsProviderService<R>)provider;
final List<R> additionalRoots = providerService.getAdditionalRoots(target, dataStorageRoot);
final List<R> additionalRoots = providerService.getAdditionalRoots(target, dataPaths);
if (!additionalRoots.isEmpty()) {
descriptors = new ArrayList<R>(descriptors);
descriptors.addAll(additionalRoots);
@@ -0,0 +1,19 @@
package org.jetbrains.jps.builders.storage;
import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.builders.BuildTargetType;
import java.io.File;
/**
* @author nik
*/
public interface BuildDataPaths {
File getDataStorageRoot();
File getTargetsDataRoot();
File getTargetTypeDataRoot(BuildTargetType<?> targetType);
File getTargetDataRoot(BuildTarget<?> target);
}
@@ -11,9 +11,11 @@ import org.jetbrains.jps.builders.BuildRootDescriptor;
import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.builders.BuildTargetLoader;
import org.jetbrains.jps.builders.BuildTargetType;
import org.jetbrains.jps.builders.impl.BuildDataPathsImpl;
import org.jetbrains.jps.builders.impl.BuildRootIndexImpl;
import org.jetbrains.jps.builders.impl.BuildTargetIndexImpl;
import org.jetbrains.jps.builders.java.dependencyView.Callbacks;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
import org.jetbrains.jps.incremental.*;
import org.jetbrains.jps.incremental.fs.BuildFSState;
import org.jetbrains.jps.incremental.messages.BuildMessage;
@@ -55,17 +57,18 @@ public class BuildRunner {
public ProjectDescriptor load(MessageHandler msgHandler, File dataStorageRoot, BuildFSState fsState) throws IOException {
final JpsModel jpsModel = myModelLoader.loadModel();
BuildDataPaths dataPaths = new BuildDataPathsImpl(dataStorageRoot);
BuildTargetIndexImpl targetIndex = new BuildTargetIndexImpl(jpsModel);
ModuleExcludeIndex index = new ModuleExcludeIndexImpl(jpsModel);
IgnoredFileIndexImpl ignoredFileIndex = new IgnoredFileIndexImpl(jpsModel);
BuildRootIndexImpl buildRootIndex = new BuildRootIndexImpl(targetIndex, jpsModel, index, dataStorageRoot, ignoredFileIndex);
BuildTargetsState targetsState = new BuildTargetsState(dataStorageRoot, jpsModel, buildRootIndex);
BuildRootIndexImpl buildRootIndex = new BuildRootIndexImpl(targetIndex, jpsModel, index, dataPaths, ignoredFileIndex);
BuildTargetsState targetsState = new BuildTargetsState(dataPaths, jpsModel, buildRootIndex);
ProjectTimestamps projectTimestamps = null;
BuildDataManager dataManager = null;
try {
projectTimestamps = new ProjectTimestamps(dataStorageRoot, targetsState);
dataManager = new BuildDataManager(dataStorageRoot, targetsState, STORE_TEMP_CACHES_IN_MEMORY);
dataManager = new BuildDataManager(dataPaths, targetsState, STORE_TEMP_CACHES_IN_MEMORY);
if (dataManager.versionDiffers()) {
myForceCleanCaches = true;
msgHandler.processMessage(new CompilerMessage("build", BuildMessage.Kind.INFO, "Dependency data format has changed, project rebuild required"));
@@ -82,9 +85,9 @@ public class BuildRunner {
}
myForceCleanCaches = true;
FileUtil.delete(dataStorageRoot);
targetsState = new BuildTargetsState(dataStorageRoot, jpsModel, buildRootIndex);
targetsState = new BuildTargetsState(dataPaths, jpsModel, buildRootIndex);
projectTimestamps = new ProjectTimestamps(dataStorageRoot, targetsState);
dataManager = new BuildDataManager(dataStorageRoot, targetsState, STORE_TEMP_CACHES_IN_MEMORY);
dataManager = new BuildDataManager(dataPaths, targetsState, STORE_TEMP_CACHES_IN_MEMORY);
// second attempt succeded
msgHandler.processMessage(new CompilerMessage("build", BuildMessage.Kind.INFO, "Project rebuild forced: " + e.getMessage()));
}
@@ -18,7 +18,7 @@ public class BuilderRegistry {
static final BuilderRegistry ourInstance = new BuilderRegistry();
}
private final Map<BuilderCategory, List<ModuleLevelBuilder>> myModuleLevelBuilders = new HashMap<BuilderCategory, List<ModuleLevelBuilder>>();
private final List<TargetBuilder<?>> myTargetBuilders = new ArrayList<TargetBuilder<?>>();
private final List<TargetBuilder<?,?>> myTargetBuilders = new ArrayList<TargetBuilder<?,?>>();
private final Map<String, BuildTargetType<?>> myTargetTypes = new LinkedHashMap<String, BuildTargetType<?>>();
public static BuilderRegistry getInstance() {
@@ -79,7 +79,7 @@ public class BuilderRegistry {
return ContainerUtil.concat(myModuleLevelBuilders.values());
}
public List<TargetBuilder<?>> getTargetBuilders() {
public List<TargetBuilder<?,?>> getTargetBuilders() {
return myTargetBuilders;
}
}
@@ -20,7 +20,7 @@ public abstract class BuilderService {
}
@NotNull
public List<? extends TargetBuilder<?>> createBuilders() {
public List<? extends TargetBuilder<?,?>> createBuilders() {
return Collections.emptyList();
}
}
@@ -5,6 +5,7 @@ import com.intellij.openapi.util.io.FileSystemUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.builders.BuildRootDescriptor;
import org.jetbrains.jps.util.JpsPathUtil;
import org.jetbrains.jps.ModuleChunk;
import org.jetbrains.jps.builders.BuildTarget;
@@ -131,17 +132,21 @@ public class FSOperations {
Timestamps timestamps, boolean forceMarkDirty,
@Nullable THashSet<File> currentFiles) throws IOException {
final ModuleExcludeIndex rootsIndex = context.getProjectDescriptor().getModuleExcludeIndex();
final Set<File> excludes = new HashSet<File>(rootsIndex.getModuleExcludes(target.getModule()));
for (JavaSourceRootDescriptor rd : context.getProjectDescriptor().getBuildRootIndex().getTargetRoots(target, context)) {
if (!rd.root.exists()) {
markDirtyFiles(context, target, timestamps, forceMarkDirty, currentFiles,
new HashSet<File>(rootsIndex.getModuleExcludes(target.getModule())));
}
static void markDirtyFiles(CompileContext context, BuildTarget<?> target, Timestamps timestamps, boolean forceMarkDirty, @Nullable THashSet<File> currentFiles, final Set<File> excludes) throws IOException {
for (BuildRootDescriptor rd : context.getProjectDescriptor().getBuildRootIndex().getTargetRoots(target, context)) {
if (!rd.getRootFile().exists()) {
continue;
}
context.getProjectDescriptor().fsState.clearRecompile(rd);
traverseRecursively(context, rd, rd.root, excludes, timestamps, forceMarkDirty, currentFiles);
traverseRecursively(context, rd, rd.getRootFile(), excludes, timestamps, forceMarkDirty, currentFiles);
}
}
private static void traverseRecursively(CompileContext context, final JavaSourceRootDescriptor rd, final File file, Set<File> excludes, @NotNull final Timestamps tsStorage, final boolean forceDirty, @Nullable Set<File> currentFiles) throws IOException {
private static void traverseRecursively(CompileContext context, final BuildRootDescriptor rd, final File file, Set<File> excludes, @NotNull final Timestamps tsStorage, final boolean forceDirty, @Nullable Set<File> currentFiles) throws IOException {
final File[] children = file.listFiles();
if (children != null) { // is directory
if (children.length > 0 && !JpsPathUtil.isUnder(excludes, file)) {
@@ -153,7 +158,7 @@ public class FSOperations {
else { // is file
boolean markDirty = forceDirty;
if (!markDirty) {
markDirty = tsStorage.getStamp(file, rd.target) != FileSystemUtil.lastModified(file);
markDirty = tsStorage.getStamp(file, rd.getTarget()) != FileSystemUtil.lastModified(file);
}
if (markDirty) {
// if it is full project rebuild, all storages are already completely cleared;
@@ -528,13 +528,19 @@ public class IncProjectBuilder {
buildModuleChunk(context, new ModuleChunk(Collections.singleton(moduleBuildTarget)));
}
else {
buildTarget(target, context);
try {
buildTarget(target, context);
}
catch (IOException e) {
throw new ProjectBuildException(e);
}
}
}
private void buildTarget(BuildTarget<?> target, CompileContext context) throws ProjectBuildException {
List<TargetBuilder<?>> builders = BuilderRegistry.getInstance().getTargetBuilders();
for (TargetBuilder<?> builder : builders) {
private void buildTarget(BuildTarget<?> target, CompileContext context) throws ProjectBuildException, IOException {
ensureFSStateInitialized(context, target);
List<TargetBuilder<?,?>> builders = BuilderRegistry.getInstance().getTargetBuilders();
for (TargetBuilder<?,?> builder : builders) {
buildTarget(target, context, builder);
updateDoneFraction(context, 1.0f / builders.size());
}
@@ -546,10 +552,17 @@ public class IncProjectBuilder {
context.setDone(processed / myTotalTargetsWork);
}
private static <B extends BuildTarget<?>> void buildTarget(B target, CompileContext context, TargetBuilder<?> builder) throws ProjectBuildException {
private static <R extends BuildRootDescriptor, T extends BuildTarget<R>> void buildTarget(final T target, final CompileContext context, TargetBuilder<?,?> builder)
throws ProjectBuildException, IOException {
if (builder.getTargetTypes().contains(target.getTargetType())) {
DirtyFilesHolder<R, T> holder = new DirtyFilesHolder<R, T>() {
@Override
public void processDirtyFiles(@NotNull FileProcessor<R, T> processor) throws IOException {
context.getProjectDescriptor().fsState.processFilesToRecompile(context, target, processor);
}
};
//noinspection unchecked
((TargetBuilder<B>)builder).build(target, context);
((TargetBuilder<R,T>)builder).build(target, context, holder);
context.checkCanceled();
}
}
@@ -952,6 +965,16 @@ public class IncProjectBuilder {
}
}
private static void ensureFSStateInitialized(CompileContext context, BuildTarget<?> target) throws IOException {
final ProjectDescriptor pd = context.getProjectDescriptor();
final Timestamps timestamps = pd.timestamps.getStorage();
final BuildTargetConfiguration configuration = pd.getTargetsState().getTargetConfiguration(target);
if (context.isProjectRebuild() || configuration.isTargetDirty() || context.getScope().isRecompilationForced(target)) {
FSOperations.markDirtyFiles(context, target, timestamps, true, null, Collections.<File>emptySet());
configuration.save();
}
}
private static void ensureFSStateInitialized(CompileContext context, ModuleChunk chunk) throws IOException {
final ProjectDescriptor pd = context.getProjectDescriptor();
final Timestamps timestamps = pd.timestamps.getStorage();
@@ -3,6 +3,7 @@ package org.jetbrains.jps.incremental;
import com.intellij.util.Consumer;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
import org.jetbrains.jps.util.JpsPathUtil;
import org.jetbrains.jps.builders.BuildRootIndex;
import org.jetbrains.jps.builders.BuildTarget;
@@ -79,7 +80,10 @@ public class ModuleBuildTarget extends BuildTarget<JavaSourceRootDescriptor> {
@NotNull
@Override
public List<JavaSourceRootDescriptor> computeRootDescriptors(JpsModel model, ModuleExcludeIndex index, IgnoredFileIndex ignoredFileIndex) {
public List<JavaSourceRootDescriptor> computeRootDescriptors(JpsModel model,
ModuleExcludeIndex index,
IgnoredFileIndex ignoredFileIndex,
BuildDataPaths dataPaths) {
List<JavaSourceRootDescriptor> roots = new ArrayList<JavaSourceRootDescriptor>();
JavaSourceRootType type = isTests() ? JavaSourceRootType.TEST_SOURCE : JavaSourceRootType.SOURCE;
for (JpsTypedModuleSourceRoot<JpsSimpleElement<JavaSourceRootProperties>> sourceRoot : myModule.getSourceRoots(type)) {
@@ -1,26 +1,30 @@
package org.jetbrains.jps.incremental;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.BuildRootDescriptor;
import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.builders.BuildTargetType;
import org.jetbrains.jps.builders.DirtyFilesHolder;
import java.io.IOException;
import java.util.Collection;
/**
* Use {@link BuilderService} to register implementations of this class
* @author nik
*/
public abstract class TargetBuilder<B extends BuildTarget<?>> extends Builder {
private final Collection<? extends BuildTargetType<? extends B>> myTargetTypes;
public abstract class TargetBuilder<R extends BuildRootDescriptor, T extends BuildTarget<R>> extends Builder {
private final Collection<? extends BuildTargetType<? extends T>> myTargetTypes;
protected TargetBuilder(Collection<? extends BuildTargetType<? extends B>> targetTypes) {
protected TargetBuilder(Collection<? extends BuildTargetType<? extends T>> targetTypes) {
myTargetTypes = targetTypes;
}
public Collection<? extends BuildTargetType<? extends B>> getTargetTypes() {
public Collection<? extends BuildTargetType<? extends T>> getTargetTypes() {
return myTargetTypes;
}
public abstract void build(@NotNull B target, @NotNull CompileContext context) throws ProjectBuildException;
public abstract void build(@NotNull T target, @NotNull CompileContext context, DirtyFilesHolder<R, T> holder)
throws ProjectBuildException, IOException;
}
@@ -6,20 +6,16 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.BuildRootDescriptor;
import org.jetbrains.jps.builders.BuildRootIndex;
import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
import org.jetbrains.jps.incremental.ModuleBuildTarget;
import org.jetbrains.jps.indices.IgnoredFileIndex;
import org.jetbrains.jps.indices.ModuleExcludeIndex;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
import org.jetbrains.jps.incremental.artifacts.builders.LayoutElementBuildersRegistry;
import org.jetbrains.jps.incremental.artifacts.impl.JpsArtifactUtil;
import org.jetbrains.jps.incremental.artifacts.instructions.*;
import org.jetbrains.jps.indices.IgnoredFileIndex;
import org.jetbrains.jps.indices.ModuleExcludeIndex;
import org.jetbrains.jps.model.JpsModel;
import org.jetbrains.jps.model.artifact.JpsArtifact;
import org.jetbrains.jps.model.artifact.elements.JpsArtifactOutputPackagingElement;
import org.jetbrains.jps.model.artifact.elements.JpsPackagingElement;
import org.jetbrains.jps.model.java.JpsProductionModuleOutputPackagingElement;
import org.jetbrains.jps.model.java.JpsTestModuleOutputPackagingElement;
import org.jetbrains.jps.model.module.JpsModule;
import java.io.PrintWriter;
import java.util.Collection;
@@ -61,18 +57,7 @@ public class ArtifactBuildTarget extends BuildTarget<ArtifactRootDescriptor> {
}
}
}
else if (element instanceof JpsProductionModuleOutputPackagingElement) {
JpsModule module = ((JpsProductionModuleOutputPackagingElement)element).getModuleReference().resolve();
if (module != null) {
dependencies.add(new ModuleBuildTarget(module, JavaModuleBuildTargetType.PRODUCTION));
}
}
else if (element instanceof JpsTestModuleOutputPackagingElement) {
JpsModule module = ((JpsTestModuleOutputPackagingElement)element).getModuleReference().resolve();
if (module != null) {
dependencies.add(new ModuleBuildTarget(module, JavaModuleBuildTargetType.TEST));
}
}
dependencies.addAll(LayoutElementBuildersRegistry.getInstance().getDependencies(element));
return true;
}
});
@@ -102,9 +87,12 @@ public class ArtifactBuildTarget extends BuildTarget<ArtifactRootDescriptor> {
@NotNull
@Override
public List<ArtifactRootDescriptor> computeRootDescriptors(JpsModel model, ModuleExcludeIndex index, IgnoredFileIndex ignoredFileIndex) {
public List<ArtifactRootDescriptor> computeRootDescriptors(JpsModel model,
ModuleExcludeIndex index,
IgnoredFileIndex ignoredFileIndex,
BuildDataPaths dataPaths) {
ArtifactInstructionsBuilderImpl builder = new ArtifactInstructionsBuilderImpl(index, ignoredFileIndex, this);
ArtifactInstructionsBuilderContext context = new ArtifactInstructionsBuilderContextImpl();
ArtifactInstructionsBuilderContext context = new ArtifactInstructionsBuilderContextImpl(model, dataPaths);
String outputPath = StringUtil.notNullize(myArtifact.getOutputPath());
final CopyToDirectoryInstructionCreator instructionCreator = new CopyToDirectoryInstructionCreator(builder, outputPath);
LayoutElementBuildersRegistry.getInstance().generateInstructions(myArtifact, instructionCreator, context);
@@ -19,7 +19,7 @@ public class ArtifactBuilderService extends BuilderService {
@NotNull
@Override
public List<? extends TargetBuilder<?>> createBuilders() {
public List<? extends TargetBuilder<?,?>> createBuilders() {
return Collections.singletonList(new IncArtifactBuilder());
}
}
@@ -9,6 +9,7 @@ import gnu.trove.TIntObjectHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.BuildRootDescriptor;
import org.jetbrains.jps.builders.BuildRootIndex;
import org.jetbrains.jps.builders.DirtyFilesHolder;
import org.jetbrains.jps.builders.storage.SourceToOutputMapping;
import org.jetbrains.jps.cmdline.ProjectDescriptor;
import org.jetbrains.jps.incremental.*;
@@ -28,7 +29,7 @@ import java.util.*;
/**
* @author nik
*/
public class IncArtifactBuilder extends TargetBuilder<ArtifactBuildTarget> {
public class IncArtifactBuilder extends TargetBuilder<ArtifactRootDescriptor, ArtifactBuildTarget> {
public static final String BUILDER_NAME = "artifacts";
public IncArtifactBuilder() {
@@ -36,7 +37,9 @@ public class IncArtifactBuilder extends TargetBuilder<ArtifactBuildTarget> {
}
@Override
public void build(@NotNull ArtifactBuildTarget target, @NotNull CompileContext context) throws ProjectBuildException {
public void build(@NotNull ArtifactBuildTarget target,
@NotNull CompileContext context,
DirtyFilesHolder<ArtifactRootDescriptor, ArtifactBuildTarget> holder) throws ProjectBuildException {
JpsArtifact artifact = target.getArtifact();
if (StringUtil.isEmpty(artifact.getOutputPath())) {
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, "Cannot build '" + artifact.getName() + "' artifact: output path is not specified"));
@@ -1,9 +1,14 @@
package org.jetbrains.jps.incremental.artifacts.builders;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.incremental.artifacts.instructions.ArtifactCompilerInstructionCreator;
import org.jetbrains.jps.incremental.artifacts.instructions.ArtifactInstructionsBuilderContext;
import org.jetbrains.jps.model.artifact.elements.JpsPackagingElement;
import java.util.Collection;
import java.util.Collections;
/**
* @author nik
*/
@@ -16,6 +21,10 @@ public abstract class LayoutElementBuilderService<E extends JpsPackagingElement>
public abstract void generateInstructions(E element, ArtifactCompilerInstructionCreator instructionCreator, ArtifactInstructionsBuilderContext builderContext);
public Collection<? extends BuildTarget<?>> getDependencies(@NotNull E element) {
return Collections.emptyList();
}
public final Class<E> getElementClass() {
return myElementClass;
}
@@ -4,6 +4,12 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ClassMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
import org.jetbrains.jps.incremental.ModuleBuildTarget;
import org.jetbrains.jps.model.module.JpsModule;
import org.jetbrains.jps.util.JpsPathUtil;
import org.jetbrains.jps.incremental.artifacts.instructions.ArtifactCompilerInstructionCreator;
import org.jetbrains.jps.incremental.artifacts.instructions.ArtifactInstructionsBuilderContext;
@@ -15,6 +21,8 @@ import org.jetbrains.jps.model.java.JpsTestModuleOutputPackagingElement;
import org.jetbrains.jps.service.JpsServiceManager;
import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
@@ -24,9 +32,9 @@ public class LayoutElementBuildersRegistry {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.artifacts.builders.LayoutElementBuildersRegistry");
private static class InstanceHolder {
static final LayoutElementBuildersRegistry ourInstance = new LayoutElementBuildersRegistry();
}
public static LayoutElementBuildersRegistry getInstance() {
return InstanceHolder.ourInstance;
}
@@ -53,16 +61,30 @@ public class LayoutElementBuildersRegistry {
generateInstructions(artifact.getRootElement(), creator, context);
}
public Collection<BuildTarget<?>> getDependencies(JpsPackagingElement element) {
LayoutElementBuilderService builder = getElementBuilder(element);
if (builder != null) {
//noinspection unchecked
return builder.getDependencies(element);
}
return Collections.emptyList();
}
private void generateInstructions(JpsPackagingElement layoutElement, ArtifactCompilerInstructionCreator instructionCreator,
ArtifactInstructionsBuilderContext builderContext) {
final LayoutElementBuilderService builder = myBuilders.get(layoutElement.getClass());
final LayoutElementBuilderService builder = getElementBuilder(layoutElement);
if (builder != null) {
//noinspection unchecked
builder.generateInstructions(layoutElement, instructionCreator, builderContext);
}
else {
}
private LayoutElementBuilderService<?> getElementBuilder(JpsPackagingElement layoutElement) {
final LayoutElementBuilderService<?> builder = myBuilders.get(layoutElement.getClass());
if (builder == null) {
LOG.error("Builder not found for artifact output layout element of class " + layoutElement.getClass());
}
return builder;
}
private void generateChildrenInstructions(JpsCompositePackagingElement element, ArtifactCompilerInstructionCreator instructionCreator,
@@ -86,7 +108,7 @@ public class LayoutElementBuildersRegistry {
}
}
private static void generateModuleOutputInstructions(String outputUrl, ArtifactCompilerInstructionCreator creator) {
private static void generateModuleOutputInstructions(@Nullable String outputUrl, ArtifactCompilerInstructionCreator creator) {
if (outputUrl != null) {
creator.addDirectoryCopyInstructions(JpsPathUtil.urlToFile(outputUrl));
}
@@ -194,6 +216,15 @@ public class LayoutElementBuildersRegistry {
ArtifactInstructionsBuilderContext builderContext) {
generateModuleOutputInstructions(element.getOutputUrl(), instructionCreator);
}
@Override
public Collection<? extends BuildTarget<?>> getDependencies(@NotNull JpsProductionModuleOutputPackagingElement element) {
JpsModule module = element.getModuleReference().resolve();
if (module != null) {
return Collections.singletonList(new ModuleBuildTarget(module, JavaModuleBuildTargetType.PRODUCTION));
}
return Collections.emptyList();
}
}
private static class ModuleTestOutputElementBuilder extends LayoutElementBuilderService<JpsTestModuleOutputPackagingElement> {
@@ -207,6 +238,15 @@ public class LayoutElementBuildersRegistry {
ArtifactInstructionsBuilderContext builderContext) {
generateModuleOutputInstructions(element.getOutputUrl(), instructionCreator);
}
@Override
public Collection<? extends BuildTarget<?>> getDependencies(@NotNull JpsTestModuleOutputPackagingElement element) {
JpsModule module = element.getModuleReference().resolve();
if (module != null) {
return Collections.singletonList(new ModuleBuildTarget(module, JavaModuleBuildTargetType.TEST));
}
return Collections.emptyList();
}
}
private class ComplexElementBuilder extends LayoutElementBuilderService<JpsComplexPackagingElement> {
@@ -1,5 +1,7 @@
package org.jetbrains.jps.incremental.artifacts.instructions;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
import org.jetbrains.jps.model.JpsModel;
import org.jetbrains.jps.model.artifact.JpsArtifact;
/**
@@ -10,4 +12,8 @@ public interface ArtifactInstructionsBuilderContext {
boolean enterArtifact(JpsArtifact artifact);
void leaveArtifact(JpsArtifact artifact);
BuildDataPaths getDataPaths();
JpsModel getModel();
}
@@ -1,5 +1,7 @@
package org.jetbrains.jps.incremental.artifacts.instructions;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
import org.jetbrains.jps.model.JpsModel;
import org.jetbrains.jps.model.artifact.JpsArtifact;
import java.util.HashSet;
@@ -10,11 +12,25 @@ import java.util.Set;
*/
public class ArtifactInstructionsBuilderContextImpl implements ArtifactInstructionsBuilderContext {
private final Set<JpsArtifact> myParentArtifacts;
private final JpsModel myModel;
private final BuildDataPaths myDataPaths;
public ArtifactInstructionsBuilderContextImpl() {
public ArtifactInstructionsBuilderContextImpl(JpsModel model, BuildDataPaths dataPaths) {
myModel = model;
myDataPaths = dataPaths;
myParentArtifacts = new HashSet<JpsArtifact>();
}
@Override
public JpsModel getModel() {
return myModel;
}
@Override
public BuildDataPaths getDataPaths() {
return myDataPaths;
}
@Override
public boolean enterArtifact(JpsArtifact artifact) {
return myParentArtifacts.add(artifact);
@@ -6,6 +6,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.builders.impl.BuildTargetChunk;
import org.jetbrains.jps.builders.java.dependencyView.Mappings;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
import org.jetbrains.jps.incremental.artifacts.ArtifactsBuildData;
import java.io.*;
@@ -20,7 +21,6 @@ import java.util.Map;
public class BuildDataManager implements StorageOwner {
private static final int VERSION = 12;
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.storage.BuildDataManager");
private static final String SRC_TO_OUTPUTS_STORAGE = "src-out";
private static final String SRC_TO_FORM_STORAGE = "src-form";
private static final String MAPPINGS_STORAGE = "mappings";
@@ -31,22 +31,22 @@ public class BuildDataManager implements StorageOwner {
private final ArtifactsBuildData myArtifactsBuildData;
private final ModuleOutputRootsLayout myOutputRootsLayout;
private final Mappings myMappings;
private final File myDataStorageRoot;
private final BuildDataPaths myDataPaths;
private final BuildTargetsState myTargetsState;
private final File myVersionFile;
public BuildDataManager(final File dataStorageRoot, BuildTargetsState targetsState, final boolean useMemoryTempCaches) throws IOException {
myDataStorageRoot = dataStorageRoot;
public BuildDataManager(final BuildDataPaths dataPaths, BuildTargetsState targetsState, final boolean useMemoryTempCaches) throws IOException {
myDataPaths = dataPaths;
myTargetsState = targetsState;
mySrcToFormMap = new SourceToFormMapping(new File(getSourceToFormsRoot(), "data"));
myOutputRootsLayout = new ModuleOutputRootsLayout(new File(getOutputsLayoutRoot(), "data"));
myMappings = new Mappings(getMappingsRoot(), useMemoryTempCaches);
myArtifactsBuildData = new ArtifactsBuildData(new File(dataStorageRoot, "artifacts"));
myVersionFile = new File(myDataStorageRoot, "version.dat");
myArtifactsBuildData = new ArtifactsBuildData(new File(dataPaths.getDataStorageRoot(), "artifacts"));
myVersionFile = new File(myDataPaths.getDataStorageRoot(), "version.dat");
}
private File getOutputsLayoutRoot() {
return new File(myDataStorageRoot, "output-roots");
return new File(myDataPaths.getDataStorageRoot(), "output-roots");
}
public SourceToOutputMappingImpl getSourceToOutputMap(final BuildTarget<?> target) throws IOException {
@@ -54,7 +54,7 @@ public class BuildDataManager implements StorageOwner {
synchronized (mySourceToOutputLock) {
mapping = mySourceToOutputs.get(target);
if (mapping == null) {
mapping = new SourceToOutputMappingImpl(new File(myTargetsState.getTargetDataRoot(target), "src-out" + File.separator + "data"));
mapping = new SourceToOutputMappingImpl(new File(myDataPaths.getTargetDataRoot(target), "src-out" + File.separator + "data"));
mySourceToOutputs.put(target, mapping);
}
}
@@ -204,16 +204,16 @@ public class BuildDataManager implements StorageOwner {
}
}
public File getSourceToFormsRoot() {
return new File(myDataStorageRoot, SRC_TO_FORM_STORAGE);
private File getSourceToFormsRoot() {
return new File(myDataPaths.getDataStorageRoot(), SRC_TO_FORM_STORAGE);
}
public File getMappingsRoot() {
return new File(myDataStorageRoot, MAPPINGS_STORAGE);
private File getMappingsRoot() {
return new File(myDataPaths.getDataStorageRoot(), MAPPINGS_STORAGE);
}
public File getDataStorageRoot() {
return myDataStorageRoot;
public BuildDataPaths getDataPaths() {
return myDataPaths;
}
private static void wipeStorage(File root, @Nullable AbstractStateStorage<?, ?> storage) {
@@ -75,6 +75,6 @@ public class BuildTargetConfiguration {
}
private File getConfigFile() {
return new File(myTargetsState.getTargetDataRoot(myTarget), "config.dat");
return new File(myTargetsState.getDataPaths().getTargetDataRoot(myTarget), "config.dat");
}
}
@@ -27,7 +27,7 @@ public class BuildTargetTypeState {
public BuildTargetTypeState(BuildTargetType<?> targetType, BuildTargetsState state) {
myTargetType = targetType;
myTargetsState = state;
myTargetsFile = new File(state.getTargetTypeDataRoot(targetType), "targets.dat");
myTargetsFile = new File(state.getDataPaths().getTargetTypeDataRoot(targetType), "targets.dat");
myConfigurations = new ConcurrentHashMap<BuildTarget<?>, BuildTargetConfiguration>();
myTargetIds = new HashMap<BuildTarget<?>, Integer>();
load();
@@ -2,12 +2,12 @@ package org.jetbrains.jps.incremental.storage;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.PathUtilRt;
import com.intellij.util.containers.ConcurrentHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.builders.BuildTargetType;
import org.jetbrains.jps.builders.impl.BuildRootIndexImpl;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
import org.jetbrains.jps.incremental.BuilderRegistry;
import org.jetbrains.jps.model.JpsModel;
@@ -20,14 +20,14 @@ import java.util.concurrent.atomic.AtomicInteger;
*/
public class BuildTargetsState {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.storage.BuildTargetsState");
private final File myDataStorageRoot;
private final BuildDataPaths myDataPaths;
private AtomicInteger myMaxTargetId = new AtomicInteger(0);
private ConcurrentMap<BuildTargetType<?>, BuildTargetTypeState> myTypeStates = new ConcurrentHashMap<BuildTargetType<?>, BuildTargetTypeState>();
private JpsModel myModel;
private final BuildRootIndexImpl myBuildRootIndex;
public BuildTargetsState(File dataStorageRoot, JpsModel model, BuildRootIndexImpl buildRootIndex) {
myDataStorageRoot = dataStorageRoot;
public BuildTargetsState(BuildDataPaths dataPaths, JpsModel model, BuildRootIndexImpl buildRootIndex) {
myDataPaths = dataPaths;
myModel = model;
myBuildRootIndex = buildRootIndex;
File targetTypesFile = getTargetTypesFile();
@@ -49,16 +49,8 @@ public class BuildTargetsState {
}
}
public File getTargetTypeDataRoot(BuildTargetType<?> targetType) {
return new File(getTargetsDataRoot(), targetType.getTypeId());
}
public File getTargetsDataRoot() {
return new File(myDataStorageRoot, "targets");
}
private File getTargetTypesFile() {
return new File(getTargetsDataRoot(), "targetTypes.dat");
return new File(myDataPaths.getTargetsDataRoot(), "targetTypes.dat");
}
public void save() {
@@ -113,12 +105,8 @@ public class BuildTargetsState {
return myMaxTargetId.incrementAndGet();
}
public File getTargetDataRoot(BuildTarget<?> target) {
return new File(getTargetTypeDataRoot(target.getTargetType()), PathUtilRt.suggestFileName(target.getId(), true, true));
}
public void clean() {
FileUtil.delete(getTargetsDataRoot());
FileUtil.delete(myDataPaths.getTargetsDataRoot());
}
public JpsModel getModel() {
@@ -128,4 +116,8 @@ public class BuildTargetsState {
public BuildRootIndexImpl getBuildRootIndex() {
return myBuildRootIndex;
}
public BuildDataPaths getDataPaths() {
return myDataPaths;
}
}
@@ -6,6 +6,8 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.testFramework.UsefulTestCase;
import com.intellij.util.io.TestFileSystemBuilder;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.builders.impl.BuildDataPathsImpl;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
import org.jetbrains.jps.util.JpsPathUtil;
import org.jetbrains.jps.api.CanceledStatus;
import org.jetbrains.jps.builders.impl.BuildRootIndexImpl;
@@ -125,10 +127,11 @@ public abstract class JpsBuildTestCase extends UsefulTestCase {
BuildTargetIndexImpl targetIndex = new BuildTargetIndexImpl(myModel);
ModuleExcludeIndex index = new ModuleExcludeIndexImpl(myModel);
IgnoredFileIndexImpl ignoredFileIndex = new IgnoredFileIndexImpl(myModel);
BuildRootIndexImpl buildRootIndex = new BuildRootIndexImpl(targetIndex, myModel, index, myDataStorageRoot, ignoredFileIndex);
BuildTargetsState targetsState = new BuildTargetsState(myDataStorageRoot, myModel, buildRootIndex);
BuildDataPaths dataPaths = new BuildDataPathsImpl(myDataStorageRoot);
BuildRootIndexImpl buildRootIndex = new BuildRootIndexImpl(targetIndex, myModel, index, dataPaths, ignoredFileIndex);
BuildTargetsState targetsState = new BuildTargetsState(dataPaths, myModel, buildRootIndex);
ProjectTimestamps timestamps = new ProjectTimestamps(myDataStorageRoot, targetsState);
BuildDataManager dataManager = new BuildDataManager(myDataStorageRoot, targetsState, true);
BuildDataManager dataManager = new BuildDataManager(dataPaths, targetsState, true);
return new ProjectDescriptor(myModel, new BuildFSState(true), timestamps, dataManager, buildLoggingManager, index, targetsState,
targetIndex, buildRootIndex, ignoredFileIndex);
}
@@ -186,7 +189,7 @@ public abstract class JpsBuildTestCase extends UsefulTestCase {
return module;
}
protected void doRebuild() {
protected void rebuildAll() {
ProjectDescriptor descriptor = createProjectDescriptor(new BuildLoggingManager(new ArtifactBuilderLoggerImpl(), new JavaBuilderLoggerImpl()));
try {
CompileScope scope = new CompileScopeImpl(true, BuilderRegistry.getInstance().getTargetTypes(), Collections.<BuildTarget<?>>emptySet(), Collections.<BuildTarget<?>,Set<File>>emptyMap());
@@ -39,7 +39,7 @@ abstract class JpsRebuildTestCase extends JpsBuildTestCase {
protected void rebuild() {
JpsJavaExtensionService.getInstance().getOrCreateProjectExtension(myProject).outputUrl = JpsPathUtil.pathToUrl(FileUtil.toSystemIndependentName(getOrCreateOutputDirectory().getAbsolutePath()))
doRebuild()
rebuildAll()
}
private File getOrCreateOutputDirectory() {
@@ -25,7 +25,7 @@ public class ResourceCopyingTest extends JpsBuildTestCase {
public void testSimple() {
String file = createFile("src/a.xml");
JpsModule m = addModule("m", PathUtil.getParentPath(file));
doRebuild();
rebuildAll();
assertOutput(m, fs().file("a.xml"));
}
public void testPackagePrefix() {
@@ -35,7 +35,7 @@ public class ResourceCopyingTest extends JpsBuildTestCase {
JpsTypedModuleSourceRoot<JpsSimpleElement<JavaSourceRootProperties>> typed = sourceRoot.asTyped(JavaSourceRootType.SOURCE);
assertNotNull(typed);
typed.getProperties().setData(new JavaSourceRootProperties("xxx"));
doRebuild();
rebuildAll();
assertOutput(m, fs().dir("xxx").file("a.xml"));
}
}
@@ -21,7 +21,7 @@ public class RebuildArtifactOnConfigurationChangeTest extends ArtifactBuilderTes
a.getRootElement().addChild(JpsPackagingElementFactory.getInstance().createDirectoryCopy(dir2));
buildAll();
assertOutput(a, fs().file("a.txt", "a").file("b.txt", "b"));
assertCopied("dir1/a.txt", "dir2/b.txt");
assertDeletedAndCopied("out/artifacts/a/a.txt", "dir1/a.txt", "dir2/b.txt");
buildAllAndAssertUpToDate();
}
@@ -1,6 +1,8 @@
package org.jetbrains.jps.util;
import com.intellij.openapi.util.SystemInfoRt;
import com.intellij.openapi.util.io.FileUtilRt;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.Set;
@@ -39,6 +41,23 @@ public class JpsPathUtil {
return url;
}
//todo[nik] copied from VfsUtil
@NotNull
public static String fixURLforIDEA(@NotNull String url ) {
int idx = url.indexOf(":/");
if( idx >= 0 && idx+2 < url.length() && url.charAt(idx+2) != '/' ) {
String prefix = url.substring(0, idx);
String suffix = url.substring(idx+2);
if (SystemInfoRt.isWindows) {
url = prefix+"://"+suffix;
} else {
url = prefix+":///"+suffix;
}
}
return url;
}
public static String pathToUrl(String path) {
return "file://" + path;
}
@@ -7,7 +7,9 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.model.JpsElement;
import org.jetbrains.jps.model.JpsElementFactory;
import org.jetbrains.jps.model.module.JpsModule;
import org.jetbrains.jps.model.module.JpsModuleReference;
import org.jetbrains.jps.model.serialization.JpsModelSerializerExtension;
import java.util.List;
@@ -68,4 +70,13 @@ public class JpsFacetSerializer {
}
return null;
}
public static JpsModuleReference createModuleReference(String facetId) {
String moduleName = facetId.substring(0, facetId.indexOf('/'));
return JpsElementFactory.getInstance().createModuleReference(moduleName);
}
public static String getFacetId(final JpsModuleReference moduleReference, final String facetTypeId, final String facetName) {
return moduleReference.getModuleName() + "/" + facetTypeId + "/" + facetName;
}
}
+1 -1
View File
@@ -45,5 +45,5 @@ xmlrpc-2.0.jar
xpp3-1.1.4-min.jar
xstream.jar
swingx-core-1.6.2.jar
netty-3.5.7.Final.jar
netty-3.5.8.Final.jar
protobuf-2.4.1.jar
@@ -30,9 +30,9 @@ import javax.swing.*;
public class RunContentDescriptor implements Disposable {
private static final Logger LOG = Logger.getInstance("#com.intellij.execution.ui.RunContentDescriptor");
private final ExecutionConsole myExecutionConsole;
private ExecutionConsole myExecutionConsole;
private ProcessHandler myProcessHandler;
private final JComponent myComponent;
private JComponent myComponent;
private final String myDisplayName;
private final Icon myIcon;
@@ -74,6 +74,11 @@ public class RunContentDescriptor implements Disposable {
public void dispose() {
if (myExecutionConsole != null) {
Disposer.dispose(myExecutionConsole);
myExecutionConsole = null;
}
if (myComponent != null) {
DataManager.removeDataProvider(myComponent);
myComponent = null;
}
}
@@ -278,10 +278,22 @@ public abstract class TabbedLanguageCodeStylePanel extends CodeStyleAbstractPane
public void setupCopyFromMenu(JPopupMenu copyMenu) {
super.setupCopyFromMenu(copyMenu);
if (myPredefinedCodeStyles.length > 0) {
JMenu langs = new JMenu("Language"); //TODO<rv>: Move to resource bundle
JMenu langs = new JMenu("Language") {
@Override
public void paint(Graphics g) {
GraphicsUtil.setupAntialiasing(g);
super.paint(g);
}
}; //TODO<rv>: Move to resource bundle
copyMenu.add(langs);
fillLanguages(langs);
JMenu predefined = new JMenu("Predefined Style"); //TODO<rv>: Move to resource bundle
JMenu predefined = new JMenu("Predefined Style") {
@Override
public void paint(Graphics g) {
GraphicsUtil.setupAntialiasing(g);
super.paint(g);
}
}; //TODO<rv>: Move to resource bundle
copyMenu.add(predefined);
fillPredefined(predefined);
}
@@ -298,7 +310,13 @@ public abstract class TabbedLanguageCodeStylePanel extends CodeStyleAbstractPane
for (final Language lang : languages) {
if (!lang.equals(getDefaultLanguage())) {
final String langName = LanguageCodeStyleSettingsProvider.getLanguageName(lang);
JMenuItem langItem = new JMenuItem(langName);
JMenuItem langItem = new JMenuItem(langName) {
@Override
public void paint(Graphics g) {
GraphicsUtil.setupAntialiasing(g);
super.paint(g);
}
};
langItem.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
@@ -321,7 +339,13 @@ public abstract class TabbedLanguageCodeStylePanel extends CodeStyleAbstractPane
private void fillPredefined(JMenuItem parentMenu) {
for (final PredefinedCodeStyle predefinedCodeStyle : myPredefinedCodeStyles) {
JMenuItem predefinedItem = new JMenuItem(predefinedCodeStyle.getName());
JMenuItem predefinedItem = new JMenuItem(predefinedCodeStyle.getName()) {
@Override
public void paint(Graphics g) {
GraphicsUtil.setupAntialiasing(g);
super.paint(g);
}
};
parentMenu.add(predefinedItem);
predefinedItem.addActionListener(new ActionListener() {
@Override
@@ -179,7 +179,7 @@ public class ReformatCodeAction extends AnAction implements DumbAware {
final TextRange range;
if (!processWholeFile && editor != null && editor.getSelectionModel().hasSelection()){
range = new TextRange(editor.getSelectionModel().getSelectionStart(), editor.getSelectionModel().getSelectionEnd());
range = TextRange.create(editor.getSelectionModel().getSelectionStart(), editor.getSelectionModel().getSelectionEnd());
}
else{
range = null;
@@ -203,8 +203,8 @@ public class ReformatCodeAction extends AnAction implements DumbAware {
final PsiFile finalFile = file;
SelectionModel selectionModel = editor.getSelectionModel();
final TextRange rangeToUse = selectionModel.hasSelection()
? TextRange.from(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd())
: TextRange.from(0, editor.getDocument().getTextLength());
? TextRange.create(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd())
: TextRange.create(0, editor.getDocument().getTextLength());
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
@Override
public void run() {
@@ -20,7 +20,8 @@ import org.jetbrains.annotations.NonNls;
/**
* @author peter
*/
public interface CodeCompletionFeatures {
public interface
CodeCompletionFeatures {
@NonNls String EXCLAMATION_FINISH = "editing.completion.finishByExclamation";
@NonNls String SECOND_BASIC_COMPLETION = "editing.completion.second.basic";
@NonNls String EDITING_COMPLETION_SMARTTYPE_GENERAL = "editing.completion.smarttype.general";
@@ -26,6 +26,7 @@ import com.intellij.openapi.editor.EditorBundle;
import com.intellij.psi.PsiFile;
import com.intellij.ui.PopupHandler;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.ui.GraphicsUtil;
import javax.swing.*;
import java.awt.*;
@@ -49,7 +50,13 @@ public class DaemonEditorPopup extends PopupHandler {
DaemonCodeAnalyzerSettings.getInstance().NEXT_ERROR_ACTION_GOES_TO_ERRORS_FIRST = errorsFirst.isSelected();
}
});
final JPopupMenu popupMenu = new JPopupMenu();
final JPopupMenu popupMenu = new JPopupMenu() {
@Override
public void paint(Graphics g) {
GraphicsUtil.setupAntialiasing(g);
super.paint(g);
}
};
popupMenu.add(errorsFirst);
final JRadioButtonMenuItem next = new JRadioButtonMenuItem(EditorBundle.message("errors.panel.go.to.next.error.warning.radio"));
@@ -191,7 +191,7 @@ public class HighlightInfo implements Segment {
}
@Nullable
public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @NotNull PsiElement element, String description, String toolTip) {
public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @NotNull PsiElement element, @Nullable String description, @Nullable String toolTip) {
TextRange range = element.getTextRange();
int start = range.getStartOffset();
int end = range.getEndOffset();
@@ -199,8 +199,8 @@ public class HighlightInfo implements Segment {
}
@Nullable
public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @Nullable PsiElement element, int start, int end, String description,
String toolTip,
public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @Nullable PsiElement element, int start, int end, @Nullable String description,
@Nullable String toolTip,
boolean isEndOfLine,
@Nullable TextAttributes forcedAttributes) {
LOG.assertTrue(element != null || ArrayUtil.find(HighlightSeverity.DEFAULT_SEVERITIES, type.getSeverity(element)) != -1, "Custom type demands element to detect its text attributes");
@@ -215,7 +215,7 @@ public class HighlightInfo implements Segment {
return highlightInfo;
}
@Nullable
public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @Nullable PsiElement element, int start, int end, String description, String toolTip) {
public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @Nullable PsiElement element, int start, int end, @Nullable String description, @Nullable String toolTip) {
return createHighlightInfo(type, element, start, end, description, toolTip, false, null);
}
@@ -279,7 +279,7 @@ public class HighlightInfo implements Segment {
this.isFileLevelAnnotation = isFileLevelAnnotation;
}
private static boolean calcNeedUpdateOnTyping(Boolean needsUpdateOnTyping, HighlightInfoType type) {
private static boolean calcNeedUpdateOnTyping(@Nullable Boolean needsUpdateOnTyping, HighlightInfoType type) {
if (needsUpdateOnTyping != null) return needsUpdateOnTyping.booleanValue();
if (type == HighlightInfoType.TODO) return false;
@@ -417,7 +417,7 @@ public class HighlightInfo implements Segment {
return info;
}
private static void appendFixes(TextRange fixedRange, HighlightInfo info, List<Annotation.QuickFixInfo> fixes) {
private static void appendFixes(@Nullable TextRange fixedRange, HighlightInfo info, List<Annotation.QuickFixInfo> fixes) {
if (fixes != null) {
for (final Annotation.QuickFixInfo quickFixInfo : fixes) {
QuickFixAction.registerQuickFixAction(info, fixedRange != null ? fixedRange : quickFixInfo.textRange, quickFixInfo.quickFix,
@@ -435,11 +435,12 @@ public class HighlightInfo implements Segment {
}
public static HighlightInfoType convertSeverity(final HighlightSeverity severity) {
return severity == HighlightSeverity.ERROR
? HighlightInfoType.ERROR
: severity == HighlightSeverity.WARNING ? HighlightInfoType.WARNING
: severity == HighlightSeverity.INFO ? HighlightInfoType.INFO
: severity == HighlightSeverity.WEAK_WARNING ? HighlightInfoType.WEAK_WARNING : HighlightInfoType.INFORMATION;
return severity == HighlightSeverity.ERROR? HighlightInfoType.ERROR :
severity == HighlightSeverity.WARNING ? HighlightInfoType.WARNING :
severity == HighlightSeverity.INFO ? HighlightInfoType.INFO :
severity == HighlightSeverity.WEAK_WARNING ? HighlightInfoType.WEAK_WARNING :
severity ==HighlightSeverity.GENERIC_SERVER_ERROR_OR_WARNING ? HighlightInfoType.GENERIC_WARNINGS_OR_ERRORS_FROM_SERVER :
HighlightInfoType.INFORMATION;
}
public static ProblemHighlightType convertType(HighlightInfoType infoType) {
@@ -450,10 +451,10 @@ public class HighlightInfo implements Segment {
}
public static ProblemHighlightType convertSeverityToProblemHighlight(HighlightSeverity severity) {
return severity == HighlightSeverity.ERROR? ProblemHighlightType.ERROR :
return severity == HighlightSeverity.ERROR ? ProblemHighlightType.ERROR :
severity == HighlightSeverity.WARNING ? ProblemHighlightType.GENERIC_ERROR_OR_WARNING :
severity == HighlightSeverity.INFO ? ProblemHighlightType.INFO :
severity == HighlightSeverity.WEAK_WARNING? ProblemHighlightType.WEAK_WARNING : ProblemHighlightType.INFORMATION;
severity == HighlightSeverity.INFO ? ProblemHighlightType.INFO :
severity == HighlightSeverity.WEAK_WARNING ? ProblemHighlightType.WEAK_WARNING : ProblemHighlightType.INFORMATION;
}
@@ -497,7 +498,7 @@ public class HighlightInfo implements Segment {
this(action, options, displayName, icon, null);
}
public IntentionActionDescriptor(@NotNull IntentionAction action, final List<IntentionAction> options, final String displayName, Icon icon, @Nullable HighlightDisplayKey key) {
public IntentionActionDescriptor(@NotNull IntentionAction action, @Nullable final List<IntentionAction> options, @Nullable final String displayName, @Nullable Icon icon, @Nullable HighlightDisplayKey key) {
myAction = action;
myOptions = options;
myDisplayName = displayName;
@@ -565,6 +566,7 @@ public class HighlightInfo implements Segment {
return options;
}
@Nullable
public String getDisplayName() {
return myDisplayName;
}
@@ -575,6 +577,7 @@ public class HighlightInfo implements Segment {
return "descriptor: " + (text.isEmpty() ? getAction().getClass() : text);
}
@Nullable
public Icon getIcon() {
return myIcon;
}
@@ -116,7 +116,7 @@ public interface HighlightInfoType {
@Override
@NotNull
public HighlightSeverity getSeverity(PsiElement psiElement) {
public HighlightSeverity getSeverity(@Nullable PsiElement psiElement) {
return mySeverity;
}
@@ -133,7 +133,7 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
}
@Nullable
public TextAttributes getTextAttributesBySeverity(HighlightSeverity severity) {
public TextAttributes getTextAttributesBySeverity(@NotNull HighlightSeverity severity) {
final SeverityBasedTextAttributes infoType = ourMap.get(severity.toString());
if (infoType != null) {
return infoType.getAttributes();
@@ -272,6 +272,7 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
return max;
}
@Nullable
public HighlightSeverity getSeverity(@NotNull String name) {
final HighlightInfoType type = STANDARD_SEVERITIES.get(name);
if (type != null) return type.getSeverity(null);
@@ -33,6 +33,7 @@ import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
@@ -45,15 +46,15 @@ import java.util.List;
public final class QuickFixAction {
private QuickFixAction() { }
public static void registerQuickFixAction(HighlightInfo info, IntentionAction action, HighlightDisplayKey key) {
public static void registerQuickFixAction(@Nullable HighlightInfo info, @Nullable IntentionAction action, @Nullable HighlightDisplayKey key) {
registerQuickFixAction(info, null, action, key);
}
public static void registerQuickFixAction(HighlightInfo info, IntentionAction action) {
public static void registerQuickFixAction(@Nullable HighlightInfo info, @Nullable IntentionAction action) {
registerQuickFixAction(info, null, action);
}
public static void registerQuickFixActions(final HighlightInfo info, final Collection<? extends IntentionAction> actions) {
public static void registerQuickFixActions(@Nullable final HighlightInfo info, @NotNull final Collection<? extends IntentionAction> actions) {
for (IntentionAction action : actions) {
registerQuickFixAction(info, action);
}
@@ -61,16 +62,16 @@ public final class QuickFixAction {
/** This is used by TeamCity plugin */
@Deprecated
public static void registerQuickFixAction(HighlightInfo info, IntentionAction action, List<IntentionAction> options, String displayName) {
public static void registerQuickFixAction(@Nullable HighlightInfo info, @Nullable IntentionAction action, @Nullable List<IntentionAction> options, @Nullable String displayName) {
doRegister(info, action, options, displayName, null, null);
}
private static void doRegister(HighlightInfo info,
IntentionAction action,
List<IntentionAction> options,
String displayName,
TextRange fixRange,
HighlightDisplayKey key) {
private static void doRegister(@Nullable HighlightInfo info,
@Nullable IntentionAction action,
@Nullable List<IntentionAction> options,
@Nullable String displayName,
@Nullable TextRange fixRange,
@Nullable HighlightDisplayKey key) {
if (info == null || action == null) return;
if (fixRange == null) fixRange = new TextRange(info.startOffset, info.endOffset);
if (info.quickFixActionRanges == null) {
@@ -85,11 +86,11 @@ public final class QuickFixAction {
}
}
public static void registerQuickFixAction(HighlightInfo info, TextRange fixRange, IntentionAction action, final HighlightDisplayKey key) {
public static void registerQuickFixAction(@Nullable HighlightInfo info, @Nullable TextRange fixRange, @Nullable IntentionAction action, @Nullable final HighlightDisplayKey key) {
doRegister(info, action, null, HighlightDisplayKey.getDisplayNameByKey(key), fixRange, key);
}
public static void registerQuickFixAction(HighlightInfo info, TextRange fixRange, IntentionAction action) {
public static void registerQuickFixAction(@Nullable HighlightInfo info, @Nullable TextRange fixRange, @Nullable IntentionAction action) {
doRegister(info, action, null, null, fixRange, null);
}
@@ -55,6 +55,7 @@ import com.intellij.util.SmartList;
import com.intellij.util.concurrency.Semaphore;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.messages.MessageBus;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -795,7 +796,11 @@ public class PsiDocumentManagerImpl extends PsiDocumentManager implements Projec
@Override
public void save() {
// Ensure all documents are committed on save so file content dependent indices, that use PSI to build have consistent content.
commitAllDocuments();
UIUtil.invokeLaterIfNeeded(new Runnable() {
public void run() {
commitAllDocuments();
}
});
}
@NonNls
@@ -18,6 +18,7 @@ package com.intellij.refactoring.changeSignature;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CustomShortcutSet;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
@@ -53,6 +54,7 @@ import com.intellij.util.ui.table.JBListTable;
import com.intellij.util.ui.table.JBTableRow;
import com.intellij.util.ui.table.JBTableRowEditor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
@@ -72,28 +74,36 @@ import java.util.Set;
/**
* @author Konstantin Bulenkov
*/
public abstract class ChangeSignatureDialogBase<P extends ParameterInfo, M extends PsiElement, V, D extends MethodDescriptor<P, V>>
extends RefactoringDialog {
public abstract class ChangeSignatureDialogBase<
ParamInfo extends ParameterInfo,
Method extends PsiElement,
Visibility,
Descriptor extends MethodDescriptor<ParamInfo, Visibility>,
ParameterTableModelItem extends ParameterTableModelItemBase<ParamInfo>,
ParameterTableModel extends ParameterTableModelBase<ParamInfo, ParameterTableModelItem>
> extends RefactoringDialog {
private static final Logger LOG = Logger.getInstance(ChangeSignatureDialogBase.class);
protected static final String EXIT_SILENTLY = "";
protected final D myMethod;
protected final Descriptor myMethod;
private final boolean myAllowDelegation;
protected JPanel myNamePanel;
protected EditorTextField myNameField;
protected EditorTextField myReturnTypeField;
protected JBListTable myParametersList;
protected TableView<ParameterTableModelItemBase<P>> myParametersTable;
protected final ParameterTableModelBase<P> myParametersTableModel;
protected TableView<ParameterTableModelItem> myParametersTable;
protected final ParameterTableModel myParametersTableModel;
protected final UpdateSignatureListener mySignatureUpdater = new UpdateSignatureListener();
private MethodSignatureComponent mySignatureArea;
private final Alarm myUpdateSignatureAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
protected VisibilityPanelBase<V> myVisibilityPanel;
protected VisibilityPanelBase<Visibility> myVisibilityPanel;
protected PsiCodeFragment myReturnTypeCodeFragment;
private DelegationPanel myDelegationPanel;
protected AnActionButton myPropagateParamChangesButton;
protected Set<M> myMethodsToPropagateParameters = null;
protected Set<Method> myMethodsToPropagateParameters = null;
private Tree myParameterPropagationTreeToReuse;
@@ -101,21 +111,23 @@ public abstract class ChangeSignatureDialogBase<P extends ParameterInfo, M exten
protected abstract LanguageFileType getFileType();
protected abstract ParameterTableModelBase<P> createParametersInfoModel(MethodDescriptor<P, V> method);
protected abstract ParameterTableModel createParametersInfoModel(Descriptor method);
protected abstract BaseRefactoringProcessor createRefactoringProcessor();
protected abstract PsiCodeFragment createReturnTypeCodeFragment();
protected abstract CallerChooserBase<M> createCallerChooser(String title, Tree treeToReuse, Consumer<Set<M>> callback);
@Nullable
protected abstract CallerChooserBase<Method> createCallerChooser(String title, Tree treeToReuse, Consumer<Set<Method>> callback);
@Nullable
protected abstract String validateAndCommitData();
protected abstract String calculateSignature();
protected abstract VisibilityPanelBase<V> createVisibilityControl();
protected abstract VisibilityPanelBase<Visibility> createVisibilityControl();
public ChangeSignatureDialogBase(Project project, final D method, boolean allowDelegation, PsiElement defaultValueContext) {
public ChangeSignatureDialogBase(Project project, final Descriptor method, boolean allowDelegation, PsiElement defaultValueContext) {
super(project, true);
myMethod = method;
myDefaultValueContext = defaultValueContext;
@@ -134,7 +146,7 @@ public abstract class ChangeSignatureDialogBase<P extends ParameterInfo, M exten
});
}
public void setParameterInfos(List<P> parameterInfos) {
public void setParameterInfos(List<ParamInfo> parameterInfos) {
myParametersTableModel.setParameterInfos(parameterInfos);
updateSignature();
}
@@ -148,7 +160,8 @@ public abstract class ChangeSignatureDialogBase<P extends ParameterInfo, M exten
}
}
protected V getVisibility() {
@Nullable
protected Visibility getVisibility() {
if (myVisibilityPanel != null) {
return myVisibilityPanel.getVisibility();
}
@@ -157,9 +170,9 @@ public abstract class ChangeSignatureDialogBase<P extends ParameterInfo, M exten
}
}
public List<P> getParameters() {
List<P> result = new ArrayList<P>(myParametersTableModel.getRowCount());
for (ParameterTableModelItemBase<P> item : myParametersTableModel.getItems()) {
public List<ParamInfo> getParameters() {
List<ParamInfo> result = new ArrayList<ParamInfo>(myParametersTableModel.getRowCount());
for (ParameterTableModelItemBase<ParamInfo> item : myParametersTableModel.getItems()) {
result.add(item.parameter);
}
return result;
@@ -319,18 +332,17 @@ public abstract class ChangeSignatureDialogBase<P extends ParameterInfo, M exten
new AnActionButton(RefactoringBundle.message("changeSignature.propagate.parameters.title"), null, PlatformIcons.NEW_PARAMETER) {
@Override
public void actionPerformed(AnActionEvent e) {
final Ref<CallerChooserBase<M>> chooser = new Ref<CallerChooserBase<M>>();
Consumer<Set<M>> callback = new Consumer<Set<M>>() {
final Ref<CallerChooserBase<Method>> chooser = new Ref<CallerChooserBase<Method>>();
Consumer<Set<Method>> callback = new Consumer<Set<Method>>() {
@Override
public void consume(Set<M> callers) {
public void consume(Set<Method> callers) {
myMethodsToPropagateParameters = callers;
myParameterPropagationTreeToReuse = chooser.get().getTree();
}
};
try {
chooser.set(
createCallerChooser(RefactoringBundle.message("changeSignature.parameter.caller.chooser"), myParameterPropagationTreeToReuse,
callback));
String message = RefactoringBundle.message("changeSignature.parameter.caller.chooser");
chooser.set(createCallerChooser(message, myParameterPropagationTreeToReuse, callback));
}
catch (ProcessCanceledException ex) {
// user cancelled initial callers search, don't show dialog
@@ -368,7 +380,7 @@ public abstract class ChangeSignatureDialogBase<P extends ParameterInfo, M exten
protected JPanel createParametersPanel(boolean hasTabsInDialog) {
myParametersTable = new TableView<ParameterTableModelItemBase<P>>(myParametersTableModel) {
myParametersTable = new TableView<ParameterTableModelItem>(myParametersTableModel) {
public void removeEditor() {
clearEditorListeners();
@@ -427,7 +439,7 @@ public abstract class ChangeSignatureDialogBase<P extends ParameterInfo, M exten
myParametersList = new JBListTable(myParametersTable) {
@Override
protected JComponent getRowRenderer(JTable table, int row, boolean selected, boolean focused) {
final List<ParameterTableModelItemBase<P>> items = myParametersTable.getItems();
final List<ParameterTableModelItem> items = myParametersTable.getItems();
final JComponent component = getRowPresentation(items.get(row), selected, focused);
for (EditorTextField editorTextField : UIUtil.findComponentsOfType(component, EditorTextField.class)) {
editorTextField.addSettingsProvider(new EditorSettingsProvider() {
@@ -442,14 +454,15 @@ public abstract class ChangeSignatureDialogBase<P extends ParameterInfo, M exten
@Override
protected boolean isRowEmpty(int row) {
final List<ParameterTableModelItemBase<P>> items = myParametersTable.getItems();
final List<ParameterTableModelItem> items = myParametersTable.getItems();
return isEmptyRow(items.get(row));
}
@Override
protected JBTableRowEditor getRowEditor(final int row) {
final List<ParameterTableModelItemBase<P>> items = myParametersTable.getItems();
final List<ParameterTableModelItem> items = myParametersTable.getItems();
JBTableRowEditor editor = getTableEditor(myParametersList.getTable(), items.get(row));
LOG.assertTrue(editor != null);
editor.addDocumentListener(new JBTableRowEditor.RowDocumentListener() {
@Override
public void documentChanged(DocumentEvent e, int column) {
@@ -496,19 +509,21 @@ public abstract class ChangeSignatureDialogBase<P extends ParameterInfo, M exten
}
}
protected JBTableRowEditor getTableEditor(JTable table, ParameterTableModelItemBase<P> item) {
@Nullable
protected JBTableRowEditor getTableEditor(JTable table, ParameterTableModelItemBase<ParamInfo> item) {
return null;
}
protected boolean isEmptyRow(ParameterTableModelItemBase<P> row) {
protected boolean isEmptyRow(ParameterTableModelItemBase<ParamInfo> row) {
return false;
}
protected JComponent getRowPresentation(ParameterTableModelItemBase<P> item, boolean selected, boolean focused) {
@Nullable
protected JComponent getRowPresentation(ParameterTableModelItemBase<ParamInfo> item, boolean selected, boolean focused) {
return null;
}
protected void customizeParametersTable(TableView<ParameterTableModelItemBase<P>> table) {
protected void customizeParametersTable(TableView<ParameterTableModelItem> table) {
}
private JComponent createSignaturePanel() {
@@ -592,7 +607,7 @@ public abstract class ChangeSignatureDialogBase<P extends ParameterInfo, M exten
}
private boolean mayPropagateParameters() {
final List<P> infos = getParameters();
final List<ParamInfo> infos = getParameters();
if (infos.size() <= myMethod.getParametersCount()) return false;
for (int i = 0; i < myMethod.getParametersCount(); i++) {
if (infos.get(i).getOldIndex() != i) return false;
@@ -35,8 +35,7 @@ import java.awt.*;
import java.util.ArrayList;
import java.util.List;
public abstract class ParameterTableModelBase<P extends ParameterInfo> extends ListTableModel<ParameterTableModelItemBase<P>>
implements RowEditableTableModel {
public abstract class ParameterTableModelBase<P extends ParameterInfo, TableItem extends ParameterTableModelItemBase<P>> extends ListTableModel<TableItem> implements RowEditableTableModel {
protected final PsiElement myTypeContext;
protected final PsiElement myDefaultValueContext;
@@ -49,14 +48,14 @@ public abstract class ParameterTableModelBase<P extends ParameterInfo> extends L
myDefaultValueContext = defaultValueContext;
}
protected abstract ParameterTableModelItemBase<P> createRowItem(@Nullable P parameterInfo);
protected abstract TableItem createRowItem(@Nullable P parameterInfo);
public void addRow() {
addRow(createRowItem(null));
}
public void setParameterInfos(List<P> parameterInfos) {
List<ParameterTableModelItemBase<P>> items = new ArrayList<ParameterTableModelItemBase<P>>(parameterInfos.size());
List<TableItem> items = new ArrayList<TableItem>(parameterInfos.size());
for (P parameterInfo : parameterInfos) {
items.add(createRowItem(parameterInfo));
}
@@ -73,8 +72,8 @@ public abstract class ParameterTableModelBase<P extends ParameterInfo> extends L
fireTableCellUpdated(rowIndex, columnIndex); // to update signature
}
protected static abstract class ColumnInfoBase<P extends ParameterInfo, Aspect>
extends ColumnInfo<ParameterTableModelItemBase<P>, Aspect> {
protected static abstract class ColumnInfoBase<P extends ParameterInfo, TableItem extends ParameterTableModelItemBase<P>, Aspect>
extends ColumnInfo<TableItem, Aspect> {
private TableCellRenderer myRenderer;
private TableCellEditor myEditor;
@@ -83,7 +82,7 @@ public abstract class ParameterTableModelBase<P extends ParameterInfo> extends L
}
@Override
public final TableCellEditor getEditor(ParameterTableModelItemBase<P> o) {
public final TableCellEditor getEditor(TableItem o) {
if (myEditor == null) {
myEditor = doCreateEditor(o);
}
@@ -91,7 +90,7 @@ public abstract class ParameterTableModelBase<P extends ParameterInfo> extends L
}
@Override
public final TableCellRenderer getRenderer(ParameterTableModelItemBase<P> item) {
public final TableCellRenderer getRenderer(TableItem item) {
if (myRenderer == null) {
final TableCellRenderer original = doCreateRenderer(item);
myRenderer = new TableCellRenderer() {
@@ -119,12 +118,12 @@ public abstract class ParameterTableModelBase<P extends ParameterInfo> extends L
return myRenderer;
}
protected abstract TableCellRenderer doCreateRenderer(ParameterTableModelItemBase<P> item);
protected abstract TableCellRenderer doCreateRenderer(TableItem item);
protected abstract TableCellEditor doCreateEditor(ParameterTableModelItemBase<P> item);
protected abstract TableCellEditor doCreateEditor(TableItem item);
}
protected static class TypeColumn<P extends ParameterInfo> extends ColumnInfoBase<P, PsiCodeFragment> {
protected static class TypeColumn<P extends ParameterInfo, TableItem extends ParameterTableModelItemBase<P>> extends ColumnInfoBase<P, TableItem, PsiCodeFragment> {
protected final Project myProject;
private final FileType myFileType;
@@ -139,25 +138,25 @@ public abstract class ParameterTableModelBase<P extends ParameterInfo> extends L
}
@Override
public PsiCodeFragment valueOf(ParameterTableModelItemBase<P> item) {
public PsiCodeFragment valueOf(TableItem item) {
return item.typeCodeFragment;
}
@Override
public boolean isCellEditable(ParameterTableModelItemBase<P> pParameterTableModelItemBase) {
public boolean isCellEditable(TableItem pParameterTableModelItemBase) {
return true;
}
public TableCellRenderer doCreateRenderer(ParameterTableModelItemBase<P> pParameterTableModelItemBase) {
public TableCellRenderer doCreateRenderer(TableItem pParameterTableModelItemBase) {
return new CodeFragmentTableCellRenderer(myProject, myFileType);
}
public TableCellEditor doCreateEditor(ParameterTableModelItemBase<P> o) {
public TableCellEditor doCreateEditor(TableItem o) {
return new CodeFragmentTableCellEditorBase(myProject, myFileType);
}
}
protected static class NameColumn<P extends ParameterInfo> extends ColumnInfoBase<P, String> {
protected static class NameColumn<P extends ParameterInfo, TableItem extends ParameterTableModelItemBase<P>> extends ColumnInfoBase<P, TableItem, String> {
private final Project myProject;
public NameColumn(Project project) {
@@ -170,21 +169,21 @@ public abstract class ParameterTableModelBase<P extends ParameterInfo> extends L
}
@Override
public String valueOf(ParameterTableModelItemBase<P> item) {
public String valueOf(TableItem item) {
return item.parameter.getName();
}
@Override
public void setValue(ParameterTableModelItemBase<P> item, String value) {
public void setValue(TableItem item, String value) {
item.parameter.setName(value);
}
@Override
public boolean isCellEditable(ParameterTableModelItemBase<P> pParameterTableModelItemBase) {
public boolean isCellEditable(TableItem pParameterTableModelItemBase) {
return true;
}
public TableCellRenderer doCreateRenderer(ParameterTableModelItemBase<P> item) {
public TableCellRenderer doCreateRenderer(TableItem item) {
return new ColoredTableCellRenderer() {
public void customizeCellRenderer(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
@@ -194,12 +193,12 @@ public abstract class ParameterTableModelBase<P extends ParameterInfo> extends L
};
}
public TableCellEditor doCreateEditor(ParameterTableModelItemBase<P> o) {
public TableCellEditor doCreateEditor(TableItem o) {
return new StringTableCellEditor(myProject);
}
}
protected static class DefaultValueColumn<P extends ParameterInfo> extends ColumnInfoBase<P, PsiCodeFragment> {
protected static class DefaultValueColumn<P extends ParameterInfo, TableItem extends ParameterTableModelItemBase<P>> extends ColumnInfoBase<P, TableItem, PsiCodeFragment> {
private final Project myProject;
private final FileType myFileType;
@@ -214,50 +213,50 @@ public abstract class ParameterTableModelBase<P extends ParameterInfo> extends L
}
@Override
public boolean isCellEditable(ParameterTableModelItemBase<P> item) {
public boolean isCellEditable(TableItem item) {
return !item.isEllipsisType() && item.parameter.getOldIndex() == -1;
}
@Override
public PsiCodeFragment valueOf(ParameterTableModelItemBase<P> item) {
public PsiCodeFragment valueOf(TableItem item) {
return item.defaultValueCodeFragment;
}
public TableCellRenderer doCreateRenderer(ParameterTableModelItemBase<P> item) {
public TableCellRenderer doCreateRenderer(TableItem item) {
return new CodeFragmentTableCellRenderer(myProject, myFileType);
}
public TableCellEditor doCreateEditor(ParameterTableModelItemBase<P> item) {
public TableCellEditor doCreateEditor(TableItem item) {
return new CodeFragmentTableCellEditorBase(myProject, myFileType);
}
}
protected static class AnyVarColumn<P extends ParameterInfo> extends ColumnInfoBase<P, Boolean> {
protected static class AnyVarColumn<P extends ParameterInfo, TableItem extends ParameterTableModelItemBase<P>> extends ColumnInfoBase<P, TableItem, Boolean> {
public AnyVarColumn() {
super(RefactoringBundle.message("column.name.any.var"));
}
@Override
public boolean isCellEditable(ParameterTableModelItemBase<P> item) {
public boolean isCellEditable(TableItem item) {
return !item.isEllipsisType() && item.parameter.getOldIndex() == -1;
}
@Override
public Boolean valueOf(ParameterTableModelItemBase<P> item) {
public Boolean valueOf(TableItem item) {
return item.parameter.isUseAnySingleVariable();
}
@Override
public void setValue(ParameterTableModelItemBase<P> item, Boolean value) {
public void setValue(TableItem item, Boolean value) {
item.parameter.setUseAnySingleVariable(value);
}
public TableCellRenderer doCreateRenderer(ParameterTableModelItemBase<P> item) {
public TableCellRenderer doCreateRenderer(TableItem item) {
return new BooleanTableCellRenderer();
}
public TableCellEditor doCreateEditor(ParameterTableModelItemBase<P> item) {
public TableCellEditor doCreateEditor(TableItem item) {
return new BooleanTableCellEditor(false);
}
@@ -36,7 +36,6 @@ import com.intellij.ui.TableUtil;
import com.intellij.ui.table.JBTable;
import com.intellij.usageView.UsageInfo;
import com.intellij.usages.impl.UsagePreviewPanel;
import com.intellij.util.ui.Table;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
@@ -134,9 +133,11 @@ public class AutomaticRenamingDialog extends DialogWrapper {
protected void handleChanges() {
final int selectedRow = myTable.getSelectedRow();
final boolean validName = RenameUtil.isValidName(myProject, myRenames[selectedRow], myNewNames[selectedRow]);
getOKAction().setEnabled(validName);
setErrorText(validName ? null : "Identifier \'" + myNewNames[selectedRow] + "\' is invalid");
if (selectedRow > -1) {
final boolean validName = RenameUtil.isValidName(myProject, myRenames[selectedRow], myNewNames[selectedRow]);
getOKAction().setEnabled(validName);
setErrorText(validName ? null : "Identifier \'" + myNewNames[selectedRow] + "\' is invalid");
}
}
protected JComponent createCenterPanel() {
@@ -696,20 +696,21 @@ public abstract class InplaceRefactoring {
releaseIfNotRestart();
}
});
myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
final Editor topLevelEditor = InjectedLanguageUtil.getTopLevelEditor(myEditor);
topLevelEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
final JBPopupFactory popupFactory = JBPopupFactory.getInstance();
myBalloon.show(new PositionTracker<Balloon>(myEditor.getContentComponent()) {
myBalloon.show(new PositionTracker<Balloon>(topLevelEditor.getContentComponent()) {
@Override
public RelativePoint recalculateLocation(Balloon object) {
if (myTarget != null && !popupFactory.isBestPopupLocationVisible(myEditor)) {
if (myTarget != null && !popupFactory.isBestPopupLocationVisible(topLevelEditor)) {
return myTarget;
}
final RelativePoint target = popupFactory.guessBestPopupLocation(myEditor);
final RelativePoint target = popupFactory.guessBestPopupLocation(topLevelEditor);
if (target == null) return myTarget;
final Point screenPoint = target.getScreenPoint();
int y = screenPoint.y;
if (target.getPoint().getY() > myEditor.getLineHeight() + myBalloon.getPreferredSize().getHeight()) {
y -= myEditor.getLineHeight();
if (target.getPoint().getY() > topLevelEditor.getLineHeight() + myBalloon.getPreferredSize().getHeight()) {
y -= topLevelEditor.getLineHeight();
}
myTarget = new RelativePoint(new Point(screenPoint.x, y));
return myTarget;
@@ -19,11 +19,14 @@ import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.Cell;
import com.intellij.ui.ColorPicker;
import com.intellij.ui.ColorUtil;
import com.intellij.ui.TableSpeedSearch;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.table.JBTable;
import com.intellij.util.PairFunction;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.border.Border;
@@ -31,6 +34,7 @@ import javax.swing.plaf.ColorUIResource;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Enumeration;
@@ -76,7 +80,7 @@ public class ShowUIDefaultsAction extends AnAction {
}) {
@Override
public boolean editCellAt(int row, int column, EventObject e) {
if (isCellEditable(row, column)) {
if (isCellEditable(row, column) && e instanceof MouseEvent) {
final Object color = getValueAt(row, column);
final Color newColor = ColorPicker.showDialog(this, "Choose Color", (Color)color, true, null);
if (newColor != null) {
@@ -107,16 +111,20 @@ public class ShowUIDefaultsAction extends AnAction {
panel.setBackground(c);
return panel;
} else if (value instanceof Icon) {
//final Icon icon = (Icon)value;
//if (icon.getIconHeight() <= 20) {
// //label.setIcon(icon);
//}
//label.setText(String.format("(%dx%d) %s)",icon.getIconWidth(), icon.getIconHeight(), label.getText()));
try {
final Icon icon = (Icon)value;
if (icon.getIconHeight() <= 20) {
label.setIcon(icon);
}
label.setText(String.format("(%dx%d) %s)",icon.getIconWidth(), icon.getIconHeight(), label.getText()));
}
catch (Throwable e1) {//
}
return panel;
} else if (value instanceof Border) {
try {
final Insets i = ((Border)value).getBorderInsets(null);
label.setText(String.format("border[%d, %d, %d, %d] %s", i.top, i.left, i.bottom, i.right, label.getText()));
label.setText(String.format("[%d, %d, %d, %d] %s", i.top, i.left, i.bottom, i.right, label.getText()));
return panel;
} catch (Exception ignore) {}
}
@@ -124,7 +132,13 @@ public class ShowUIDefaultsAction extends AnAction {
}
});
final JBScrollPane pane = new JBScrollPane(table);
new TableSpeedSearch(table);
new TableSpeedSearch(table, new PairFunction<Object, Cell, String>() {
@Nullable
@Override
public String fun(Object o, Cell cell) {
return cell.column == 1 ? null : String.valueOf(o);
}
});
table.setShowGrid(false);
final JPanel panel = new JPanel(new BorderLayout());
panel.add(pane, BorderLayout.CENTER);
@@ -22,8 +22,8 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.EnvironmentUtil;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.execution.ParametersListUtil;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -254,64 +254,27 @@ public class ParametersList implements Cloneable {
}
/**
* <p>Joins list of parameters into single string, which may be then parsed back into list by {@link #parse(String)}.</p>
* <p/>
* <p>
* <strong>Conversion rules:</strong>
* <ul>
* <li>double quotes are escaped by backslash (<code>&#92;</code>);</li>
* <li>empty parameters parameters and parameters with spaces inside are surrounded with double quotes (<code>"</code>);</li>
* <li>parameters are separated by single whitespace.</li>
* </ul>
* </p>
* <p/>
* <p><strong>Examples:</strong></p>
* <p>
* <code>['a', 'b'] => 'a b'</code><br/>
* <code>['a="1 2"', 'b'] => '"a &#92;"1 2&#92;"" b'</code>
* </p>
*
* @param parameters a list of parameters to join.
* @return a string with parameters.
* @see ParametersListUtil#join(java.util.List)
*/
@NotNull
public static String join(@NotNull final List<String> parameters) {
return ParametersTokenizer.encode(parameters);
}
@NotNull
public static String join(final String... parameters) {
return ParametersTokenizer.encode(Arrays.asList(parameters));
return ParametersListUtil.join(parameters);
}
/**
* <p>Converts single parameter string (as created by {@link #join(java.util.List)}) into list of parameters.</p>
* <p/>
* <p>
* <strong>Conversion rules:</strong>
* <ul>
* <li>starting/whitespaces are trimmed;</li>
* <li>parameters are split by whitespaces, whitespaces itself are dropped</li>
* <li>parameters inside double quotes (<code>"a b"</code>) are kept as single one;</li>
* <li>double quotes are dropped, escaped double quotes (<code>&#92;"</code>) are un-escaped.</li>
* </ul>
* </p>
* <p/>
* <p><strong>Examples:</strong></p>
* <p>
* <code>' a b ' => ['a', 'b']</code><br/>
* <code>'a="1 2" b' => ['a=1 2', 'b']</code><br/>
* <code>'a " " b' => ['a', ' ', 'b']</code><br/>
* <code>'"a &#92;"1 2&#92;"" b' => ['a="1 2"', 'b']</code>
* </p>
*
* @param string parameter string to split.
* @return array of parameters.
* @see ParametersListUtil#join(java.util.List)
*/
@NotNull
public static String join(final String... parameters) {
return ParametersListUtil.join(parameters);
}
/**
* @see ParametersListUtil#parseToArray(String)
*/
@NotNull
public static String[] parse(@NotNull final String string) {
final List<String> params = ParametersTokenizer.decode(string);
return ArrayUtil.toStringArray(params);
return ParametersListUtil.parseToArray(string);
}
public String expandMacros(String text) {
@@ -356,84 +319,4 @@ public class ParametersList implements Cloneable {
return myParameters.toString();
}
private static class ParametersTokenizer {
private ParametersTokenizer() {
}
@NotNull
public static String encode(@NotNull final List<String> parameters) {
final StringBuilder buffer = new StringBuilder();
for (final String parameter : parameters) {
if (buffer.length() > 0) {
buffer.append(' ');
}
buffer.append(encode(parameter));
}
return buffer.toString();
}
@NotNull
public static String encode(@NotNull String parameter) {
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append(parameter);
StringUtil.escapeQuotes(builder);
if (builder.length() == 0 || StringUtil.indexOf(builder, ' ') >= 0 || StringUtil.indexOf(builder, '|') >= 0) {
StringUtil.quote(builder);
}
return builder.toString();
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
@NotNull
public static List<String> decode(@NotNull String parameterString) {
parameterString = parameterString.trim();
final ArrayList<String> params = ContainerUtil.newArrayList();
final StringBuilder token = new StringBuilder(128);
boolean inQuotes = false;
boolean escapedQuote = false;
boolean nonEmpty = false;
for (int i = 0; i < parameterString.length(); i++) {
final char ch = parameterString.charAt(i);
if (ch == '\"') {
if (!escapedQuote) {
inQuotes = !inQuotes;
nonEmpty = true;
continue;
}
escapedQuote = false;
}
else if (Character.isWhitespace(ch)) {
if (!inQuotes) {
if (token.length() > 0 || nonEmpty) {
params.add(token.toString());
token.setLength(0);
nonEmpty = false;
}
continue;
}
}
else if (ch == '\\') {
if (i < parameterString.length() - 1 && parameterString.charAt(i + 1) == '"') {
escapedQuote = true;
continue;
}
}
token.append(ch);
}
if (token.length() > 0 || nonEmpty) {
params.add(token.toString());
}
return params;
}
}
}
@@ -17,6 +17,7 @@ package com.intellij.ide.util.treeView;
import com.intellij.ide.projectView.PresentationData;
import com.intellij.openapi.project.Project;
import com.intellij.ui.Gray;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
@@ -167,7 +168,7 @@ public abstract class PresentableNodeDescriptor<E> extends NodeDescriptor<E> {
}
public Color getHighlightColor() {
return UIUtil.isUnderDarcula() ? UIUtil.getPanelBackground().brighter() : UIUtil.getTreeBackground().brighter();
return UIUtil.isUnderDarcula() ? Gray._100 : UIUtil.getTreeBackground().brighter();
}
public static class ColoredFragment {
@@ -16,6 +16,8 @@
package com.intellij.xml.util;
import org.jetbrains.annotations.Nullable;
/**
* @author yole
*/
@@ -23,11 +25,11 @@ public class XmlStringUtil {
private XmlStringUtil() {
}
public static String escapeString(String str) {
public static String escapeString(@Nullable String str) {
return escapeString(str, false);
}
public static String escapeString(String str, final boolean escapeWhiteSpace) {
public static String escapeString(@Nullable String str, final boolean escapeWhiteSpace) {
return XmlTagUtilBase.escapeString(str, escapeWhiteSpace);
}
}
@@ -16,9 +16,10 @@
package com.intellij.xml.util;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
public class XmlTagUtilBase {
public static String escapeString(final String str, final boolean escapeWhiteSpace) {
public static String escapeString(@Nullable final String str, final boolean escapeWhiteSpace) {
if (str == null) return null;
StringBuffer buffer = null;
for (int i = 0; i < str.length(); i++) {
@@ -16,6 +16,9 @@
package com.intellij.ide.dnd;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -94,8 +97,14 @@ public class FileCopyPasteUtil {
public static List<File> getFileList(@NotNull final Transferable transferable) {
try {
if (transferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
@SuppressWarnings({"unchecked"}) final List<File> fileList = (List<File>)transferable.getTransferData(DataFlavor.javaFileListFlavor);
return fileList;
@SuppressWarnings({"unchecked"})
final List<File> fileList = (List<File>)transferable.getTransferData(DataFlavor.javaFileListFlavor);
return ContainerUtil.filter(fileList, new Condition<File>() {
@Override
public boolean value(File file) {
return !StringUtil.isEmptyOrSpaces(file.getPath());
}
});
}
else {
return LinuxDragAndDropSupport.getFiles(transferable);
@@ -105,4 +114,5 @@ public class FileCopyPasteUtil {
return null;
}
}
@@ -21,7 +21,8 @@ import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.ColorUtil;
import org.jetbrains.annotations.Nullable;
import com.intellij.util.containers.hash.HashMap;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.plaf.ColorUIResource;
@@ -104,8 +105,7 @@ public final class DarculaLaf extends BasicLookAndFeel {
@SuppressWarnings({"HardCodedStringLiteral"})
static void initIdeaDefaults(UIDefaults defaults) {
loadDefaults(defaults, null); //load defaults
loadDefaults(defaults, SystemInfo.isMac ? "mac" : SystemInfo.isWindows ? "windows" : "linux"); // load OS customization
loadDefaults(defaults);
defaults.put("Table.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] {
"ctrl C", "copy",
"ctrl V", "paste",
@@ -158,44 +158,70 @@ public final class DarculaLaf extends BasicLookAndFeel {
}));
}
private static void loadDefaults(UIDefaults defaults, @Nullable String postfix) {
private static void loadDefaults(UIDefaults defaults) {
final Properties properties = new Properties();
final String osSuffix = SystemInfo.isMac ? "mac" : SystemInfo.isWindows ? "windows" : "linux";
try {
final Properties properties = new Properties();
final String secondPart = postfix == null ? "" : "_" + postfix;
final String name = "darcula" + secondPart + ".properties";
final InputStream stream = DarculaLaf.class.getResourceAsStream(name);
InputStream stream = DarculaLaf.class.getResourceAsStream("darcula.properties");
properties.load(stream);
stream.close();
stream = DarculaLaf.class.getResourceAsStream("darcula_" + osSuffix + ".properties");
properties.load(stream);
stream.close();
HashMap<String, Object> darculaGlobalSettings = new HashMap<String, Object>();
final String prefix = "darcula.";
for (String key : properties.stringPropertyNames()) {
final String value = properties.getProperty(key);
if (key.endsWith("Insets")) {
final List<String> numbers = StringUtil.split(value, ",");
defaults.put(key, new InsetsUIResource(Integer.parseInt(numbers.get(0)),
Integer.parseInt(numbers.get(1)),
Integer.parseInt(numbers.get(2)),
Integer.parseInt(numbers.get(3))));
} else if (key.endsWith(".border")) {
try {
defaults.put(key, Class.forName(value).newInstance());
} catch (Exception e) {log(e);}
} else {
final Color color = ColorUtil.fromHex(value, null);
final Integer invVal = getInteger(value);
Icon icon = value != null && value.startsWith("AllIcons.") ? IconLoader.getIcon(value) : null;
if (color != null) {
defaults.put(key, new ColorUIResource(color));
} else if (invVal != null) {
defaults.put(key, invVal);
} else if (icon != null) {
defaults.put(key, new IconUIResource(icon));
} else {
defaults.put(key, value);
if (key.startsWith(prefix)) {
darculaGlobalSettings.put(key.substring(prefix.length()), parseValue(key, properties.getProperty(key)));
}
}
for (Object key : defaults.keySet()) {
if (key instanceof String && ((String)key).contains(".")) {
final String s = (String)key;
final String darculaKey = s.substring(s.lastIndexOf('.') + 1);
if (darculaGlobalSettings.containsKey(darculaKey)) {
defaults.put(key, darculaGlobalSettings.get(darculaKey));
}
}
}
for (String key : properties.stringPropertyNames()) {
final String value = properties.getProperty(key);
defaults.put(key, parseValue(key, value));
}
}
catch (IOException e) {log(e);}
}
private static Object parseValue(String key, @NotNull String value) {
if (key.endsWith("Insets")) {
final List<String> numbers = StringUtil.split(value, ",");
return new InsetsUIResource(Integer.parseInt(numbers.get(0)),
Integer.parseInt(numbers.get(1)),
Integer.parseInt(numbers.get(2)),
Integer.parseInt(numbers.get(3)));
} else if (key.endsWith(".border")) {
try {
return Class.forName(value).newInstance();
} catch (Exception e) {log(e);}
} else {
final Color color = ColorUtil.fromHex(value, null);
final Integer invVal = getInteger(value);
Icon icon = value.startsWith("AllIcons.") ? IconLoader.getIcon(value) : null;
if (color != null) {
return new ColorUIResource(color);
} else if (invVal != null) {
return invVal;
} else if (icon != null) {
return new IconUIResource(icon);
}
}
return value;
}
private static Integer getInteger(String value) {
try {
return Integer.parseInt(value);
@@ -1,84 +1,50 @@
darcula.background=535353
darcula.textBackground=535353
darcula.foreground=eeeeee
darcula.textForeground=eeeeee
darcula.caretForeground=eeeeee
text=eeeeee
Menu.maxGutterIconWidth=18
MenuItem.maxGutterIconWidth=18
MenuItem.acceleratorDelimiter=-
#Trees
Tree.background=535353
Tree.foreground=eeeeee
Tree.textForeground=eeeeee
Tree.textBackground=535353
#Tree.selectionBackground=BEBEBE
#Tree.selectionForeground=535353
EditorPane.background=535353
EditorPane.inactiveBackground=535353
EditorPane.foreground=eeeeee
EditorPane.inactiveForeground=eeeeee
EditorPaneUI=com.intellij.ide.ui.laf.darcula.ui.DarculaEditorPaneUI
#Lists
List.background=535353
List.foreground=eeeeee
#Tables
Table.background=535353
Table.foreground=eeeeee
control=535353
Panel.background=535353
Panel.foreground=eeeeee
ScrollBarUI=com.intellij.ide.ui.laf.darcula.ui.DarculaScrollBarUI
Menu.selectionBackground=bebebe
MenuBar.background=535353
MenuBar.disabledBackground=535353
MenuBar.shadow=535353
Menu.background=535353
MenuItem.background=535353
Menu.foreground=eeeeee
MenuItem.foreground=eeeeee
TabbedPane.tabInsets=0,4,0,4
ToggleButton.foreground=eeeeee
Separator.background=535353
Separator.foreground=888888
Label.background=535353
Label.foreground=eeeeee
Focus.color=ff0000
TextField.background=535353
TextField.foreground=eeeeee
TextField.caretForeground=eeeeee
#TextFieldUI=com.intellij.ide.ui.laf.darcula.ui.DarculaTextFieldUI
TextField.background=737373
TextFieldUI=com.intellij.ide.ui.laf.darcula.ui.DarculaTextFieldUI
TextField.border=com.intellij.ide.ui.laf.darcula.ui.DarculaTextBorder
PasswordField.background=535353
PasswordField.foreground=eeeeee
PasswordField.caretForeground=eeeeee
PasswordField.background=aaaaaa
TextArea.background=535353
TextArea.foreground=eeeeee
TextArea.caretForeground=eeeeee
TextPane.background=535353
TextPane.foreground=eeeeee
TextPane.caretForeground=eeeeee
CheckBox.background=535353
CheckBox.foreground=eeeeee
CheckBoxUI=com.intellij.ide.ui.laf.darcula.ui.DarculaCheckBoxUI
RadioButton.foreground=eeeeee
RadioButton.background=535353
#ComboBoxUI=com.intellij.ide.ui.laf.darcula.ui.DarculaComboBoxUI
ComboBox.background=eeeeee
ComboBox.foreground=000000
RadioButtonUI=com.intellij.ide.ui.laf.darcula.ui.DarculaRadioButtonUI
StatusBar.topColor=2c2c2c
StatusBar.top2Color=2c2c2c
StatusBar.bottomColor=2c2c2c
Button.foreground=eeeeee
Button.background=535353
Button.border=com.intellij.ide.ui.laf.darcula.ui.DarculaButtonPainter
#ButtonUI=com.intellij.ide.ui.laf.borders.DarculaButtonUI
MenuItem.acceleratorForeground=eeeeee
PopupMenu.background=535353
PopupMenu.translucentBackground=535353
@@ -63,6 +63,6 @@ public class DarculaButtonPainter implements Border, UIResource {
@Override
public boolean isBorderOpaque() {
return false;
return true;
}
}
@@ -0,0 +1,56 @@
/*
* Copyright 2000-2012 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.ide.ui.laf.darcula.ui;
import com.intellij.icons.AllIcons;
import javax.swing.*;
import javax.swing.plaf.basic.BasicButtonUI;
import java.awt.*;
/**
* @author Konstantin Bulenkov
*/
public class DarculaComboBoxButton extends JButton {
private final JComboBox myComboBox;
public DarculaComboBoxButton(JComboBox comboBox) {
myComboBox = comboBox;
setUI(new BasicButtonUI() {
@Override
public void paint(Graphics g, JComponent c) {
final Icon i;
if (myComboBox.isEditable()) {
g.drawLine(0,0,0,c.getHeight());
i = AllIcons.Mac.Tree_white_down_arrow;
} else {
i = AllIcons.Ide.Statusbar_arrows;
}
i.paintIcon(c, g, (c.getWidth() - i.getIconWidth()) / 2, (c.getHeight() - i.getIconHeight()) / 2);
}
@Override
public Dimension getPreferredSize(JComponent c) {
return super.getPreferredSize(c);
}
});
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
}
}
@@ -0,0 +1,88 @@
/*
* Copyright 2000-2012 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.ide.ui.laf.darcula.ui;
import javax.swing.*;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicComboBoxUI;
import java.awt.*;
/**
* @author Konstantin Bulenkov
*/
public class DarculaComboBoxUI extends BasicComboBoxUI {
private final JComboBox myComboBox;
public DarculaComboBoxUI(JComboBox c) {
myComboBox = c;
c.setBorder(null);
}
@SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"})
public static ComponentUI createUI(JComponent c) {
return new DarculaComboBoxUI(((JComboBox)c));
}
@Override
protected LayoutManager createLayoutManager() {
return new DarculaComboBoxLayoutManager();
}
@Override
public void paintCurrentValueBackground(Graphics g, Rectangle bounds, boolean hasFocus) {
super.paintCurrentValueBackground(g, bounds, false);
}
@Override
public void paint(Graphics g, JComponent c) {
super.paint(g, c);
}
@Override
protected JButton createArrowButton() {
return new DarculaComboBoxButton(myComboBox);
}
class DarculaComboBoxLayoutManager extends BasicComboBoxUI.ComboBoxLayoutManager {
public void layoutContainer(final Container parent) {
if (arrowButton != null && !comboBox.isEditable()) {
final Insets insets = comboBox.getInsets();
final int width = comboBox.getWidth();
final int height = comboBox.getHeight();
arrowButton.setBounds(insets.left, insets.top, width - (insets.left + insets.right), height - (insets.top + insets.bottom));
return;
}
final JComboBox cb = (JComboBox)parent;
final int width = cb.getWidth();
final int height = cb.getHeight();
final Insets insets = getInsets();
final int buttonHeight = height - (insets.top + insets.bottom);
final int buttonWidth = 20;
if (arrowButton != null) {
arrowButton.setBounds(width - (insets.right + buttonWidth), insets.top, buttonWidth, buttonHeight);
}
if (editor != null) {
final Rectangle editorRect = rectangleForCurrentValue();
editorRect.width += 4;
editor.setBounds(editorRect);
}
}
}
}
@@ -0,0 +1,32 @@
/*
* Copyright 2000-2012 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.ide.ui.laf.darcula.ui;
import com.intellij.util.ui.ButtonlessScrollBarUI;
import javax.swing.*;
import javax.swing.plaf.ComponentUI;
/**
* @author Konstantin Bulenkov
*/
public class DarculaScrollBarUI extends ButtonlessScrollBarUI {
@SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"})
public static ComponentUI createUI(JComponent c) {
return new DarculaScrollBarUI();
}
}
@@ -0,0 +1,417 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.ide.ui.laf.darcula.ui.DarculaTest">
<grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="740" height="400"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<tabbedpane id="7fdea" class="com.intellij.ui.components.JBTabbedPane">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<grid id="82dae" layout-manager="GridLayoutManager" row-count="7" column-count="7" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<tabbedpane title="Controls"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="18633" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Checkbox 1"/>
</properties>
</component>
<component id="9cf6e" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Checkbox 2"/>
</properties>
</component>
<component id="ccfb9" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Checkbox 3"/>
</properties>
</component>
<component id="cd11b" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Checkbox 4"/>
</properties>
</component>
<component id="210e8" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<enabled value="false"/>
<text value="Checkbox 5"/>
</properties>
</component>
<hspacer id="72565">
<constraints>
<grid row="0" column="6" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<vspacer id="4309a">
<constraints>
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="987f8" class="com.intellij.ui.components.JBCheckBox" binding="myJBCheckBox1" default-binding="true">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<component id="57e78" class="com.intellij.ui.components.JBCheckBox" binding="myJBCheckBox2" default-binding="true">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<selected value="true"/>
</properties>
</component>
<component id="3fd84" class="com.intellij.ui.components.JBCheckBox" binding="myJBCheckBox3" default-binding="true">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<selected value="true"/>
</properties>
</component>
<component id="4c4e6" class="com.intellij.ui.components.JBCheckBox" binding="myJBCheckBox4" default-binding="true">
<constraints>
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<selected value="true"/>
</properties>
</component>
<component id="4faf4" class="com.intellij.ui.components.JBCheckBox" binding="myJBCheckBox5" default-binding="true">
<constraints>
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<enabled value="false"/>
</properties>
</component>
<component id="389e3" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Radio button 1"/>
</properties>
</component>
<component id="2c501" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Radio button 2"/>
</properties>
</component>
<component id="74a2d" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="2" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Radio button 3"/>
</properties>
</component>
<component id="8b6b8" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="3" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Radio button 4"/>
</properties>
</component>
<component id="fbe33" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="4" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<enabled value="false"/>
<text value="Radio button 5"/>
</properties>
</component>
<component id="1935f" class="com.intellij.ui.components.JBRadioButton">
<constraints>
<grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<component id="3443a" class="com.intellij.ui.components.JBRadioButton">
<constraints>
<grid row="1" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<component id="46c61" class="com.intellij.ui.components.JBRadioButton">
<constraints>
<grid row="2" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<component id="b4c96" class="com.intellij.ui.components.JBRadioButton">
<constraints>
<grid row="3" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<component id="3f56f" class="com.intellij.ui.components.JBRadioButton">
<constraints>
<grid row="4" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<component id="cee3a" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Combo 1"/>
</properties>
</component>
<component id="21050" class="javax.swing.JLabel">
<constraints>
<grid row="1" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Combo 2"/>
</properties>
</component>
<component id="402e8" class="javax.swing.JLabel">
<constraints>
<grid row="2" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Combo 3"/>
</properties>
</component>
<component id="9de33" class="javax.swing.JLabel">
<constraints>
<grid row="3" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<enabled value="false"/>
<text value="Combo 4"/>
</properties>
</component>
<component id="786c1" class="javax.swing.JLabel">
<constraints>
<grid row="4" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<enabled value="false"/>
<text value="Combo 5"/>
</properties>
</component>
<component id="cf830" class="javax.swing.JComboBox" binding="myComboBox1" default-binding="true">
<constraints>
<grid row="0" column="5" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<model>
<item value="item 1"/>
<item value="item 2"/>
<item value="long item"/>
<item value="very long item"/>
<item value="blah blah blah blah"/>
<item value="hello"/>
<item value="darcula"/>
</model>
</properties>
</component>
<component id="70b41" class="javax.swing.JComboBox" binding="myComboBox2" default-binding="true">
<constraints>
<grid row="1" column="5" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<model>
<item value="item 1"/>
<item value="item 2"/>
<item value="long item"/>
<item value="very long item"/>
<item value="blah blah blah blah"/>
<item value="hello"/>
<item value="darcula"/>
</model>
</properties>
</component>
<component id="fd136" class="javax.swing.JComboBox" binding="myComboBox3" default-binding="true">
<constraints>
<grid row="2" column="5" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<editable value="true"/>
<model>
<item value="item 1"/>
<item value="item 2"/>
<item value="long item"/>
<item value="very long item"/>
<item value="blah blah blah blah"/>
<item value="hello"/>
<item value="darcula"/>
</model>
</properties>
</component>
<component id="f8aa2" class="javax.swing.JComboBox" binding="myComboBox4" default-binding="true">
<constraints>
<grid row="3" column="5" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<editable value="true"/>
<enabled value="false"/>
<model>
<item value="item 1"/>
<item value="item 2"/>
<item value="long item"/>
<item value="very long item"/>
<item value="blah blah blah blah"/>
<item value="hello"/>
<item value="darcula"/>
</model>
</properties>
</component>
<component id="15345" class="javax.swing.JComboBox" binding="myComboBox5" default-binding="true">
<constraints>
<grid row="4" column="5" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<enabled value="false"/>
<model>
<item value="item 1"/>
<item value="item 2"/>
<item value="long item"/>
<item value="very long item"/>
<item value="blah blah blah blah"/>
<item value="hello"/>
<item value="darcula"/>
</model>
</properties>
</component>
<grid id="89ff7" layout-manager="GridLayoutManager" row-count="3" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="5" column="0" row-span="1" col-span="7" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="9f0fc" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Username:"/>
</properties>
</component>
<component id="4ae36" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Password:"/>
</properties>
</component>
<component id="da910" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<enabled value="false"/>
<text value="Disabled:"/>
</properties>
</component>
<hspacer id="fb796">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<component id="4fa3a" class="javax.swing.JTextField" binding="myTextField1" default-binding="true">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
<component id="55f5c" class="javax.swing.JTextField" binding="myThisTextIsDisabledTextField" default-binding="true">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties>
<enabled value="false"/>
<text value="This text is disabled"/>
</properties>
</component>
<component id="a89cc" class="javax.swing.JPasswordField" binding="myPasswordField1" default-binding="true">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
</children>
</grid>
</children>
</grid>
<grid id="df06" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<tabbedpane title="Table"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<scrollpane id="3105c" class="com.intellij.ui.components.JBScrollPane">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="d2ccf" class="com.intellij.ui.table.JBTable">
<constraints/>
<properties/>
</component>
</children>
</scrollpane>
</children>
</grid>
</children>
</tabbedpane>
</children>
</grid>
<buttonGroups>
<group name="myGroup1">
<member id="1935f"/>
<member id="3443a"/>
<member id="46c61"/>
<member id="b4c96"/>
<member id="3f56f"/>
</group>
</buttonGroups>
</form>
@@ -0,0 +1,58 @@
/*
* Copyright 2000-2012 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.ide.ui.laf.darcula.ui;
import com.intellij.ide.ui.laf.darcula.DarculaLaf;
import com.intellij.ui.components.JBCheckBox;
import javax.swing.*;
/**
* @author Konstantin Bulenkov
*/
public class DarculaTest {
private JBCheckBox myJBCheckBox1;
private JBCheckBox myJBCheckBox2;
private JBCheckBox myJBCheckBox3;
private JBCheckBox myJBCheckBox4;
private JBCheckBox myJBCheckBox5;
private JComboBox myComboBox1;
private JComboBox myComboBox2;
private JComboBox myComboBox3;
private JComboBox myComboBox4;
private JComboBox myComboBox5;
private JTextField myTextField1;
private JTextField myThisTextIsDisabledTextField;
private JPasswordField myPasswordField1;
private JPanel myRoot;
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(new DarculaLaf());
}
catch (UnsupportedLookAndFeelException ignored) {}
final JFrame frame = new JFrame("Darcula Demo");
frame.setSize(600, 500);
frame.setContentPane(new DarculaTest().myRoot);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
frame.setVisible(true);
}
});
}
}
@@ -0,0 +1,82 @@
/*
* Copyright 2000-2012 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.ide.ui.laf.darcula.ui;
import com.intellij.ide.ui.laf.darcula.DarculaUIUtil;
import com.intellij.openapi.ui.GraphicsConfig;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.ui.ColorUtil;
import com.intellij.util.ui.JBInsets;
import javax.swing.border.Border;
import javax.swing.plaf.UIResource;
import java.awt.*;
/**
* @author Konstantin Bulenkov
*/
public class DarculaTextBorder implements Border, UIResource {
private JBInsets myInsets = new JBInsets(4, 7, 4, 7);
@Override
public JBInsets getBorderInsets(Component c) {
return myInsets;
}
@Override
public boolean isBorderOpaque() {
return false;
}
@Override
public void paintBorder(Component c, Graphics g2, int x, int y, int width, int height) {
Graphics2D g = ((Graphics2D)g2);
g.setColor(ColorUtil.fromHex("737373"));
int cX = myInsets.right;
int cY = myInsets.top;
int cW = width - myInsets.width();
int cH = height - myInsets.height();
final GraphicsConfig config = new GraphicsConfig(g);
g.translate(x, y);
if (c.hasFocus()) {
int sysOffX = SystemInfo.isMac ? 0 : 1;
int sysOffY = SystemInfo.isMac ? 0 : -1;
DarculaUIUtil.paintFocusRing(g, 2, 2, width-4, height-4);
//g.setColor(DarculaUIUtil.GLOW_COLOR.darker().darker());
//g.drawRect(1, 1, width - 2, height - 2);
//g.drawRect(2, 2, width-4, height-4);
//g.setColor(ColorUtil.toAlpha(DarculaUIUtil.GLOW_COLOR, 70));
//g.drawRoundRect(0, 0, width, height, 5, 5);
//g.setColor(ColorUtil.toAlpha(DarculaUIUtil.GLOW_COLOR, 80));
//g.drawRoundRect(1, 1, width - 2, height-2, 5, 5);
//g.setColor(ColorUtil.toAlpha(DarculaUIUtil.GLOW_COLOR, 120));
//g.drawRoundRect(2, 2, width - 4, height - 4, 5, 5);
//g.setColor(ColorUtil.toAlpha(DarculaUIUtil.GLOW_COLOR, 140));
//g.drawRoundRect(3, 2, width - 6, height - 4, 5, 5);
} else {
//g.fillRect(2, 1, cX-2, height - 2); //left
//g.fillRect(cX + cW , 1, width-cW - cX, height - 2); //right
//g.fillRect(1, 1, width - 2, cY); //top
//g.fillRect(1, cY + cH, width - 2, height - 2); //bottom
g.setColor(ColorUtil.fromHex("939393"));
g.drawRect(1, 1, width - 2, height - 2);
}
g.translate(-x, -y);
config.restore();
}
}
@@ -15,9 +15,17 @@
*/
package com.intellij.ide.ui.laf.darcula.ui;
import com.intellij.openapi.ui.GraphicsConfig;
import com.intellij.util.ui.JBInsets;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicTextFieldUI;
import javax.swing.text.JTextComponent;
import java.awt.*;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
/**
* @author Konstantin Bulenkov
@@ -25,7 +33,57 @@ import javax.swing.plaf.basic.BasicTextFieldUI;
public class DarculaTextFieldUI extends BasicTextFieldUI {
@SuppressWarnings("MethodOverridesStaticMethodOfSuperclass")
public static ComponentUI createUI(JComponent c) {
public static ComponentUI createUI(final JComponent c) {
c.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
c.repaint();
}
@Override
public void focusLost(FocusEvent e) {
c.repaint();
}
});
return new DarculaTextFieldUI();
}
@Override
protected void installDefaults() {
super.installDefaults();
}
@Override
protected void paintSafely(Graphics g) {
super.paintSafely(g);
}
@Override
protected void paintBackground(Graphics g) {
final JTextComponent c = getComponent();
final Container parent = c.getParent();
if (parent != null) {
g.setColor(parent.getBackground());
g.fillRect(0,0,c.getWidth(), c.getHeight());
}
final Border border = c.getBorder();
if (border instanceof DarculaTextBorder) {
g.setColor(c.getBackground());
final int width = c.getWidth();
final int height = c.getHeight();
final JBInsets insets = ((DarculaTextBorder)border).getBorderInsets(c);
if (c.hasFocus()) {
final GraphicsConfig config = new GraphicsConfig(g);
((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
((Graphics2D)g).setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);
g.fillRoundRect(insets.left-5, insets.top-2, width - insets.width() + 10, height - insets.height() + 6, 5, 5);
config.restore();
} else {
g.fillRect(insets.left-5, insets.top-2, width - insets.width() + 12, height - insets.height() + 6);
}
} else {
super.paintBackground(g);
}
}
}
@@ -0,0 +1,273 @@
/*
* Copyright 2000-2012 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.internal.anomalies;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.objectTree.ObjectNode;
import com.intellij.openapi.util.objectTree.ObjectTree;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
/**
* User: Vassiliy.Kudryashov
*/
public class TopAnomaliesAction extends ActionGroup {
private static final Comparator<Pair<?, Integer>> COMPARATOR = new Comparator<Pair<?, Integer>>() {
@Override
public int compare(Pair<?, Integer> o1, Pair<?, Integer> o2) {
int i = o2.getSecond() - o1.getSecond();
if (i != 0) {
return i;
}
int h1 = o1.hashCode();
int h2 = o2.hashCode();
if (h1 > h2) {
return 1;
}
if (h1 < h2) {
return -1;
}
return 0;
}
};
private static final int LIMIT = 10;
private static final ResettableAction TOP_PARENTS = new ResettableAction("Parents") {
TreeSet<Pair<JComponent, Integer>> top = new TreeSet<Pair<JComponent, Integer>>(COMPARATOR);
TreeSet<Pair<JComponent, Integer>> old = new TreeSet<Pair<JComponent, Integer>>(COMPARATOR);
@Override
public void update(AnActionEvent e) {
e.getPresentation().setText("Top " + LIMIT + " component parents");
}
@Override
void reset() {
top.clear();
old.clear();
}
@Override
public void actionPerformed(AnActionEvent e) {
old = new TreeSet<Pair<JComponent, Integer>>(top);
top.clear();
Window[] windows = Window.getWindows();
for (Window window : windows) {
if (window.isVisible() && (window instanceof JFrame)) {
JFrame f = (JFrame)window;
checkParents((JComponent)f.getContentPane(), top, LIMIT);
}
}
System.out.println("Top " + LIMIT + " component parents");
for (Pair<JComponent, Integer> pair : top) {
System.out.println(
pair.first.getClass().getName() + " (" + pair.second + " children)" + getChange(old, pair.first, pair.second));
}
}
private void checkParents(JComponent component, Set<Pair<JComponent, Integer>> top, int limit) {
top.add(Pair.create(component, component.getComponentCount()));
trimToLimit(top, limit);
for (int i = 0; i < component.getComponentCount(); i++) {
Component child = component.getComponent(i);
if (child instanceof JComponent) {
checkParents((JComponent)child, top, limit);
}
}
}
};
private static final ResettableAction TOP_UI_PROPERTIES = new ResettableAction("ClientProperties") {
TreeSet<Pair<JComponent, Integer>> top = new TreeSet<Pair<JComponent, Integer>>(COMPARATOR);
TreeSet<Pair<JComponent, Integer>> old = new TreeSet<Pair<JComponent, Integer>>(COMPARATOR);
@Override
public void update(AnActionEvent e) {
e.getPresentation().setText("Top " + LIMIT + " ClientProperties");
}
@Override
void reset() {
top.clear();
old.clear();
}
@Override
public void actionPerformed(AnActionEvent e) {
old = new TreeSet<Pair<JComponent, Integer>>(top);
top.clear();
Window[] windows = Window.getWindows();
for (Window window : windows) {
if (window.isVisible() && (window instanceof JFrame)) {
JFrame f = (JFrame)window;
checkClientProperties((JComponent)f.getContentPane(), top, LIMIT);
}
}
System.out.println("Top " + LIMIT + " ClientProperties");
for (Pair<JComponent, Integer> pair : top) {
System.out.println(pair.first.getClass().getName() + " (" + pair.second + " properties)" + getChange(old, pair.first, pair.second));
}
}
private void checkClientProperties(JComponent component, Set<Pair<JComponent, Integer>> top, int limit) {
try {
Field clientProperties = JComponent.class.getDeclaredField("clientProperties");
clientProperties.setAccessible(true);
Object o = clientProperties.get(component);
if (o != null) {
Method size = o.getClass().getMethod("size");
size.setAccessible(true);
Object sizeResult = size.invoke(o);
if (sizeResult instanceof Integer) {
top.add(Pair.create(component, (Integer)sizeResult));
trimToLimit(top, limit);
}
}
}
catch (NoSuchMethodException e) {
}
catch (InvocationTargetException e) {
}
catch (IllegalAccessException e) {
}
catch (NoSuchFieldException e) {
}
for (int i = 0; i < component.getComponentCount(); i++) {
Component child = component.getComponent(i);
if (child instanceof JComponent) {
checkClientProperties((JComponent)child, top, limit);
}
}
}
};
private static final ResettableAction TOP_DISPOSABLE = new ResettableAction("Disposable") {
TreeSet<Pair<Object, Integer>> top = new TreeSet<Pair<Object, Integer>>(COMPARATOR);
TreeSet<Pair<Object, Integer>> old = new TreeSet<Pair<Object, Integer>>(COMPARATOR);
@Override
public void update(AnActionEvent e) {
e.getPresentation().setText("Top " + LIMIT + " disposables");
}
@Override
void reset() {
top.clear();
old.clear();
}
@Override
public void actionPerformed(AnActionEvent e) {
old = new TreeSet<Pair<Object, Integer>>(top);
top.clear();
ObjectTree<Disposable> tree = Disposer.getTree();
Set<Disposable> roots = tree.getRootObjects();
for (Disposable root : roots) {
checkDisposables(tree, root, top, LIMIT);
}
System.out.println("Top " + LIMIT + " disposables");
for (Pair<Object, Integer> pair : top) {
System.out.println(pair.first.getClass().getName() + " (" + pair.second + " related)" + getChange(old, pair.first, pair.second));
}
}
private void checkDisposables(ObjectTree tree, Object key, Set<Pair<Object, Integer>> top, int limit) {
ObjectNode node = tree.getNode(key);
if (node == null) {
return;
}
Collection children = node.getChildren();
top.add(Pair.create(key, children.size()));
trimToLimit(top, limit);
for (Object child : children) {
checkDisposables(tree, child, top, limit);
}
}
};
private static final ResettableAction RESET_THEM_ALL = new ResettableAction("Reset statistics") {
@Override
void reset() {
}
@Override
public void actionPerformed(AnActionEvent e) {
for (ResettableAction action : CHILDREN) {
action.reset();
}
}
};
private static ResettableAction[] CHILDREN = {TOP_PARENTS, TOP_UI_PROPERTIES, TOP_DISPOSABLE, RESET_THEM_ALL};
@Override
public void update(AnActionEvent e) {
e.getPresentation().setText("Top " + LIMIT);
}
@NotNull
@Override
public AnAction[] getChildren(@Nullable AnActionEvent e) {
return CHILDREN;
}
private static <K, V> void trimToLimit(Set<Pair<K, V>> top, int limit) {
int k = 0;
for (Iterator<Pair<K, V>> iterator = top.iterator(); iterator.hasNext(); ) {
k++;
iterator.next();
if (k >= limit) {
iterator.remove();
}
}
}
private static <K, V extends Integer> String getChange(Set<Pair<K, V>> old, K key, int newResult) {
for (Pair<K, V> oldPair : old) {
if (oldPair.first == key) {
int oldResult = oldPair.second.intValue();
if (oldResult != newResult) {
return (oldResult > newResult ? " -" : " +") + Math.abs(newResult - oldResult);
}
break;
}
}
return "";
}
private static abstract class ResettableAction extends AnAction {
protected ResettableAction(@Nullable String text) {
super(text);
}
abstract void reset();
}
}
@@ -179,14 +179,30 @@ public class DumbServiceImpl extends DumbService {
if (!wasDumb) {
// always change dumb status inside write action.
// This will ensure all active read actions are completed before the app goes dumb
final Ref<Boolean> startFailure = new Ref<Boolean>(Boolean.FALSE);
application.runWriteAction(new Runnable() {
public void run() {
myDumb = true;
myPublisher.enteredDumbMode();
updateRunnable.run();
try {
myPublisher.enteredDumbMode();
}
catch (Throwable e) {
LOG.error(e);
}
finally {
try {
updateRunnable.run();
}
catch (Throwable e) {
startFailure.set(Boolean.TRUE);
LOG.error("Failed to start background index update task", e);
}
}
}
});
if (startFailure.get()) {
updateFinished();
}
}
else {
myUpdatesQueue.addLast(updateRunnable);
@@ -197,23 +213,27 @@ public class DumbServiceImpl extends DumbService {
private void updateFinished() {
myDumb = false;
if (!myProject.isDisposed()) {
myPublisher.exitDumbMode();
FileEditorManagerEx.getInstanceEx(myProject).refreshIcons();
try {
if (!myProject.isDisposed()) {
myPublisher.exitDumbMode();
FileEditorManagerEx.getInstanceEx(myProject).refreshIcons();
}
}
while (true) {
final Runnable runnable;
synchronized (myRunWhenSmartQueue) {
if (myRunWhenSmartQueue.isEmpty()) {
break;
finally {
while (true) {
final Runnable runnable;
synchronized (myRunWhenSmartQueue) {
if (myRunWhenSmartQueue.isEmpty()) {
break;
}
runnable = myRunWhenSmartQueue.pullFirst();
}
try {
runnable.run();
}
catch (Throwable e) {
LOG.error(e);
}
runnable = myRunWhenSmartQueue.pullFirst();
}
try {
runnable.run();
}
catch (Throwable e) {
LOG.error(e);
}
}
}
@@ -278,10 +298,6 @@ public class DumbServiceImpl extends DumbService {
}
public void run() {
if (myProject.isDisposed()) {
return;
}
ProgressManager.getInstance().run(new Task.Backgroundable(myProject, IdeBundle.message("progress.indexing"), false) {
private final BlockingQueue<Ref<CacheUpdateRunner>> myActionQueue = new LinkedBlockingQueue<Ref<CacheUpdateRunner>>();
@@ -358,7 +374,7 @@ public class DumbServiceImpl extends DumbService {
finally {
myProcessedItems += count;
if (LOG.isDebugEnabled()) {
LOG.debug("Scheduling checkNextUpdateFromQueue");
LOG.debug("Scheduling checkNextUpdateFromQueue; Thread: " + Thread.currentThread().getName());
}
UIUtil.invokeLaterIfNeeded(new DumbAwareRunnable() {
public void run() {
@@ -389,7 +405,7 @@ public class DumbServiceImpl extends DumbService {
private void checkNextUpdateFromQueue() {
if (LOG.isDebugEnabled()) {
LOG.debug("Inside checkNextUpdateFromQueue");
LOG.debug("Inside checkNextUpdateFromQueue, Thread: " + Thread.currentThread().getName());
}
IndexUpdateRunnable nextUpdateRunnable = null;
try {
@@ -261,7 +261,13 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
return message;
}
private static void initProject(ProjectImpl project, @Nullable ProjectImpl template) throws IOException {
private void initProject(@NotNull ProjectImpl project, @Nullable ProjectImpl template) throws IOException {
final ProgressIndicator indicator = myProgressManager.getProgressIndicator();
if (indicator != null) {
indicator.setText(ProjectBundle.message("loading.components.for", project.isDefault() ? "Default" : project.getName()));
indicator.setIndeterminate(true);
}
ApplicationManager.getApplication().getMessageBus().syncPublisher(ProjectLifecycleListener.TOPIC).beforeProjectLoaded(project);
@@ -311,7 +317,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
public Project loadProject(String filePath) throws IOException, JDOMException, InvalidDataException {
try {
ProjectImpl project = createProject(null, filePath, false, false);
doLoadProject(filePath, project);
initProject(project, null);
return project;
}
catch (StateStorageException e) {
@@ -319,16 +325,6 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
}
}
private void doLoadProject(String filePath, ProjectImpl project) throws IOException, StateStorageException {
filePath = toCanonicalName(filePath);
final ProgressIndicator indicator = myProgressManager.getProgressIndicator();
if (indicator != null) {
indicator.setText(ProjectBundle.message("loading.components.for", FileUtil.toSystemDependentName(filePath)));
indicator.setIndeterminate(true);
}
initProject(project, null);
}
@NotNull
private static String toCanonicalName(@NotNull final String filePath) {
try {
@@ -540,7 +536,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
@Override
@Nullable
public Project compute() throws IOException {
doLoadProject(filePath, project);
initProject(project, null);
return project;
}
}, ProjectBundle.message("project.load.progress"), true, project);
@@ -547,6 +547,7 @@
</action>
<action id="UiInspector" internal="true" class="com.intellij.internal.inspector.UiInspectorAction" text="UI Inspector"/>
<group id="TopAnomalies" internal="true" class="com.intellij.internal.anomalies.TopAnomaliesAction" text="Top Anomalies" popup="true"/>
<action id="ShowSplash" internal="true" class="com.intellij.ui.ShowSplashAction" text="Show Splash" />
<action id="ValidationTest" internal="true" class="com.intellij.internal.validation.TestDialogWithValidationAction" text="Validation Dialog Test" />
<action id="MacMessagesTest" internal="true" class="com.intellij.internal.validation.TestMacMessagesAction" text="Test Mac Messages" />
@@ -261,7 +261,10 @@ public class CompositePrintable implements Printable, Disposable {
@Override
public void print(String text, ConsoleViewContentType contentType) {
try {
IOUtil.writeString(contentType.toString() + text, getFileWriter());
final DataOutputStream writer = getFileWriter();
if (writer != null) {
IOUtil.writeString(contentType.toString() + text, writer);
}
}
catch (FileNotFoundException e) {
LOG.info(e);
@@ -276,11 +279,13 @@ public class CompositePrintable implements Printable, Disposable {
if (info instanceof DiffHyperlink.DiffHyperlinkInfo) {
final DiffHyperlink diffHyperlink = ((DiffHyperlink.DiffHyperlinkInfo)info).getPrintable();
try {
DataOutputStream fileWriter = getFileWriter();
IOUtil.writeString(HYPERLINK, fileWriter);
IOUtil.writeString(diffHyperlink.getLeft(), fileWriter);
IOUtil.writeString(diffHyperlink.getRight(), fileWriter);
IOUtil.writeString(diffHyperlink.getFilePath(), fileWriter);
final DataOutputStream fileWriter = getFileWriter();
if (fileWriter != null) {
IOUtil.writeString(HYPERLINK, fileWriter);
IOUtil.writeString(diffHyperlink.getLeft(), fileWriter);
IOUtil.writeString(diffHyperlink.getRight(), fileWriter);
IOUtil.writeString(diffHyperlink.getFilePath(), fileWriter);
}
}
catch (FileNotFoundException e) {
LOG.info(e);
@@ -0,0 +1,171 @@
/*
* Copyright 2000-2012 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.util.execution;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.containers.ContainerUtilRt;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author nik
*/
public class ParametersListUtil {
/**
* <p>Joins list of parameters into single string, which may be then parsed back into list by {@link #parseToArray(String)}.</p>
* <p/>
* <p>
* <strong>Conversion rules:</strong>
* <ul>
* <li>double quotes are escaped by backslash (<code>&#92;</code>);</li>
* <li>empty parameters parameters and parameters with spaces inside are surrounded with double quotes (<code>"</code>);</li>
* <li>parameters are separated by single whitespace.</li>
* </ul>
* </p>
* <p/>
* <p><strong>Examples:</strong></p>
* <p>
* <code>['a', 'b'] => 'a b'</code><br/>
* <code>['a="1 2"', 'b'] => '"a &#92;"1 2&#92;"" b'</code>
* </p>
*
* @param parameters a list of parameters to join.
* @return a string with parameters.
*/
@NotNull
public static String join(@NotNull final List<String> parameters) {
return encode(parameters);
}
@NotNull
public static String join(final String... parameters) {
return encode(Arrays.asList(parameters));
}
/**
* @see #parse(String)
*/
@NotNull
public static String[] parseToArray(@NotNull final String string) {
final List<String> params = parse(string);
return ArrayUtil.toStringArray(params);
}
/**
* <p>Converts single parameter string (as created by {@link #join(java.util.List)}) into list of parameters.</p>
* <p/>
* <p>
* <strong>Conversion rules:</strong>
* <ul>
* <li>starting/whitespaces are trimmed;</li>
* <li>parameters are split by whitespaces, whitespaces itself are dropped</li>
* <li>parameters inside double quotes (<code>"a b"</code>) are kept as single one;</li>
* <li>double quotes are dropped, escaped double quotes (<code>&#92;"</code>) are un-escaped.</li>
* </ul>
* </p>
* <p/>
* <p><strong>Examples:</strong></p>
* <p>
* <code>' a b ' => ['a', 'b']</code><br/>
* <code>'a="1 2" b' => ['a=1 2', 'b']</code><br/>
* <code>'a " " b' => ['a', ' ', 'b']</code><br/>
* <code>'"a &#92;"1 2&#92;"" b' => ['a="1 2"', 'b']</code>
* </p>
*
* @param string parameter string to split.
* @return array of parameters.
*/
@NotNull
public static List<String> parse(@NotNull String parameterString) {
parameterString = parameterString.trim();
final ArrayList<String> params = ContainerUtilRt.newArrayList();
final StringBuilder token = new StringBuilder(128);
boolean inQuotes = false;
boolean escapedQuote = false;
boolean nonEmpty = false;
for (int i = 0; i < parameterString.length(); i++) {
final char ch = parameterString.charAt(i);
if (ch == '\"') {
if (!escapedQuote) {
inQuotes = !inQuotes;
nonEmpty = true;
continue;
}
escapedQuote = false;
}
else if (Character.isWhitespace(ch)) {
if (!inQuotes) {
if (token.length() > 0 || nonEmpty) {
params.add(token.toString());
token.setLength(0);
nonEmpty = false;
}
continue;
}
}
else if (ch == '\\') {
if (i < parameterString.length() - 1 && parameterString.charAt(i + 1) == '"') {
escapedQuote = true;
continue;
}
}
token.append(ch);
}
if (token.length() > 0 || nonEmpty) {
params.add(token.toString());
}
return params;
}
@NotNull
private static String encode(@NotNull final List<String> parameters) {
final StringBuilder buffer = new StringBuilder();
for (final String parameter : parameters) {
if (buffer.length() > 0) {
buffer.append(' ');
}
buffer.append(encode(parameter));
}
return buffer.toString();
}
@NotNull
private static String encode(@NotNull String parameter) {
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append(parameter);
StringUtil.escapeQuotes(builder);
if (builder.length() == 0 || StringUtil.indexOf(builder, ' ') >= 0 || StringUtil.indexOf(builder, '|') >= 0) {
StringUtil.quote(builder);
}
return builder.toString();
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
}
@@ -74,24 +74,24 @@ public class ObjectsConvertor {
private ObjectsConvertor() {
}
public static List<VirtualFile> fp2vf(final Collection<FilePath> in) {
public static List<VirtualFile> fp2vf(@NotNull final Collection<FilePath> in) {
return convert(in, FILEPATH_TO_VIRTUAL);
}
public static List<FilePath> vf2fp(final List<VirtualFile> in) {
public static List<FilePath> vf2fp(@NotNull final List<VirtualFile> in) {
return convert(in, VIRTUAL_FILEPATH);
}
public static List<File> fp2jiof(final Collection<FilePath> in) {
public static List<File> fp2jiof(@NotNull final Collection<FilePath> in) {
return convert(in, FILEPATH_FILE);
}
public static <T,S> List<S> convert(final Collection<T> in, final Convertor<T,S> convertor) {
public static <T,S> List<S> convert(@NotNull final Collection<T> in, final Convertor<T,S> convertor) {
return convert(in, convertor, null);
}
public static <T,U, S extends U> List<S> convert(final Collection<T> in, final Convertor<T,S> convertor,
@Nullable final NotNullFunction<U, Boolean> outFilter) {
public static <T,U, S extends U> List<S> convert(@NotNull final Collection<T> in, final Convertor<T,S> convertor,
@Nullable final NotNullFunction<U, Boolean> outFilter) {
final List<S> out = new ArrayList<S>();
for (T t : in) {
final S converted = convertor.convert(t);
@@ -1337,6 +1337,7 @@ switch.statement.with.too.few.branches.problem.descriptor='<code>#ref</code>' ha
switch.statement.without.default.ignore.option=Ignore if all cases of an enumerated type are covered
unnecessary.label.remove.quickfix=Remove label
unnecessary.return.problem.descriptor=<code>#ref</code> is unnecessary as the last statement in a 'void' method #loc
unnecessary.return.constructor.problem.descriptor=<code>#ref</code> is unnecessary as the last statement in a constructor #loc
unused.label.remove.quickfix=Remove unused label
unnecessarily.qualified.static.usage.problem.descriptor=Unnecessarily qualified static method call <code>#ref()</code> #loc
unnecessarily.qualified.static.usage.problem.descriptor1=Unnecessarily qualified static access <code>#ref</code> #loc
@@ -1945,7 +1946,7 @@ parameter.of.concrete.class.option=Ignore parameters whose type is abstract clas
static.variable.of.concrete.class.option=Ignore static fields whose type is an abstract class
class.only.used.in.one.package.display.name=Class only used from one other package
class.only.used.in.one.package.problem.descriptor=Class <code>#ref</code> has only dependencies on and/or dependents in package ''{0}'' #loc
unnecessary.return.option=Ignore in then branch branch of 'if' statement with 'else' branch
unnecessary.return.option=Ignore in then branch of 'if' statement with 'else' branch
usage.of.obsolete.assert.display.name=Usage of obsolete 'junit.framework.Assert'
use.of.obsolete.assert.problem.descriptor=Call to <code>#ref()</code> from 'org.junit.framework.Assert' should be replaced with call to method from 'org.junit.Assert' #loc
use.of.obsolete.assert.quickfix=Replace with 'org.junit.Assert' method call
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2012 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.
@@ -41,8 +41,18 @@ public class UnnecessaryReturnInspection extends BaseInspection {
@Override
@NotNull
public String getDisplayName() {
return InspectionGadgetsBundle.message(
"unnecessary.return.display.name");
return InspectionGadgetsBundle.message("unnecessary.return.display.name");
}
@Override
@NotNull
public String buildErrorString(Object... infos) {
if (((Boolean)infos[0]).booleanValue()) {
return InspectionGadgetsBundle.message("unnecessary.return.constructor.problem.descriptor");
}
else {
return InspectionGadgetsBundle.message("unnecessary.return.problem.descriptor");
}
}
@Override
@@ -52,15 +62,7 @@ public class UnnecessaryReturnInspection extends BaseInspection {
@Override
public JComponent createOptionsPanel() {
return new SingleCheckboxOptionsPanel(
InspectionGadgetsBundle.message("unnecessary.return.option"),
this, "ignoreInThenBranch");
}
@Override
@NotNull
public String buildErrorString(Object... infos) {
return InspectionGadgetsBundle.message("unnecessary.return.problem.descriptor");
return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message("unnecessary.return.option"), this, "ignoreInThenBranch");
}
@Override
@@ -85,41 +87,43 @@ public class UnnecessaryReturnInspection extends BaseInspection {
}
final PsiElement methodParent = PsiTreeUtil.getParentOfType(statement, PsiMethod.class, PsiLambdaExpression.class);
PsiCodeBlock codeBlock = null;
final boolean constructor;
if (methodParent instanceof PsiMethod) {
codeBlock = ((PsiMethod)methodParent).getBody();
final PsiMethod method = (PsiMethod)methodParent;
codeBlock = method.getBody();
constructor = method.isConstructor();
}
else if (methodParent instanceof PsiLambdaExpression) {
final PsiElement lambdaBody = ((PsiLambdaExpression)methodParent).getBody();
constructor = false;
final PsiLambdaExpression lambdaExpression = (PsiLambdaExpression)methodParent;
final PsiElement lambdaBody = lambdaExpression.getBody();
if (lambdaBody instanceof PsiCodeBlock) {
codeBlock = (PsiCodeBlock)lambdaBody;
}
}
else {
return;
}
if (codeBlock == null) {
return;
}
if (!ControlFlowUtils.blockCompletesWithStatement(codeBlock, statement)) {
return;
}
if (ignoreInThenBranch && isInThenBranch(statement, statement.getParent())) {
if (ignoreInThenBranch && isInThenBranch(statement)) {
return;
}
registerStatementError(statement);
registerStatementError(statement, Boolean.valueOf(constructor));
}
private boolean isInThenBranch(PsiReturnStatement statement, PsiElement parent) {
if (!(parent instanceof PsiCodeBlock)) {
private boolean isInThenBranch(PsiStatement statement) {
final PsiIfStatement ifStatement =
PsiTreeUtil.getParentOfType(statement, PsiIfStatement.class, true, PsiMethod.class, PsiLambdaExpression.class);
if (ifStatement == null) {
return false;
}
final PsiElement grandParent = parent.getParent();
if (grandParent == null) {
return false;
}
final PsiElement greatGrandParent = grandParent.getParent();
if (!(greatGrandParent instanceof PsiIfStatement)) {
return false;
}
final PsiStatement elseBranch = ((PsiIfStatement)greatGrandParent).getElseBranch();
return elseBranch == null || !PsiTreeUtil.isAncestor(elseBranch, statement, true);
final PsiStatement elseBranch = ifStatement.getElseBranch();
return elseBranch != null && !PsiTreeUtil.isAncestor(elseBranch, statement, true);
}
}
}
@@ -18,6 +18,7 @@ package com.siyeh.ig.imports;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
@@ -34,8 +35,10 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class StaticImportInspection extends BaseInspection {
@@ -139,27 +142,22 @@ public class StaticImportInspection extends BaseInspection {
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
final PsiElementFactory factory = psiFacade.getElementFactory();
final PsiClass aClass = target.getContainingClass();
if (aClass == null) {
return;
}
final String qualifiedName = aClass.getQualifiedName();
final String text = reference.getText();
final String referenceText = qualifiedName + '.' + text;
if (reference instanceof PsiReferenceExpression) {
try {
final PsiExpression newReference = factory.createExpressionFromText(referenceText, reference);
reference.replace(newReference);
}
catch (IncorrectOperationException e) {
throw new RuntimeException(e);
}
final PsiExpression newReference = factory.createExpressionFromText(referenceText, reference);
final PsiElement insertedElement = reference.replace(newReference);
JavaCodeStyleManager.getInstance(project).shortenClassReferences(insertedElement);
}
else {
final PsiJavaCodeReferenceElement referenceElement =
factory.createReferenceElementByFQClassName(referenceText, reference.getResolveScope());
try {
reference.replace(referenceElement);
}
catch (IncorrectOperationException e) {
throw new RuntimeException(e);
}
final PsiElement insertedElement = reference.replace(referenceElement);
JavaCodeStyleManager.getInstance(project).shortenClassReferences(insertedElement);
}
}
@@ -204,7 +202,7 @@ public class StaticImportInspection extends BaseInspection {
final PsiMember member = (PsiMember)target;
for (JavaResolveResult importTarget : importTargets) {
final PsiElement targetElement = importTarget.getElement();
if (targetElement instanceof PsiMethod) {
if (targetElement instanceof PsiMethod || targetElement instanceof PsiField) {
if (member.equals(targetElement)) {
addReference(reference);
}
@@ -24,6 +24,7 @@ import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.ImportUtils;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -47,8 +48,7 @@ public class AssertEqualsCalledOnArrayInspection extends BaseInspection {
return new AssertEqualsCalledOnArrayFix();
}
private static class AssertEqualsCalledOnArrayFix
extends InspectionGadgetsFix {
private static class AssertEqualsCalledOnArrayFix extends InspectionGadgetsFix {
@Override
@NotNull
@@ -59,17 +59,17 @@ public class AssertEqualsCalledOnArrayInspection extends BaseInspection {
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement methodNameIdentifier = descriptor.getPsiElement();
final PsiReferenceExpression methodExpression = (PsiReferenceExpression)methodNameIdentifier.getParent();
if (methodExpression == null) {
final PsiElement parent = methodNameIdentifier.getParent();
if (!(parent instanceof PsiReferenceExpression)) {
return;
}
final PsiReferenceExpression methodExpression = (PsiReferenceExpression)parent;
final PsiExpression qualifier = methodExpression.getQualifierExpression();
if (qualifier == null) {
if (qualifier == null && ImportUtils.addStaticImport("org.junit.Assert", "assertArrayEquals", methodExpression)) {
replaceExpression(methodExpression, "assertArrayEquals");
}
else {
final String qualifierText = qualifier.getText();
replaceExpression(methodExpression, qualifierText + ".assertArrayEquals");
replaceExpression(methodExpression, "org.junit.Assert.assertArrayEquals");
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2008-2010 Bas Leijdekkers
* Copyright 2008-2012 Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@ import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.ImportUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -31,15 +32,13 @@ public class AssertEqualsMayBeAssertSameInspection extends BaseInspection {
@Override
@NotNull
public String getDisplayName() {
return InspectionGadgetsBundle.message(
"assertequals.may.be.assertsame.display.name");
return InspectionGadgetsBundle.message("assertequals.may.be.assertsame.display.name");
}
@Override
@NotNull
protected String buildErrorString(Object... infos) {
return InspectionGadgetsBundle.message(
"assertequals.may.be.assertsame.problem.descriptor");
return InspectionGadgetsBundle.message("assertequals.may.be.assertsame.problem.descriptor");
}
@Override
@@ -47,29 +46,45 @@ public class AssertEqualsMayBeAssertSameInspection extends BaseInspection {
return new AssertEqualsMayBeAssertSameFix();
}
private static class AssertEqualsMayBeAssertSameFix
extends InspectionGadgetsFix {
private static class AssertEqualsMayBeAssertSameFix extends InspectionGadgetsFix {
@NotNull
public String getName() {
return InspectionGadgetsBundle.message(
"assertequals.may.be.assertsame.quickfix");
return InspectionGadgetsBundle.message("assertequals.may.be.assertsame.quickfix");
}
@Override
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement();
final PsiElement grandParent = element.getParent().getParent();
final PsiElement parent = element.getParent();
if (!(parent instanceof PsiReferenceExpression)) {
return;
}
final PsiReferenceExpression methodExpression = (PsiReferenceExpression)parent;
final PsiElement grandParent = methodExpression.getParent();
if (!(grandParent instanceof PsiMethodCallExpression)) {
return;
}
final PsiMethodCallExpression methodCallExpression =
(PsiMethodCallExpression)grandParent;
@NonNls final String text = methodCallExpression.getText();
final String newExpressionText =
text.replace("assertEquals", "assertSame");
replaceExpression(methodCallExpression, newExpressionText);
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)grandParent;
final PsiMethod method = methodCallExpression.resolveMethod();
if (method == null) {
return;
}
final PsiClass containingClass = method.getContainingClass();
if (containingClass == null) {
return;
}
final String className = containingClass.getQualifiedName();
if (className == null) {
return;
}
final PsiExpression qualifier = methodExpression.getQualifierExpression();
if (qualifier == null && ImportUtils.addStaticImport(className, "assertSame", methodExpression)) {
replaceExpression(methodExpression, "assertSame");
}
else {
replaceExpression(methodExpression, className + ".assertSame");
}
}
}
@@ -78,22 +93,19 @@ public class AssertEqualsMayBeAssertSameInspection extends BaseInspection {
return new AssertEqualsMayBeAssertSameVisitor();
}
private static class AssertEqualsMayBeAssertSameVisitor
extends BaseInspectionVisitor {
private static class AssertEqualsMayBeAssertSameVisitor extends BaseInspectionVisitor {
@Override
public void visitMethodCallExpression(
PsiMethodCallExpression expression) {
public void visitMethodCallExpression(PsiMethodCallExpression expression) {
super.visitMethodCallExpression(expression);
final PsiReferenceExpression methodExpression =
expression.getMethodExpression();
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
@NonNls final String name = methodExpression.getReferenceName();
if (!"assertEquals".equals(name)) {
return;
}
final PsiExpressionList argumentList = expression.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
if (arguments.length == 3 && arguments.length == 2) {
if (arguments.length != 3 && arguments.length != 2) {
return;
}
final PsiMethod method = expression.resolveMethod();
@@ -105,8 +117,7 @@ public class AssertEqualsMayBeAssertSameInspection extends BaseInspection {
return;
}
final String qualifiedName = aClass.getQualifiedName();
if (!"org.junit.Assert".equals(qualifiedName) &&
!"junit.framework.Assert".equals(qualifiedName)) {
if (!"org.junit.Assert".equals(qualifiedName) && !"junit.framework.Assert".equals(qualifiedName)) {
return;
}
final PsiExpression argument1 = arguments[arguments.length - 2];
@@ -120,9 +131,8 @@ public class AssertEqualsMayBeAssertSameInspection extends BaseInspection {
registerMethodCallError(expression);
}
private static boolean couldBeAssertSameArgument(
PsiExpression argument1) {
final PsiType type = argument1.getType();
private static boolean couldBeAssertSameArgument(PsiExpression expression) {
final PsiType type = expression.getType();
if (!(type instanceof PsiClassType)) {
return false;
}
@@ -134,19 +144,15 @@ public class AssertEqualsMayBeAssertSameInspection extends BaseInspection {
if (!argumentClass.hasModifierProperty(PsiModifier.FINAL)) {
return false;
}
final PsiMethod[] methods =
argumentClass.findMethodsByName("equals", true);
final PsiManager manager = argument1.getManager();
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(
manager.getProject());
final PsiClass objectClass = psiFacade.findClass(
CommonClassNames.JAVA_LANG_OBJECT,
argumentClass.getResolveScope());
final PsiMethod[] methods = argumentClass.findMethodsByName("equals", true);
final PsiManager manager = expression.getManager();
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(manager.getProject());
final PsiClass objectClass = psiFacade.findClass(CommonClassNames.JAVA_LANG_OBJECT, argumentClass.getResolveScope());
if (objectClass == null) {
return false;
}
for (PsiMethod psiMethod : methods) {
final PsiClass containingClass = psiMethod.getContainingClass();
for (PsiMethod method : methods) {
final PsiClass containingClass = method.getContainingClass();
if (!objectClass.equals(containingClass)) {
return false;
}
@@ -19,7 +19,6 @@ import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
@@ -34,15 +33,13 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
@Override
@NotNull
public String getDisplayName() {
return InspectionGadgetsBundle.message(
"simplifiable.junit.assertion.display.name");
return InspectionGadgetsBundle.message("simplifiable.junit.assertion.display.name");
}
@Override
@NotNull
protected String buildErrorString(Object... infos) {
return InspectionGadgetsBundle.message(
"simplifiable.junit.assertion.problem.descriptor", infos[0]);
return InspectionGadgetsBundle.message("simplifiable.junit.assertion.problem.descriptor", infos[0]);
}
@Override
@@ -55,20 +52,17 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
@Override
@NotNull
public String getName() {
return InspectionGadgetsBundle.message(
"simplify.junit.assertion.simplify.quickfix");
return InspectionGadgetsBundle.message("simplify.junit.assertion.simplify.quickfix");
}
@Override
public void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
public void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement methodNameIdentifier = descriptor.getPsiElement();
final PsiElement parent = methodNameIdentifier.getParent();
if (parent == null) {
return;
}
final PsiMethodCallExpression callExpression =
(PsiMethodCallExpression)parent.getParent();
final PsiMethodCallExpression callExpression = (PsiMethodCallExpression)parent.getParent();
if (isAssertThatCouldBeAssertNull(callExpression)) {
replaceAssertWithAssertNull(callExpression);
}
@@ -86,15 +80,12 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
}
}
private static void replaceAssertWithFail(
PsiMethodCallExpression callExpression)
throws IncorrectOperationException {
private static void replaceAssertWithFail(PsiMethodCallExpression callExpression) throws IncorrectOperationException {
final PsiMethod method = callExpression.resolveMethod();
if (method == null) {
return;
}
final PsiExpressionList argumentList =
callExpression.getArgumentList();
final PsiExpressionList argumentList = callExpression.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
final PsiExpression message;
if (arguments.length == 2) {
@@ -104,19 +95,18 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
message = null;
}
@NonNls final StringBuilder newExpression = new StringBuilder();
addStaticImportIfPossible(callExpression, "fail", newExpression);
if (!ImportUtils.addStaticImport("org.junit.Assert", "fail", callExpression)) {
newExpression.append("org.junit.Assert.");
}
newExpression.append("fail(");
if (message != null) {
newExpression.append(message.getText());
}
newExpression.append(')');
replaceExpressionAndShorten(callExpression,
newExpression.toString());
replaceExpressionAndShorten(callExpression, newExpression.toString());
}
private static void replaceAssertTrueWithAssertEquals(
PsiMethodCallExpression callExpression)
throws IncorrectOperationException {
private static void replaceAssertTrueWithAssertEquals(PsiMethodCallExpression callExpression) throws IncorrectOperationException {
final PsiMethod method = callExpression.resolveMethod();
if (method == null) {
return;
@@ -125,8 +115,7 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
final PsiParameter[] parameters = parameterList.getParameters();
final PsiType stringType = TypeUtils.getStringType(callExpression);
final PsiType paramType1 = parameters[0].getType();
final PsiExpressionList argumentList =
callExpression.getArgumentList();
final PsiExpressionList argumentList = callExpression.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
final int testPosition;
final PsiExpression message;
@@ -142,25 +131,19 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
PsiExpression lhs = null;
PsiExpression rhs = null;
if (testArgument instanceof PsiBinaryExpression) {
final PsiBinaryExpression binaryExpression =
(PsiBinaryExpression)testArgument;
final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)testArgument;
lhs = binaryExpression.getLOperand();
rhs = binaryExpression.getROperand();
}
else if (testArgument instanceof PsiMethodCallExpression) {
final PsiMethodCallExpression call =
(PsiMethodCallExpression)testArgument;
final PsiReferenceExpression equalityMethodExpression =
call.getMethodExpression();
final PsiExpressionList equalityArgumentList =
call.getArgumentList();
final PsiExpression[] equalityArgs =
equalityArgumentList.getExpressions();
final PsiMethodCallExpression call = (PsiMethodCallExpression)testArgument;
final PsiReferenceExpression equalityMethodExpression = call.getMethodExpression();
final PsiExpressionList equalityArgumentList = call.getArgumentList();
final PsiExpression[] equalityArgs = equalityArgumentList.getExpressions();
rhs = equalityArgs[0];
lhs = equalityMethodExpression.getQualifierExpression();
}
if (!(lhs instanceof PsiLiteralExpression) &&
rhs instanceof PsiLiteralExpression) {
if (!(lhs instanceof PsiLiteralExpression) && rhs instanceof PsiLiteralExpression) {
final PsiExpression temp = lhs;
lhs = rhs;
rhs = temp;
@@ -169,27 +152,22 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
return;
}
@NonNls final StringBuilder newExpression = new StringBuilder();
addStaticImportIfPossible(callExpression, "assertEquals",
newExpression);
if (!ImportUtils.addStaticImport("org.junit.Assert", "assertEquals", callExpression)) {
newExpression.append("org.junit.Assert.");
}
newExpression.append("assertEquals(");
if (message != null) {
newExpression.append(message.getText());
newExpression.append(',');
newExpression.append(message.getText()).append(',');
}
newExpression.append(lhs.getText());
newExpression.append(',');
newExpression.append(rhs.getText());
if (isFloatingPoint(lhs) || isFloatingPoint(rhs)) {
newExpression.append(lhs.getText()).append(',').append(rhs.getText());
if (TypeUtils.hasFloatingPointType(lhs) || TypeUtils.hasFloatingPointType(rhs)) {
newExpression.append(",0.0");
}
newExpression.append(')');
replaceExpressionAndShorten(callExpression,
newExpression.toString());
replaceExpressionAndShorten(callExpression, newExpression.toString());
}
private static void replaceAssertWithAssertNull(
PsiMethodCallExpression callExpression)
throws IncorrectOperationException {
private static void replaceAssertWithAssertNull(PsiMethodCallExpression callExpression) throws IncorrectOperationException {
final PsiMethod method = callExpression.resolveMethod();
if (method == null) {
return;
@@ -198,8 +176,7 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
final PsiParameter[] parameters = parameterList.getParameters();
final PsiType stringType = TypeUtils.getStringType(callExpression);
final PsiType paramType1 = parameters[0].getType();
final PsiExpressionList argumentList =
callExpression.getArgumentList();
final PsiExpressionList argumentList = callExpression.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
final int testPosition;
final PsiExpression message;
@@ -211,48 +188,38 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
testPosition = 0;
message = null;
}
final PsiBinaryExpression binaryExpression =
(PsiBinaryExpression)arguments[testPosition];
final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)arguments[testPosition];
final PsiExpression lhs = binaryExpression.getLOperand();
PsiExpression rhs = binaryExpression.getROperand();
if (rhs == null) {
return;
}
final IElementType tokenType =
binaryExpression.getOperationTokenType();
if (!(lhs instanceof PsiLiteralExpression) &&
rhs instanceof PsiLiteralExpression) {
final IElementType tokenType = binaryExpression.getOperationTokenType();
if (!(lhs instanceof PsiLiteralExpression) && rhs instanceof PsiLiteralExpression) {
rhs = lhs;
}
@NonNls final StringBuilder newExpression = new StringBuilder();
final PsiReferenceExpression methodExpression =
callExpression.getMethodExpression();
@NonNls final String methodName =
methodExpression.getReferenceName();
final PsiReferenceExpression methodExpression = callExpression.getMethodExpression();
@NonNls final String methodName = methodExpression.getReferenceName();
@NonNls final String memberName;
if ("assertFalse".equals(methodName) ^
tokenType.equals(JavaTokenType.NE)) {
if ("assertFalse".equals(methodName) ^ tokenType.equals(JavaTokenType.NE)) {
memberName = "assertNotNull";
}
else {
memberName = "assertNull";
}
addStaticImportIfPossible(callExpression, memberName, newExpression);
newExpression.append(memberName);
newExpression.append('(');
if (message != null) {
newExpression.append(message.getText());
newExpression.append(',');
if (!ImportUtils.addStaticImport("org.junit.Assert", memberName, callExpression)) {
newExpression.append("org.junit.Assert.");
}
newExpression.append(rhs.getText());
newExpression.append(')');
replaceExpressionAndShorten(callExpression,
newExpression.toString());
newExpression.append(memberName).append('(');
if (message != null) {
newExpression.append(message.getText()).append(',');
}
newExpression.append(rhs.getText()).append(')');
replaceExpressionAndShorten(callExpression, newExpression.toString());
}
private static void replaceAssertWithAssertSame(
PsiMethodCallExpression callExpression)
throws IncorrectOperationException {
private static void replaceAssertWithAssertSame(PsiMethodCallExpression callExpression) throws IncorrectOperationException {
final PsiMethod method = callExpression.resolveMethod();
if (method == null) {
return;
@@ -261,8 +228,7 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
final PsiParameter[] parameters = parameterList.getParameters();
final PsiType stringType = TypeUtils.getStringType(callExpression);
final PsiType paramType1 = parameters[0].getType();
final PsiExpressionList argumentList =
callExpression.getArgumentList();
final PsiExpressionList argumentList = callExpression.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
final int testPosition;
final PsiExpression message;
@@ -274,14 +240,11 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
testPosition = 0;
message = null;
}
final PsiBinaryExpression binaryExpression =
(PsiBinaryExpression)arguments[testPosition];
final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)arguments[testPosition];
PsiExpression lhs = binaryExpression.getLOperand();
PsiExpression rhs = binaryExpression.getROperand();
final IElementType tokenType =
binaryExpression.getOperationTokenType();
if (!(lhs instanceof PsiLiteralExpression) &&
rhs instanceof PsiLiteralExpression) {
final IElementType tokenType = binaryExpression.getOperationTokenType();
if (!(lhs instanceof PsiLiteralExpression) && rhs instanceof PsiLiteralExpression) {
final PsiExpression temp = lhs;
lhs = rhs;
rhs = temp;
@@ -290,31 +253,24 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
return;
}
@NonNls final StringBuilder newExpression = new StringBuilder();
final PsiReferenceExpression methodExpression =
callExpression.getMethodExpression();
@NonNls final String methodName =
methodExpression.getReferenceName();
final PsiReferenceExpression methodExpression = callExpression.getMethodExpression();
@NonNls final String methodName = methodExpression.getReferenceName();
@NonNls final String memberName;
if ("assertFalse".equals(methodName) ^
tokenType.equals(JavaTokenType.NE)) {
if ("assertFalse".equals(methodName) ^ tokenType.equals(JavaTokenType.NE)) {
memberName = "assertNotSame";
}
else {
memberName = "assertSame";
}
addStaticImportIfPossible(callExpression, memberName, newExpression);
newExpression.append(memberName);
newExpression.append('(');
if (message != null) {
newExpression.append(message.getText());
newExpression.append(',');
if (!ImportUtils.addStaticImport("org.junit.Assert", memberName, callExpression)) {
newExpression.append("org.junit.Assert.");
}
newExpression.append(lhs.getText());
newExpression.append(',');
newExpression.append(rhs.getText());
newExpression.append(')');
replaceExpressionAndShorten(callExpression,
newExpression.toString());
newExpression.append(memberName).append('(');
if (message != null) {
newExpression.append(message.getText()).append(',');
}
newExpression.append(lhs.getText()).append(',').append(rhs.getText()).append(')');
replaceExpressionAndShorten(callExpression, newExpression.toString());
}
private static void replaceAssertEqualsWithAssertLiteral(
@@ -328,8 +284,7 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
final PsiParameter[] parameters = parameterList.getParameters();
final PsiType stringType = TypeUtils.getStringType(callExpression);
final PsiType paramType1 = parameters[0].getType();
final PsiExpressionList argumentList =
callExpression.getArgumentList();
final PsiExpressionList argumentList = callExpression.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
final int firstTestPosition;
final int secondTestPosition;
@@ -344,10 +299,8 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
secondTestPosition = 1;
message = null;
}
final PsiExpression firstTestArgument =
arguments[firstTestPosition];
final PsiExpression secondTestArgument =
arguments[secondTestPosition];
final PsiExpression firstTestArgument = arguments[firstTestPosition];
final PsiExpression secondTestArgument = arguments[secondTestPosition];
final String literalValue;
final String compareValue;
if (isSimpleLiteral(firstTestArgument, secondTestArgument)) {
@@ -358,47 +311,18 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
literalValue = secondTestArgument.getText();
compareValue = firstTestArgument.getText();
}
final String uppercaseLiteralValue =
Character.toUpperCase(literalValue.charAt(0)) +
literalValue.substring(1);
final String uppercaseLiteralValue = Character.toUpperCase(literalValue.charAt(0)) + literalValue.substring(1);
@NonNls final StringBuilder newExpression = new StringBuilder();
@NonNls final String methodName = "assert" + uppercaseLiteralValue;
addStaticImportIfPossible(callExpression, methodName, newExpression);
newExpression.append(methodName);
newExpression.append('(');
if (!ImportUtils.addStaticImport("org.junit.Assert", methodName, callExpression)) {
newExpression.append("org.junit.Assert.");
}
newExpression.append(methodName).append('(');
if (message != null) {
newExpression.append(message.getText());
newExpression.append(',');
newExpression.append(message.getText()).append(',');
}
newExpression.append(compareValue);
newExpression.append(')');
replaceExpressionAndShorten(callExpression,
newExpression.toString());
}
private static void addStaticImportIfPossible(
PsiMethodCallExpression context, @NonNls String memberName,
@NonNls StringBuilder out) {
final PsiMethod containingMethod = PsiTreeUtil.getParentOfType(
context, PsiMethod.class);
if (TestUtils.isJUnit4TestMethod(containingMethod)) {
final PsiReferenceExpression methodExpression =
context.getMethodExpression();
if (methodExpression.isQualified() ||
!ImportUtils.nameCanBeStaticallyImported(
"org.junit.Assert", memberName, context)) {
out.append("org.junit.Assert.");
}
else {
ImportUtils.addStaticImport(
"org.junit.Assert", memberName, context);
}
}
}
private static boolean isFloatingPoint(PsiExpression expression) {
final PsiType type = expression.getType();
return PsiType.FLOAT.equals(type) || PsiType.DOUBLE.equals(type);
newExpression.append(compareValue).append(')');
replaceExpressionAndShorten(callExpression, newExpression.toString());
}
}
@@ -407,12 +331,10 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
return new SimplifiableJUnitAssertionVisitor();
}
private static class SimplifiableJUnitAssertionVisitor
extends BaseInspectionVisitor {
private static class SimplifiableJUnitAssertionVisitor extends BaseInspectionVisitor {
@Override
public void visitMethodCallExpression(
@NotNull PsiMethodCallExpression expression) {
public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
super.visitMethodCallExpression(expression);
if (isAssertThatCouldBeAssertNull(expression)) {
if (hasEqEqExpressionArgument(expression)) {
@@ -434,8 +356,7 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
registerMethodCallError(expression, "assertEquals()");
}
else if (isAssertEqualsThatCouldBeAssertLiteral(expression)) {
registerMethodCallError(expression,
getReplacementMethodName(expression));
registerMethodCallError(expression, getReplacementMethodName(expression));
}
else if (isAssertThatCouldBeFail(expression)) {
registerMethodCallError(expression, "fail()");
@@ -443,14 +364,12 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
}
@NonNls
private static String getReplacementMethodName(
PsiMethodCallExpression expression) {
private static String getReplacementMethodName(PsiMethodCallExpression expression) {
final PsiExpressionList argumentList = expression.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
final PsiExpression firstArgument = arguments[0];
if (firstArgument instanceof PsiLiteralExpression) {
final PsiLiteralExpression literalExpression =
(PsiLiteralExpression)firstArgument;
final PsiLiteralExpression literalExpression = (PsiLiteralExpression)firstArgument;
final Object value = literalExpression.getValue();
if (value == Boolean.TRUE) {
return "assertTrue()";
@@ -464,8 +383,7 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
}
final PsiExpression secondArgument = arguments[1];
if (secondArgument instanceof PsiLiteralExpression) {
final PsiLiteralExpression literalExpression =
(PsiLiteralExpression)secondArgument;
final PsiLiteralExpression literalExpression = (PsiLiteralExpression)secondArgument;
final Object value = literalExpression.getValue();
if (value == Boolean.TRUE) {
return "assertTrue()";
@@ -480,18 +398,15 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
return "";
}
private static boolean hasEqEqExpressionArgument(
PsiMethodCallExpression expression) {
private static boolean hasEqEqExpressionArgument(PsiMethodCallExpression expression) {
final PsiExpressionList list = expression.getArgumentList();
final PsiExpression[] arguments = list.getExpressions();
final PsiExpression argument = arguments[0];
if (!(argument instanceof PsiBinaryExpression)) {
return false;
}
final PsiBinaryExpression binaryExpression =
(PsiBinaryExpression)argument;
final IElementType tokenType =
binaryExpression.getOperationTokenType();
final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)argument;
final IElementType tokenType = binaryExpression.getOperationTokenType();
return JavaTokenType.EQEQ.equals(tokenType);
}
}
@@ -501,8 +416,7 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
if (!isAssertTrue(expression)) {
return false;
}
final PsiReferenceExpression methodExpression =
expression.getMethodExpression();
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
final PsiMethod method = (PsiMethod)methodExpression.resolve();
if (method == null) {
return false;
@@ -527,13 +441,11 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
return testArgument != null && isEqualityComparison(testArgument);
}
static boolean isAssertThatCouldBeAssertSame(
PsiMethodCallExpression expression) {
static boolean isAssertThatCouldBeAssertSame(PsiMethodCallExpression expression) {
if (!isAssertTrue(expression) && !isAssertFalse(expression)) {
return false;
}
final PsiReferenceExpression methodExpression =
expression.getMethodExpression();
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
final PsiMethod method = (PsiMethod)methodExpression.resolve();
if (method == null) {
return false;
@@ -558,13 +470,11 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
return testArgument != null && isIdentityComparison(testArgument);
}
static boolean isAssertThatCouldBeAssertNull(
PsiMethodCallExpression expression) {
static boolean isAssertThatCouldBeAssertNull(PsiMethodCallExpression expression) {
if (!isAssertTrue(expression) && !isAssertFalse(expression)) {
return false;
}
final PsiReferenceExpression methodExpression =
expression.getMethodExpression();
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
final PsiMethod method = (PsiMethod)methodExpression.resolve();
if (method == null) {
return false;
@@ -601,8 +511,7 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
else {
return false;
}
final PsiReferenceExpression methodExpression =
expression.getMethodExpression();
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
final PsiMethod method = (PsiMethod)methodExpression.resolve();
if (method == null) {
return false;
@@ -636,13 +545,11 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
}
}
static boolean isAssertEqualsThatCouldBeAssertLiteral(
PsiMethodCallExpression expression) {
static boolean isAssertEqualsThatCouldBeAssertLiteral(PsiMethodCallExpression expression) {
if (!isAssertEquals(expression)) {
return false;
}
final PsiReferenceExpression methodExpression =
expression.getMethodExpression();
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
final PsiMethod method = (PsiMethod)methodExpression.resolve();
if (method == null) {
return false;
@@ -675,8 +582,7 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
isSimpleLiteral(secondTestArgument, firstTestArgument);
}
static boolean isSimpleLiteral(PsiExpression expression1,
PsiExpression expression2) {
static boolean isSimpleLiteral(PsiExpression expression1, PsiExpression expression2) {
if (!(expression1 instanceof PsiLiteralExpression)) {
return false;
}
@@ -684,8 +590,7 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
if (PsiKeyword.NULL.equals(text)) {
return true;
}
if (!PsiKeyword.TRUE.equals(text) &&
!PsiKeyword.FALSE.equals(text)) {
if (!PsiKeyword.TRUE.equals(text) && !PsiKeyword.FALSE.equals(text)) {
return false;
}
final PsiType type = expression2.getType();
@@ -694,8 +599,7 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
private static boolean isEqualityComparison(PsiExpression expression) {
if (expression instanceof PsiBinaryExpression) {
final PsiBinaryExpression binaryExpression =
(PsiBinaryExpression)expression;
final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)expression;
final IElementType tokenType = binaryExpression.getOperationTokenType();
if (!tokenType.equals(JavaTokenType.EQEQ)) {
return false;
@@ -709,13 +613,11 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
return type != null && ClassUtils.isPrimitive(type);
}
else if (expression instanceof PsiMethodCallExpression) {
final PsiMethodCallExpression call =
(PsiMethodCallExpression)expression;
final PsiMethodCallExpression call = (PsiMethodCallExpression)expression;
if (!MethodCallUtils.isEqualsCall(call)) {
return false;
}
final PsiReferenceExpression methodExpression =
call.getMethodExpression();
final PsiReferenceExpression methodExpression = call.getMethodExpression();
return methodExpression.getQualifierExpression() != null;
}
return false;
@@ -725,8 +627,7 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
if (!(expression instanceof PsiBinaryExpression)) {
return false;
}
final PsiBinaryExpression binaryExpression =
(PsiBinaryExpression)expression;
final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)expression;
if (!ComparisonUtils.isEqualityComparison(binaryExpression)) {
return false;
}
@@ -747,8 +648,7 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
if (!(expression instanceof PsiBinaryExpression)) {
return false;
}
final PsiBinaryExpression binaryExpression =
(PsiBinaryExpression)expression;
final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)expression;
if (!ComparisonUtils.isEqualityComparison(binaryExpression)) {
return false;
}
@@ -757,30 +657,24 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
return false;
}
final PsiExpression lhs = binaryExpression.getLOperand();
return PsiKeyword.NULL.equals(lhs.getText()) ||
PsiKeyword.NULL.equals(rhs.getText());
return PsiKeyword.NULL.equals(lhs.getText()) || PsiKeyword.NULL.equals(rhs.getText());
}
private static boolean isAssertTrue(
@NotNull PsiMethodCallExpression expression) {
private static boolean isAssertTrue(@NotNull PsiMethodCallExpression expression) {
return isAssertMethodCall(expression, "assertTrue");
}
private static boolean isAssertFalse(
@NotNull PsiMethodCallExpression expression) {
private static boolean isAssertFalse(@NotNull PsiMethodCallExpression expression) {
return isAssertMethodCall(expression, "assertFalse");
}
private static boolean isAssertEquals(
@NotNull PsiMethodCallExpression expression) {
private static boolean isAssertEquals(@NotNull PsiMethodCallExpression expression) {
return isAssertMethodCall(expression, "assertEquals");
}
private static boolean isAssertMethodCall(
@NotNull PsiMethodCallExpression expression,
private static boolean isAssertMethodCall(@NotNull PsiMethodCallExpression expression,
@NonNls @NotNull String assertMethodName) {
final PsiReferenceExpression methodExpression =
expression.getMethodExpression();
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
@NonNls final String methodName = methodExpression.getReferenceName();
if (!assertMethodName.equals(methodName)) {
return false;
@@ -794,7 +688,6 @@ public class SimplifiableJUnitAssertionInspection extends BaseInspection {
return false;
}
final String qualifiedName = targetClass.getQualifiedName();
return "junit.framework.Assert".equals(qualifiedName) ||
"org.junit.Assert".equals(qualifiedName);
return "junit.framework.Assert".equals(qualifiedName) || "org.junit.Assert".equals(qualifiedName);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2012 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.
@@ -25,6 +25,7 @@ import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.ComparisonUtils;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -109,7 +110,7 @@ public class ComparisonToNaNInspection extends BaseInspection {
}
final PsiExpression lhs = expression.getLOperand();
final PsiExpression rhs = expression.getROperand();
if (rhs == null || !isFloatingPointType(lhs) && !isFloatingPointType(rhs)) {
if (rhs == null || !TypeUtils.hasFloatingPointType(lhs) && !TypeUtils.hasFloatingPointType(rhs)) {
return;
}
if (isNaN(lhs)) {
@@ -120,17 +121,6 @@ public class ComparisonToNaNInspection extends BaseInspection {
}
}
private static boolean isFloatingPointType(PsiExpression expression) {
if (expression == null) {
return false;
}
final PsiType type = expression.getType();
if (type == null) {
return false;
}
return PsiType.DOUBLE.equals(type) || PsiType.FLOAT.equals(type);
}
private static boolean isNaN(PsiExpression expression) {
if (!(expression instanceof PsiReferenceExpression)) {
return false;
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2007 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2012 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.
@@ -17,38 +17,34 @@ package com.siyeh.ig.numeric;
import com.intellij.psi.PsiBinaryExpression;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiType;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.ComparisonUtils;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.NotNull;
public class FloatingPointEqualityInspection extends BaseInspection {
@NotNull
public String getDisplayName() {
return InspectionGadgetsBundle.message(
"floating.point.equality.display.name");
return InspectionGadgetsBundle.message("floating.point.equality.display.name");
}
@NotNull
protected String buildErrorString(Object... infos) {
return InspectionGadgetsBundle.message(
"floating.point.equality.problem.descriptor");
return InspectionGadgetsBundle.message("floating.point.equality.problem.descriptor");
}
public BaseInspectionVisitor buildVisitor() {
return new FloatingPointEqualityComparisonVisitor();
}
private static class FloatingPointEqualityComparisonVisitor
extends BaseInspectionVisitor {
private static class FloatingPointEqualityComparisonVisitor extends BaseInspectionVisitor {
@Override
public void visitBinaryExpression(
@NotNull PsiBinaryExpression expression) {
public void visitBinaryExpression(@NotNull PsiBinaryExpression expression) {
super.visitBinaryExpression(expression);
final PsiExpression rhs = expression.getROperand();
if (rhs == null) {
@@ -58,8 +54,7 @@ public class FloatingPointEqualityInspection extends BaseInspection {
return;
}
final PsiExpression lhs = expression.getLOperand();
if (!isFloatingPointType(lhs) && !isFloatingPointType(rhs)) {
if (!TypeUtils.hasFloatingPointType(lhs) && !TypeUtils.hasFloatingPointType(rhs)) {
return;
}
if (ExpressionUtils.isZero(lhs) || ExpressionUtils.isZero(rhs)) {
@@ -67,16 +62,5 @@ public class FloatingPointEqualityInspection extends BaseInspection {
}
registerError(expression);
}
private static boolean isFloatingPointType(PsiExpression expression) {
if (expression == null) {
return false;
}
final PsiType type = expression.getType();
if (type == null) {
return false;
}
return PsiType.DOUBLE.equals(type) || PsiType.FLOAT.equals(type);
}
}
}
@@ -445,64 +445,56 @@ public class ImportUtils {
return false;
}
public static void addStaticImport(
@NotNull String qualifierClass, @NotNull String memberName,
@NotNull PsiElement context)
public static boolean addStaticImport(@NotNull String qualifierClass, @NotNull String memberName, @NotNull PsiElement context)
throws IncorrectOperationException {
final PsiClass containingClass =
PsiTreeUtil.getParentOfType(context, PsiClass.class);
if (!nameCanBeStaticallyImported(qualifierClass, memberName, context)) {
return false;
}
final PsiClass containingClass = PsiTreeUtil.getParentOfType(context, PsiClass.class);
if (InheritanceUtil.isInheritor(containingClass, qualifierClass)) {
return;
return true;
}
final PsiFile psiFile = context.getContainingFile();
if (!(psiFile instanceof PsiJavaFile)) {
return;
return false;
}
final PsiJavaFile javaFile = (PsiJavaFile)psiFile;
final PsiImportList importList = javaFile.getImportList();
if (importList == null) {
return;
return false;
}
final PsiImportStatementBase existingImportStatement =
importList.findSingleImportStatement(memberName);
final PsiImportStatementBase existingImportStatement = importList.findSingleImportStatement(memberName);
if (existingImportStatement != null) {
return;
return false;
}
final PsiImportStaticStatement onDemandImportStatement =
findOnDemandImportStaticStatement(importList, qualifierClass);
if (onDemandImportStatement != null &&
!hasOnDemandImportStaticConflict(qualifierClass, memberName,
context)) {
return;
final PsiImportStaticStatement onDemandImportStatement = findOnDemandImportStaticStatement(importList, qualifierClass);
if (onDemandImportStatement != null && !hasOnDemandImportStaticConflict(qualifierClass, memberName, context)) {
return true;
}
final Project project = context.getProject();
final GlobalSearchScope scope = context.getResolveScope();
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
final PsiClass aClass = psiFacade.findClass(qualifierClass, scope);
if (aClass == null) {
return;
return false;
}
final String qualifiedName = aClass.getQualifiedName();
if (qualifiedName == null) {
return;
return false;
}
final List<PsiImportStaticStatement> imports =
getMatchingImports(importList, qualifiedName);
final CodeStyleSettings codeStyleSettings =
CodeStyleSettingsManager.getSettings(project);
final List<PsiImportStaticStatement> imports = getMatchingImports(importList, qualifiedName);
final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project);
final PsiElementFactory elementFactory = psiFacade.getElementFactory();
if (imports.size() <
codeStyleSettings.NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND) {
importList.add(elementFactory.createImportStaticStatement(aClass,
memberName));
if (imports.size() < codeStyleSettings.NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND) {
importList.add(elementFactory.createImportStaticStatement(aClass, memberName));
}
else {
for (PsiImportStaticStatement importStatement : imports) {
importStatement.delete();
}
importList.add(
elementFactory.createImportStaticStatement(aClass, "*"));
importList.add(elementFactory.createImportStaticStatement(aClass, "*"));
}
return true;
}
private static PsiImportStaticStatement findOnDemandImportStaticStatement(
@@ -65,9 +65,7 @@ public class TypeUtils {
return typeEquals(CommonClassNames.JAVA_LANG_STRING, targetType);
}
public static boolean expressionHasTypeOrSubtype(
@Nullable PsiExpression expression,
@NonNls @NotNull String typeName) {
public static boolean expressionHasTypeOrSubtype(@Nullable PsiExpression expression, @NonNls @NotNull String typeName) {
if (expression == null) {
return false;
}
@@ -84,8 +82,7 @@ public class TypeUtils {
}
//getTypeIfOneOfOrSubtype
public static String expressionHasTypeOrSubtype(
@Nullable PsiExpression expression,
public static String expressionHasTypeOrSubtype(@Nullable PsiExpression expression,
@NonNls @NotNull String... typeNames) {
if (expression == null) {
return null;
@@ -110,9 +107,7 @@ public class TypeUtils {
return null;
}
public static boolean expressionHasTypeOrSubtype(
@Nullable PsiExpression expression,
@NonNls @NotNull Collection<String> typeNames) {
public static boolean expressionHasTypeOrSubtype(@Nullable PsiExpression expression, @NonNls @NotNull Collection<String> typeNames) {
if (expression == null) {
return false;
}
@@ -136,9 +131,7 @@ public class TypeUtils {
return false;
}
public static boolean variableHasTypeOrSubtype(
@Nullable PsiVariable variable,
@NonNls @NotNull String... typeNames) {
public static boolean variableHasTypeOrSubtype(@Nullable PsiVariable variable, @NonNls @NotNull String... typeNames) {
if (variable == null) {
return false;
}
@@ -158,4 +151,15 @@ public class TypeUtils {
}
return false;
}
public static boolean hasFloatingPointType(@Nullable PsiExpression expression) {
if (expression == null) {
return false;
}
final PsiType type = expression.getType();
if (type == null) {
return false;
}
return PsiType.FLOAT.equals(type) || PsiType.DOUBLE.equals(type);
}
}
@@ -0,0 +1,97 @@
package com.siyeh.igtest.controlflow.unnecessary_return;
import java.util.concurrent.Callable;
public class UnnecessaryReturn
{
public UnnecessaryReturn()
{
return;
}
public void foo()
{
return;
}
public void foo2()
{
{
{
return;
}
}
}
public void bar()
{
if(true)
{
return;
}
}
public void barzoom()
{
while(true)
{
return;
}
}
}
class C {
public C() {
return;
}
public void m1() {
return;
}
public boolean m2() {
return true;
}
public void m3(boolean f) {
if (!f) {
return;
}
System.out.println("m3()");
if (f) {
return;
}
}
public void m4(boolean f) {
if (f) {
System.out.println("m4()");
return;
}
else {
return;
}
}
public void m5() {
while (true) {
System.out.println("m5()");
return;
}
}
public void lambda() {
Runnable r = () -> { return; };
System.out.println(r);
Callable<Integer> c = () -> { return 42; };
System.out.println(c);
}
void m5(boolean a) {
if (a) return;
else {
System.out.println();
}
}
}

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