Merge remote-tracking branch 'origin/master'

This commit is contained in:
Kirill Likhodedov
2012-03-26 18:15:28 +04:00
104 changed files with 1559 additions and 344 deletions
@@ -0,0 +1,40 @@
/*
* 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.compiler;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.nio.charset.Charset;
import java.util.Collection;
/**
* @author nik
*/
public abstract class CompilerEncodingService {
public static CompilerEncodingService getInstance(@NotNull Project project) {
return ServiceManager.getService(project, CompilerEncodingService.class);
}
@Nullable
public abstract Charset getPreferredModuleEncoding(@NotNull Module module);
@NotNull
public abstract Collection<Charset> getAllModuleEncodings(@NotNull Module module);
}
@@ -0,0 +1,118 @@
/*
* 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.compiler.impl;
import com.intellij.compiler.CompilerEncodingService;
import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.encoding.EncodingProjectManager;
import com.intellij.openapi.vfs.encoding.EncodingProjectManagerImpl;
import com.intellij.psi.util.CachedValue;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
/**
* @author nik
*/
public class CompilerEncodingServiceImpl extends CompilerEncodingService {
@NotNull private final Project myProject;
private final CachedValue<Map<Module, Set<Charset>>> myModuleFileEncodings;
public CompilerEncodingServiceImpl(@NotNull Project project) {
myProject = project;
myModuleFileEncodings = CachedValuesManager.getManager(project).createCachedValue(new CachedValueProvider<Map<Module, Set<Charset>>>() {
@Override
public Result<Map<Module, Set<Charset>>> compute() {
Map<Module, Set<Charset>> result = computeModuleCharsetMap();
return Result.create(result, ProjectRootManager.getInstance(myProject),
((EncodingProjectManagerImpl)EncodingProjectManager.getInstance(myProject)).getModificationTracker());
}
}, false);
}
private Map<Module, Set<Charset>> computeModuleCharsetMap() {
final Map<Module, Set<Charset>> map = new THashMap<Module, Set<Charset>>();
final Map<VirtualFile, Charset> mappings = EncodingProjectManager.getInstance(myProject).getAllMappings();
ProjectFileIndex index = ProjectRootManager.getInstance(myProject).getFileIndex();
final CompilerManager compilerManager = CompilerManager.getInstance(myProject);
for (Map.Entry<VirtualFile, Charset> entry : mappings.entrySet()) {
final VirtualFile file = entry.getKey();
final Charset charset = entry.getValue();
if (file == null || charset == null || !compilerManager.isCompilableFileType(file.getFileType())
|| !index.isInSourceContent(file)) continue;
final Module module = index.getModuleForFile(file);
if (module == null) continue;
Set<Charset> set = map.get(module);
if (set == null) {
set = new LinkedHashSet<Charset>();
map.put(module, set);
final VirtualFile sourceRoot = index.getSourceRootForFile(file);
VirtualFile current = file.getParent();
Charset parentCharset = null;
while (current != null) {
final Charset currentCharset = mappings.get(current);
if (currentCharset != null) {
parentCharset = currentCharset;
}
if (current.equals(sourceRoot)) {
break;
}
current = current.getParent();
}
if (parentCharset != null) {
set.add(parentCharset);
}
}
set.add(charset);
}
return map;
}
@Override
@Nullable
public Charset getPreferredModuleEncoding(@NotNull Module module) {
final Set<Charset> encodings = myModuleFileEncodings.getValue().get(module);
return ContainerUtil.getFirstItem(encodings, EncodingProjectManager.getInstance(myProject).getDefaultCharset());
}
@NotNull
@Override
public Collection<Charset> getAllModuleEncodings(@NotNull Module module) {
final Set<Charset> encodings = myModuleFileEncodings.getValue().get(module);
if (encodings != null) {
return encodings;
}
return ContainerUtil.createMaybeSingletonList(EncodingProjectManager.getInstance(myProject).getDefaultCharset());
}
}
@@ -24,6 +24,7 @@ import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ModuleRootModel;
import com.intellij.openapi.util.Pair;
import com.intellij.util.Chunk;
import com.intellij.util.containers.ContainerUtil;
@@ -106,15 +107,16 @@ public final class ModuleCompilerUtil {
}
}
public static GraphGenerator<ModifiableRootModel> createGraphGenerator(final Map<Module, ModifiableRootModel> models) {
return GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<ModifiableRootModel>() {
public Collection<ModifiableRootModel> getNodes() {
public static <T extends ModuleRootModel> GraphGenerator<T> createGraphGenerator(final Map<Module, T> models) {
return GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<T>() {
public Collection<T> getNodes() {
return models.values();
}
public Iterator<ModifiableRootModel> getIn(final ModifiableRootModel model) {
public Iterator<T> getIn(final ModuleRootModel model) {
final Module[] modules = model.getModuleDependencies();
final List<ModifiableRootModel> dependencies = new ArrayList<ModifiableRootModel>();
final List<T> dependencies = new ArrayList<T>();
for (Module module : modules) {
dependencies.add(models.get(module));
}
@@ -162,7 +164,7 @@ public final class ModuleCompilerUtil {
return null;
}
public static Collection<Chunk<ModifiableRootModel>> buildChunks(final Map<Module, ModifiableRootModel> models) {
public static <T extends ModuleRootModel> Collection<Chunk<T>> buildChunks(final Map<Module, T> models) {
return toChunkGraph(createGraphGenerator(models)).getNodes();
}
}
@@ -42,4 +42,6 @@ public interface ProjectFromSourcesBuilder {
@NotNull
WizardContext getContext();
boolean hasRootsFromOtherDetectors(ProjectStructureDetector thisDetector);
}
@@ -32,6 +32,7 @@ import com.intellij.ide.util.projectWizard.importSources.ProjectStructureDetecto
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.module.*;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
@@ -262,6 +263,15 @@ public class ProjectFromSourcesBuilderImpl extends ProjectBuilder implements Pro
myUpdaters.add(updater);
}
public boolean hasRootsFromOtherDetectors(ProjectStructureDetector thisDetector) {
for (ProjectStructureDetector projectStructureDetector : Extensions.getExtensions(ProjectStructureDetector.EP_NAME)) {
if (projectStructureDetector != thisDetector && !getProjectRoots(projectStructureDetector).isEmpty()) {
return true;
}
}
return false;
}
@NotNull
private static Module createModule(ProjectDescriptor projectDescriptor, final ModuleDescriptor descriptor,
final Map<LibraryDescriptor, Library> projectLibs, final ModifiableModuleModel moduleModel)
@@ -18,16 +18,15 @@ package com.intellij.openapi.roots.ui.configuration;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.wm.impl.content.GraphicsConfig;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.components.JBList;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.components.labels.LinkLabel;
import com.intellij.ui.components.labels.LinkListener;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.BaseButtonBehavior;
import com.intellij.util.ui.TimedDeadzone;
@@ -45,6 +44,7 @@ import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.RoundRectangle2D;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
@@ -52,6 +52,7 @@ import java.util.List;
* User: spLeaner
*/
public class ConfigurationErrorsComponent extends JPanel implements Disposable, ListDataListener {
private static final int MAX_ERRORS_TO_SHOW = SystemInfo.getIntProperty("idea.project.structure.max.errors.to.show", 100);
private static final boolean ONE_LINE = true;
private static final boolean MULTI_LINE = false;
@@ -95,7 +96,7 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable,
private void ensureCurrentViewIs(final boolean oneLine, @Nullable final Object data) {
if (oneLine) {
if (myCurrentView instanceof OneLineErrorComponent) return;
myConfigurationErrorsListModel.setFilter(null);
myConfigurationErrorsListModel.setFilter(true, true);
OneLineErrorComponent c = new OneLineErrorComponent(myConfigurationErrorsListModel) {
@Override
public void onViewChange(Object data) {
@@ -109,14 +110,9 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable,
}
myCurrentView = c;
} else {
Condition<ConfigurationError> filter = data == null ? null : new Condition<ConfigurationError>() {
@Override
public boolean value(ConfigurationError error) {
return data == null ? true : "Ignored".equals(data) ? error.isIgnored() : !error.isIgnored();
}
};
myConfigurationErrorsListModel.setFilter(filter);
}
else {
myConfigurationErrorsListModel.setFilter(data == null || !"Ignored".equals(data), data == null || "Ignored".equals(data));
if (myCurrentView instanceof MultiLineErrorComponent) return;
MultiLineErrorComponent c = new MultiLineErrorComponent(myConfigurationErrorsListModel) {
@Override
@@ -568,13 +564,13 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable,
if (errors.size() == 1) {
mySingleErrorLabel.setText(myModel.getErrors().get(0).getPlainTextTitle());
} else {
myErrorsLabel.setText(String.format("%s errors found", errors.size()));
myErrorsLabel.setText(String.format("%s errors found", getErrorsCount(errors.size())));
}
}
final List<ConfigurationError> ignoredErrors = myModel.getIgnoredErrors();
if (ignoredErrors.size() > 0) {
myIgnoredErrorsLabel.setText(String.format("%s ignored error%s", ignoredErrors.size(), ignoredErrors.size() == 1 ? "" : "s"));
myIgnoredErrorsLabel.setText(String.format("%s ignored error%s", getErrorsCount(ignoredErrors.size()), ignoredErrors.size() == 1 ? "" : "s"));
}
removeAll();
@@ -595,6 +591,10 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable,
repaint();
}
private static String getErrorsCount(final int size) {
return size < MAX_ERRORS_TO_SHOW ? String.valueOf(size) : MAX_ERRORS_TO_SHOW + "+";
}
private JComponent wrapLabel(@NotNull final JLabel label, @NotNull final ConfigurationError configurationError) {
final JPanel result = new JPanel(new BorderLayout());
result.setBackground(label.getBackground());
@@ -653,7 +653,9 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable,
public void onClick(MouseEvent e) {
final Object o = myModel.getElementAt(0);
if (o instanceof ConfigurationError) {
((ConfigurationError)o).ignore(!((ConfigurationError)o).isIgnored());
final ConfigurationError error = (ConfigurationError)o;
error.ignore(!error.isIgnored());
myModel.update(error);
updateView();
}
}
@@ -678,72 +680,92 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable,
}
}
//todo[nik] move to ContainerUtil after 11.1
@NotNull
private static <T> List<T> concat(@NotNull final List<? extends T> list1, @NotNull final List<? extends T> list2) {
return new AbstractList<T>() {
public T get(int index) {
if (index < list1.size()) {
return list1.get(index);
}
return list2.get(index - list1.size());
}
public int size() {
return list1.size() + list2.size();
}
};
}
private static class ConfigurationErrorsListModel extends AbstractListModel implements ConfigurationErrors, Disposable {
private MessageBusConnection myConnection;
private List<ConfigurationError> myErrorsList = new ArrayList<ConfigurationError>();
private Condition<ConfigurationError> myFilter;
private List<ConfigurationError> myNotIgnoredErrors = new ArrayList<ConfigurationError>();
private List<ConfigurationError> myAllErrors;
private List<ConfigurationError> myIgnoredErrors = new ArrayList<ConfigurationError>();
private ConfigurationErrorsListModel(@NotNull final Project project) {
setFilter(true, true);
myConnection = project.getMessageBus().connect();
myConnection.subscribe(TOPIC, this);
}
public void setFilter(Condition<ConfigurationError> filter) {
myFilter = filter;
public void setFilter(boolean showNotIgnored, boolean showIgnored) {
if (showIgnored && showNotIgnored) {
myAllErrors = concat(myNotIgnoredErrors, myIgnoredErrors);
}
else if (showIgnored) {
myAllErrors = myIgnoredErrors;
}
else {
myAllErrors = myNotIgnoredErrors;
}
}
@Override
public int getSize() {
return myFilter == null ? myErrorsList.size() : ContainerUtil.filter(myErrorsList, myFilter).size();
return Math.min(myAllErrors.size(), MAX_ERRORS_TO_SHOW);
}
@Override
public Object getElementAt(int index) {
return myFilter == null ? myErrorsList.get(index) : ContainerUtil.filter(myErrorsList, myFilter).get(index);
return myAllErrors.get(index);
}
private boolean accept(ConfigurationError error) {
return myFilter == null || myFilter.value(error);
}
@Override
public void addError(@NotNull ConfigurationError error) {
if (!myErrorsList.contains(error) && accept(error)) {
int ndx = 0;
if (error.isIgnored()) {
ndx = myErrorsList.size();
if (!myAllErrors.contains(error)) {
List<ConfigurationError> targetList = error.isIgnored() ? myIgnoredErrors : myNotIgnoredErrors;
if (targetList.size() < MAX_ERRORS_TO_SHOW) {
targetList.add(0, error);
}
else {
targetList.add(error);
}
myErrorsList.add(ndx, error);
fireIntervalAdded(this, ndx, ndx);
int i = myAllErrors.indexOf(error);
if (i != -1 && i < MAX_ERRORS_TO_SHOW) {
fireIntervalAdded(this, i, i);
}
}
}
@Override
public void removeError(@NotNull ConfigurationError error) {
if (myErrorsList.contains(error)) {
final int ndx = myErrorsList.indexOf(error);
myErrorsList.remove(ndx);
fireIntervalRemoved(this, ndx, ndx);
final int i = myAllErrors.indexOf(error);
myIgnoredErrors.remove(error);
myNotIgnoredErrors.remove(error);
if (i != -1 && i < MAX_ERRORS_TO_SHOW) {
fireIntervalRemoved(this, i, i);
}
}
public List<ConfigurationError> getErrors() {
return ContainerUtil.filter(myErrorsList, new Condition<ConfigurationError>() {
@Override
public boolean value(final ConfigurationError error) {
return !error.isIgnored();
}
});
return myNotIgnoredErrors;
}
public List<ConfigurationError> getIgnoredErrors() {
return ContainerUtil.filter(myErrorsList, new Condition<ConfigurationError>() {
@Override
public boolean value(final ConfigurationError error) {
return error.isIgnored();
}
});
return myIgnoredErrors;
}
@Override
@@ -755,9 +777,30 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable,
}
public void update(final ConfigurationError error) {
final int ndx = myErrorsList.indexOf(error);
if (ndx >= 0) {
fireContentsChanged(this, ndx, ndx);
final int i0 = myAllErrors.indexOf(error);
if (error.isIgnored()) {
if (myNotIgnoredErrors.remove(error)) {
myIgnoredErrors.add(0, error);
}
}
else {
if (myIgnoredErrors.remove(error)) {
myNotIgnoredErrors.add(0, error);
}
}
final int i1 = myAllErrors.indexOf(error);
if (i0 == i1 && i0 != -1) {
if (i0 < MAX_ERRORS_TO_SHOW) {
fireContentsChanged(this, i0, i0);
}
}
else {
if (i0 != -1 && i0 < MAX_ERRORS_TO_SHOW) {
fireIntervalRemoved(this, i0, i0);
}
if (i1 != -1 && i1 < MAX_ERRORS_TO_SHOW) {
fireIntervalAdded(this, i1, i1);
}
}
}
}
@@ -18,7 +18,7 @@ package com.intellij.openapi.roots.ui.configuration;
import com.intellij.compiler.ModuleCompilerUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootModel;
import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext;
import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.*;
import com.intellij.openapi.util.text.StringUtil;
@@ -49,14 +49,13 @@ public class GeneralProjectSettingsElement extends ProjectStructureElement {
@Override
public void check(ProjectStructureProblemsHolder problemsHolder) {
final Graph<Chunk<ModifiableRootModel>> graph = ModuleCompilerUtil.toChunkGraph(
myContext.getModulesConfigurator().createGraphGenerator());
final Collection<Chunk<ModifiableRootModel>> chunks = graph.getNodes();
final Graph<Chunk<ModuleRootModel>> graph = ModuleCompilerUtil.toChunkGraph(myContext.getModulesConfigurator().createGraphGenerator());
final Collection<Chunk<ModuleRootModel>> chunks = graph.getNodes();
List<String> cycles = new ArrayList<String>();
for (Chunk<ModifiableRootModel> chunk : chunks) {
final Set<ModifiableRootModel> modules = chunk.getNodes();
for (Chunk<ModuleRootModel> chunk : chunks) {
final Set<ModuleRootModel> modules = chunk.getNodes();
List<String> names = new ArrayList<String>();
for (ModifiableRootModel model : modules) {
for (ModuleRootModel model : modules) {
names.add(model.getModule().getName());
}
if (modules.size() > 1) {
@@ -213,10 +213,10 @@ public class ModulesConfigurator implements ModulesProvider, ModuleEditor.Change
myAllModulesChangeListeners.add(listener);
}
public GraphGenerator<ModifiableRootModel> createGraphGenerator() {
final Map<Module, ModifiableRootModel> models = new HashMap<Module, ModifiableRootModel>();
public GraphGenerator<ModuleRootModel> createGraphGenerator() {
final Map<Module, ModuleRootModel> models = new HashMap<Module, ModuleRootModel>();
for (ModuleEditor moduleEditor : myModuleEditors) {
models.put(moduleEditor.getModule(), moduleEditor.getModifiableRootModel());
models.put(moduleEditor.getModule(), moduleEditor.getRootModel());
}
return ModuleCompilerUtil.createGraphGenerator(models);
}
@@ -770,10 +770,16 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple
return null;
}
};
Collection<AnAction> actionsFromExtensions = new ArrayList<AnAction>();
for (final ModuleStructureExtension extension : ModuleStructureExtension.EP_NAME.getExtensions()) {
result.addAll(extension.createAddActions(selectedNodeRetriever, TREE_UPDATER, myProject, myRoot));
actionsFromExtensions.addAll(extension.createAddActions(selectedNodeRetriever, TREE_UPDATER, myProject, myRoot));
}
if (!actionsFromExtensions.isEmpty() && !result.isEmpty()) {
result.add(new Separator());
}
result.addAll(actionsFromExtensions);
return result.toArray(new AnAction[result.size()]);
}
};
@@ -26,6 +26,7 @@ import com.intellij.codeInspection.*;
import com.intellij.codeInspection.ex.BaseLocalInspectionTool;
import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.util.text.StringUtil;
@@ -60,6 +61,8 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
@Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_SETTER_PARAMETER = true;
@Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS = true; // remains for test
@SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD = true;
private static final Logger LOG = Logger.getInstance("#" + NullableStuffInspection.class.getName());
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
@@ -144,10 +147,10 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
final PsiParameter[] parameters = setter.getParameterList().getParameters();
assert parameters.length == 1 : setter.getText();
final PsiParameter parameter = parameters[0];
assert parameter != null : setter.getText();
LOG.assertTrue(parameter != null, setter.getText());
if (REPORT_NOT_ANNOTATED_GETTER && !AnnotationUtil.isAnnotated(parameter, manager.getAllAnnotations()) && !TypeConversionUtil.isPrimitiveAndNotNull(parameter.getType())) {
final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier();
assert nameIdentifier1 != null : parameter;
assertValidElement(setter, parameter, nameIdentifier1);
holder.registerProblem(nameIdentifier1,
InspectionsBundle.message("inspection.nullable.problems.annotated.field.setter.parameter.not.annotated",
StringUtil.getShortName(anno)),
@@ -157,7 +160,7 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
if (PropertyUtils.isSimpleSetter(setter)) {
if (annotated.isDeclaredNotNull && manager.isNullable(parameter, false)) {
final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier();
assert nameIdentifier1 != null : parameter;
assertValidElement(setter, parameter, nameIdentifier1);
holder.registerProblem(nameIdentifier1, InspectionsBundle.message(
"inspection.nullable.problems.annotated.field.setter.parameter.conflict",
StringUtil.getShortName(anno), nullableSimpleName),
@@ -166,7 +169,7 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
}
else if (annotated.isDeclaredNullable && manager.isNotNull(parameter, false)) {
final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier();
assert nameIdentifier1 != null : parameter;
assertValidElement(setter, parameter, nameIdentifier1);
holder.registerProblem(nameIdentifier1, InspectionsBundle.message(
"inspection.nullable.problems.annotated.field.setter.parameter.conflict", StringUtil.getShortName(anno), notNullSimpleName),
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
@@ -241,6 +244,11 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
}
}
private void assertValidElement(PsiMethod setter, PsiParameter parameter, PsiIdentifier nameIdentifier1) {
LOG.assertTrue(nameIdentifier1 != null, setter.getText());
LOG.assertTrue(parameter.isPhysical(), setter.getText());
}
public PsiAssignmentExpression getAssignmentExpressionIfOnAssignmentLefthand(PsiExpression expression) {
PsiElement parent = PsiTreeUtil.skipParentsOfType(expression, PsiParenthesizedExpression.class);
if (!(parent instanceof PsiAssignmentExpression)) {
@@ -20,11 +20,11 @@ import com.intellij.codeInsight.completion.InsertionContext;
import com.intellij.codeInsight.completion.JavaLookupElementBuilder;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiTypesUtil;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -35,9 +35,9 @@ import java.util.List;
* @author Konstantin Bulenkov
*/
public class JavaLangClassMemberReference extends PsiReferenceBase<PsiLiteralExpression> implements InsertHandler<LookupElement> {
private final PsiClassObjectAccessExpression myContext;
private final PsiExpression myContext;
public JavaLangClassMemberReference(PsiLiteralExpression literal, PsiClassObjectAccessExpression context) {
public JavaLangClassMemberReference(PsiLiteralExpression literal, PsiExpression context) {
super(literal);
myContext = context;
}
@@ -67,7 +67,26 @@ public class JavaLangClassMemberReference extends PsiReferenceBase<PsiLiteralExp
@Nullable
private PsiClass getPsiClass() {
return PsiTypesUtil.getPsiClass(myContext.getOperand().getType());
if (myContext instanceof PsiClassObjectAccessExpression) {
return PsiTypesUtil.getPsiClass(((PsiClassObjectAccessExpression)myContext).getOperand().getType());
} else if (myContext instanceof PsiMethodCallExpression) {
final PsiMethod method = ((PsiMethodCallExpression)myContext).resolveMethod();
if (method != null && "forName".equals(method.getName()) && isClass(method.getContainingClass())) {
final PsiExpression[] expressions = ((PsiMethodCallExpression)myContext).getArgumentList().getExpressions();
if (expressions.length == 1 && expressions[0] instanceof PsiLiteralExpression) {
final Object value = ((PsiLiteralExpression)expressions[0]).getValue();
if (value instanceof String) {
final Project project = myContext.getProject();
return JavaPsiFacade.getInstance(project).findClass(String.valueOf(value), GlobalSearchScope.allScope(project));
}
}
}
}
return null;
}
private static boolean isClass(PsiClass aClass) {
return aClass != null && CommonClassNames.JAVA_LANG_CLASS.equals(aClass.getQualifiedName());
}
@Nullable
@@ -33,8 +33,8 @@ public class JavaReflectionReferenceProvider extends PsiReferenceProvider {
final PsiElement expressionList;
if (value != null && (expressionList = element.getParent()) instanceof PsiExpressionList) {
final PsiElement methodCall = expressionList.getParent();
final PsiClassObjectAccessExpression classAccess;
if (methodCall != null && (classAccess = PsiTreeUtil.findChildOfType(methodCall, PsiClassObjectAccessExpression.class)) != null) {
final PsiExpression classAccess;
if (methodCall != null && (classAccess = getContext(methodCall)) != null) {
return new PsiReference[]{new JavaLangClassMemberReference((PsiLiteralExpression)element, classAccess)};
}
}
@@ -42,6 +42,12 @@ public class JavaReflectionReferenceProvider extends PsiReferenceProvider {
return PsiReference.EMPTY_ARRAY;
}
@Nullable
private static PsiExpression getContext(PsiElement methodCall) {
final PsiClassObjectAccessExpression expression = PsiTreeUtil.findChildOfType(methodCall, PsiClassObjectAccessExpression.class);
return expression == null ? PsiTreeUtil.findChildOfType(methodCall, PsiMethodCallExpression.class) : expression;
}
@Nullable
private static String getValue(PsiLiteralExpression element) {
final Object value = element.getValue();
@@ -74,6 +74,10 @@ public class JavaMoveDirectoryWithClassesHelper extends MoveDirectoryWithClasses
if (!(file instanceof PsiClassOwner)) {
return false;
}
if (!JspPsiUtil.isInJspFile(file)) {
return false;
}
for (PsiClass psiClass : ((PsiClassOwner)file).getClasses()) {
final PsiClass newClass = MoveClassesOrPackagesUtil.doMoveClass(psiClass, moveDestination);
@@ -0,0 +1,37 @@
/*
* 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.psi;
import com.intellij.openapi.extensions.ExtensionPointName;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Evgeny Gerashchenko
* @since 3/20/12
*/
public interface ClsFileDecompiledPsiFileProvider {
ExtensionPointName<ClsFileDecompiledPsiFileProvider> EP_NAME = ExtensionPointName.create("com.intellij.psi.clsDecompiledFileProvider");
/**
* Returns decompiled PSI associated with this classfile
*
* @param clsFile instance of ClsFile
* @return decompiled PSI file
*/
@Nullable
PsiFile getDecompiledPsiFile(@NotNull PsiJavaFile clsFile);
}
-1
View File
@@ -12,7 +12,6 @@
<orderEntry type="module" module-name="resources-en" />
<orderEntry type="library" name="Guava" level="project" />
<orderEntry type="library" name="asm" level="project" />
<orderEntry type="module" module-name="platform-api" />
</component>
</module>
@@ -26,8 +26,6 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileTypes.ContentBasedClassFileProcessor;
import com.intellij.openapi.fileTypes.ContentBasedFileSubstitutor;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.progress.NonCancelableSection;
import com.intellij.openapi.progress.ProgressIndicatorProvider;
@@ -327,12 +325,10 @@ public class ClsFileImpl extends ClsRepositoryPsiElement<PsiClassHolderFileStub>
@Override
public PsiFile getDecompiledPsiFile() {
for (ContentBasedFileSubstitutor processor : Extensions.getExtensions(ContentBasedFileSubstitutor.EP_NAME)) {
if (processor instanceof ContentBasedClassFileProcessor && processor.isApplicable(getProject(), getVirtualFile())) {
PsiFile decompiledPsiFile = ((ContentBasedClassFileProcessor)processor).getDecompiledPsiFile(this);
if (decompiledPsiFile != null) {
return decompiledPsiFile;
}
for (ClsFileDecompiledPsiFileProvider provider : Extensions.getExtensions(ClsFileDecompiledPsiFileProvider.EP_NAME)) {
PsiFile decompiledPsiFile = provider.getDecompiledPsiFile(this);
if (decompiledPsiFile != null) {
return decompiledPsiFile;
}
}
return (PsiFile) getMirror();
@@ -0,0 +1,26 @@
/*
* 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.
*/
class ForNameDeclaredField {
void foo() {
Class.forName("Test").getDeclaredField("<caret>");
}
}
class Test {
public int num;
public int num2;
int num3;
}
@@ -0,0 +1,26 @@
/*
* 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.
*/
class ForNameDeclaredField {
void foo() {
Class.forName("Test").getDeclaredField("num3");
}
}
class Test {
public int num;
public int num2;
int num3;
}
@@ -0,0 +1,30 @@
/*
* 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.
*/
class ForNameDeclaredMethod {
void foo() {
Class.forName("Test").getDeclaredMethod("<caret>");
}
}
class Test {
public void method(){}
public void method2(A a, B b){}
void method3(){}
}
class A {}
class B {}
class C {}
@@ -0,0 +1,30 @@
/*
* 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.
*/
class ForNameDeclaredMethod {
void foo() {
Class.forName("Test").getDeclaredMethod("method2", A.class, B.class);
}
}
class Test {
public void method(){}
public void method2(A a, B b){}
void method3(){}
}
class A {}
class B {}
class C {}
@@ -0,0 +1,26 @@
/*
* 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.
*/
class ForNameField {
void foo() {
Class.forName("Test").getField("<caret>");
}
}
class Test {
public int num;
public int num2;
int num3;
}
@@ -0,0 +1,26 @@
/*
* 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.
*/
class ForNameField {
void foo() {
Class.forName("Test").getField("num2");
}
}
class Test {
public int num;
public int num2;
int num3;
}
@@ -0,0 +1,30 @@
/*
* 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.
*/
class ForNameMethod {
void foo() {
Class.forName("Test").getMethod("<caret>");
}
}
class Test {
public void method(){}
public void method2(A a, B b){}
void method3(){}
}
class A {}
class B {}
class C {}
@@ -0,0 +1,30 @@
/*
* 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.
*/
class ForNameMethod {
void foo() {
Class.forName("Test").getMethod("method2", A.class, B.class);
}
}
class Test {
public void method(){}
public void method2(A a, B b){}
void method3(){}
}
class A {}
class B {}
class C {}
@@ -1240,4 +1240,16 @@ class Foo {{
assert myFixture.lookupElementStrings.containsAll(['too', 'command.toString'])
}
public void testUnfinishedString() {
myFixture.configureByText 'a.java', '''
// Date
class Foo {
String s = "<caret>
String s2 = s;
}
'''
type 'D'
assert !lookup
}
}
@@ -52,6 +52,21 @@ public class JavaReflectionCompletionTest extends LightFixtureCompletionTestCase
doTest(1, "method", "method2");
}
public void testForNameDeclaredMethod() throws Exception {
doTest(1, "method", "method2", "method3");
}
public void testForNameMethod() throws Exception {
doTest(1, "method", "method2");
}
public void testForNameField() throws Exception {
doTest(1, "num", "num2");
}
public void testForNameDeclaredField() throws Exception {
doTest(2, "num", "num2", "num3");
}
private void doTest(int index, String... expected) {
configureByFile(getTestName(false) + ".java");
@@ -65,7 +65,7 @@ public abstract class IntervalTreeImpl<T extends MutableInterval> extends RedBla
private final IntervalTreeImpl<E> myIntervalTree;
public IntervalNode(IntervalTreeImpl<E> intervalTree, @NotNull E key, int start, int end) {
public IntervalNode(@NotNull IntervalTreeImpl<E> intervalTree, @NotNull E key, int start, int end) {
// maxEnd == 0 so to not disrupt existing maxes
myIntervalTree = intervalTree;
myStart = start;
@@ -28,7 +28,7 @@ public class RangeMarkerImpl extends UserDataHolderBase implements RangeMarkerEx
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.RangeMarkerImpl");
protected final DocumentEx myDocument;
protected RangeMarkerTree<RangeMarkerEx>.RMNode myNode;
protected RangeMarkerTree.RMNode<RangeMarkerEx> myNode;
private final long myId;
private static final StripedIDGenerator counter = new StripedIDGenerator();
@@ -91,7 +91,7 @@ public class RangeMarkerImpl extends UserDataHolderBase implements RangeMarkerEx
public void invalidate(final DocumentEvent e) {
setValid(false);
RangeMarkerTree<RangeMarkerEx>.RMNode node = myNode;
RangeMarkerTree.RMNode<RangeMarkerEx> node = myNode;
if (node != null) {
node.processAliveKeys(new Processor<RangeMarkerEx>() {
@@ -88,10 +88,10 @@ public class RangeMarkerTree<T extends RangeMarkerEx> extends IntervalTreeImpl<T
private static final int DUPLICATE_LIMIT = 30; // assertion: no more than DUPLICATE_LIMIT range markers are allowed to be registered at given (start, end)
@Override
public RangeMarkerTree<T>.RMNode addInterval(@NotNull T interval, int start, int end, boolean greedyToLeft, boolean greedyToRight, int layer) {
public RMNode<T> addInterval(@NotNull T interval, int start, int end, boolean greedyToLeft, boolean greedyToRight, int layer) {
RangeMarkerImpl marker = (RangeMarkerImpl)interval;
marker.setValid(true);
RangeMarkerTree<T>.RMNode node = (RMNode)super.addInterval(interval, start, end, greedyToLeft, greedyToRight, layer);
RMNode<T> node = (RMNode)super.addInterval(interval, start, end, greedyToLeft, greedyToRight, layer);
if (DEBUG && node.intervals.size() > DUPLICATE_LIMIT) {
l.readLock().lock();
@@ -113,7 +113,7 @@ public class RangeMarkerTree<T extends RangeMarkerEx> extends IntervalTreeImpl<T
}
return node;
}
private String errMsg(RMNode node) {
private String errMsg(RMNode<T> node) {
@NonNls final StringBuilder msg = new StringBuilder();
final AtomicInteger alive = new AtomicInteger();
node.processAliveKeys(new Processor<Object>() {
@@ -135,8 +135,8 @@ public class RangeMarkerTree<T extends RangeMarkerEx> extends IntervalTreeImpl<T
@NotNull
@Override
protected RMNode createNewNode(@NotNull T key, int start, int end, boolean greedyToLeft, boolean greedyToRight, int layer) {
return new RMNode(key, start, end, greedyToLeft, greedyToRight);
protected RMNode<T> createNewNode(@NotNull T key, int start, int end, boolean greedyToLeft, boolean greedyToRight, int layer) {
return new RMNode<T>(this, key, start, end, greedyToLeft, greedyToRight);
}
@Override
@@ -146,21 +146,26 @@ public class RangeMarkerTree<T extends RangeMarkerEx> extends IntervalTreeImpl<T
}
@Override
protected RangeMarkerTree<T>.RMNode lookupNode(@NotNull T key) {
return (RMNode)((RangeMarkerImpl)key).myNode;
protected RMNode<T> lookupNode(@NotNull T key) {
return (RMNode<T>)((RangeMarkerImpl)key).myNode;
}
@Override
protected void setNode(@NotNull T key, IntervalNode<T> intervalNode) {
((RangeMarkerImpl)key).myNode = (RangeMarkerTree.RMNode)intervalNode;
((RangeMarkerImpl)key).myNode = (RMNode)intervalNode;
}
public class RMNode extends IntervalTreeImpl.IntervalNode<T> {
static class RMNode<T extends RangeMarkerEx> extends IntervalTreeImpl.IntervalNode<T> {
private final boolean isExpandToLeft;
private final boolean isExpandToRight;
public RMNode(@NotNull T key, int start, int end, boolean greedyToLeft, boolean greedyToRight) {
super(RangeMarkerTree.this, key, start, end);
public RMNode(@NotNull RangeMarkerTree<T> rangeMarkerTree,
@NotNull T key,
int start,
int end,
boolean greedyToLeft,
boolean greedyToRight) {
super(rangeMarkerTree, key, start, end);
isExpandToLeft = greedyToLeft;
isExpandToRight = greedyToRight;
}
@@ -227,7 +232,7 @@ public class RangeMarkerTree<T extends RangeMarkerEx> extends IntervalTreeImpl<T
if (marker == null) continue; // node remains removed from the tree
marker.documentChanged(e);
if (marker.isValid()) {
RMNode insertedNode = (RMNode)findOrInsert(node);
RMNode<T> insertedNode = (RMNode)findOrInsert(node);
// can change if two range become the one
if (insertedNode != node) {
// merge happened
@@ -17,10 +17,11 @@ package com.intellij.codeInsight.completion;
import com.intellij.lang.LanguageParserDefinitions;
import com.intellij.lang.ParserDefinition;
import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiErrorElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.util.ThreeState;
import org.jetbrains.annotations.NotNull;
@@ -42,13 +43,26 @@ public class SkipAutopopupInStrings extends CompletionConfidence {
if (contextElement != null) {
ParserDefinition definition = LanguageParserDefinitions.INSTANCE.forLanguage(PsiUtilBase.getLanguageAtOffset(psiFile, offset));
if (definition != null) {
ElementPattern<PsiElement> pattern = PlatformPatterns.psiElement().withElementType(definition.getStringLiteralElements());
if (pattern.accepts(contextElement) || pattern.accepts(contextElement.getParent())) {
if (isStringLiteral(contextElement, definition) || isStringLiteral(contextElement.getParent(), definition)) {
return ThreeState.YES;
}
if (offset > 0) {
PsiElement prev = psiFile.findElementAt(offset - 1);
if (prev != null && (isStringLiteralWithError(prev, definition) || isStringLiteralWithError(prev.getParent(), definition))) {
return ThreeState.YES;
}
}
}
}
return ThreeState.UNSURE;
}
private static boolean isStringLiteral(PsiElement element, ParserDefinition definition) {
return PlatformPatterns.psiElement().withElementType(definition.getStringLiteralElements()).accepts(element);
}
private static boolean isStringLiteralWithError(PsiElement element, ParserDefinition definition) {
return isStringLiteral(element, definition) && PsiTreeUtil.nextLeaf(element) instanceof PsiErrorElement;
}
}
@@ -172,10 +172,6 @@ public interface ModifiableRootModel extends ModuleRootModel {
void setExcludeExplodedDirectory(boolean excludeExplodedDir);
@NotNull Module[] getModuleDependencies();
@NotNull Module[] getModuleDependencies(boolean includeTests);
boolean isWritable();
void setRootUrls(OrderRootType orderRootType, String[] urls);
@@ -193,4 +193,10 @@ public interface ModuleRootModel {
@NotNull String[] getRootUrls(OrderRootType rootType);
<T> T getModuleExtension(Class<T> klass);
@NotNull
Module[] getModuleDependencies();
@NotNull
Module[] getModuleDependencies(boolean includeTests);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* 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.
@@ -33,6 +33,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actions.EditorActionUtil;
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
@@ -82,7 +83,14 @@ public class TargetElementUtilBase {
@Nullable
public static PsiReference findReference(Editor editor) {
return findReference(editor, editor.getCaretModel().getOffset());
PsiReference result = findReference(editor, editor.getCaretModel().getOffset());
if (result == null) {
final Integer offset = editor.getUserData(EditorActionUtil.EXPECTED_CARET_OFFSET);
if (offset != null) {
result = findReference(editor, offset);
}
}
return result;
}
@Nullable
@@ -124,7 +132,15 @@ public class TargetElementUtilBase {
public static PsiElement findTargetElement(Editor editor, int flags) {
ApplicationManager.getApplication().assertIsDispatchThread();
return getInstance().findTargetElement(editor, flags, editor.getCaretModel().getOffset());
final PsiElement result = getInstance().findTargetElement(editor, flags, editor.getCaretModel().getOffset());
if (result != null) {
return result;
}
final Integer offset = editor.getUserData(EditorActionUtil.EXPECTED_CARET_OFFSET);
if (offset != null) {
return getInstance().findTargetElement(editor, flags, offset);
}
return result;
}
public static boolean inVirtualSpace(Editor editor, int offset) {
@@ -87,7 +87,11 @@ public class ProblemDescriptorImpl extends CommonProblemDescriptorImpl implement
assertPhysical(startElement);
if (startElement != endElement) assertPhysical(endElement);
if (startElement.getTextRange().getStartOffset() >= endElement.getTextRange().getEndOffset()) {
final TextRange startElementRange = startElement.getTextRange();
LOG.assertTrue(startElementRange != null, startElement);
final TextRange endElementRange = endElement.getTextRange();
LOG.assertTrue(endElementRange != null, endElement);
if (startElementRange.getStartOffset() >= endElementRange.getEndOffset()) {
if (!(startElement instanceof PsiFile && endElement instanceof PsiFile)) {
LOG.error("Empty PSI elements should not be passed to createDescriptor. Start: " + startElement + ", end: " + endElement);
}
@@ -141,7 +141,11 @@ public class InspectionResultsViewComparator implements Comparator {
private static int compareEntity(final RefEntity entity, final PsiElement element) {
if (entity instanceof RefElement) {
return PsiUtilCore.compareElementsByPosition(((RefElement)entity).getElement(), element);
final PsiElement psiElement = ((RefElement)entity).getElement();
if (psiElement != null && element != null) {
return PsiUtilCore.compareElementsByPosition(psiElement, element);
}
if (element == null) return psiElement == null ? 0 : 1;
}
if (element instanceof PsiQualifiedNamedElement) {
return StringUtil.compare(entity.getQualifiedName(), ((PsiQualifiedNamedElement)element).getQualifiedName(), true);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* 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.
@@ -26,6 +26,7 @@ import com.intellij.ide.IdeBundle;
import com.intellij.ide.dnd.FileCopyPasteUtil;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actions.EditorActionUtil;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.markup.TextAttributes;
@@ -109,7 +110,7 @@ public class CopyReferenceAction extends AnAction {
private static PsiElement getElementToCopy(final Editor editor, final DataContext dataContext) {
PsiElement element = null;
if (editor != null) {
PsiReference reference = TargetElementUtilBase.findReference(editor, editor.getCaretModel().getOffset());
PsiReference reference = TargetElementUtilBase.findReference(editor);
if (reference != null) {
element = reference.getElement();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* 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.
@@ -22,6 +22,7 @@ import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx;
@@ -55,6 +56,7 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.*;
import java.util.*;
@@ -351,4 +353,9 @@ public class FileTemplateUtil{
CreateFromTemplateHandler handler = findHandler(template);
return handler.canCreate(dirs);
}
@Nullable
public static Icon getIcon(@NotNull FileTemplate fileTemplate) {
return FileTypeManager.getInstance().getFileTypeByExtension(fileTemplate.getExtension()).getIcon();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* 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.
@@ -17,10 +17,10 @@
package com.intellij.ide.fileTemplates.actions;
import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.ide.fileTemplates.FileTemplateUtil;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDirectory;
import org.jetbrains.annotations.Nullable;
@@ -30,7 +30,7 @@ public class CreateFromTemplateAction extends CreateFromTemplateActionBase {
private final FileTemplate myTemplate;
public CreateFromTemplateAction(FileTemplate template){
super(template.getName(), null, FileTypeManagerEx.getInstanceEx().getFileTypeByExtension(template.getExtension()).getIcon());
super(template.getName(), null, FileTemplateUtil.getIcon(template));
myTemplate = template;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* 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.
@@ -17,7 +17,7 @@
package com.intellij.ide.fileTemplates.impl;
import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.ide.fileTemplates.FileTemplateUtil;
import com.intellij.ui.components.JBList;
import org.jetbrains.annotations.NotNull;
@@ -52,7 +52,7 @@ abstract class FileTemplateTabAsList extends FileTemplateTab {
Icon icon = null;
if (value instanceof FileTemplate) {
FileTemplate template = (FileTemplate) value;
icon = FileTypeManager.getInstance().getFileTypeByExtension(template.getExtension()).getIcon();
icon = FileTemplateUtil.getIcon(template);
final boolean internalTemplate = AllFileTemplatesConfigurable.isInternalTemplate(template.getName(), getTitle());
if (internalTemplate) {
setFont(getFont().deriveFont(Font.BOLD));
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* 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.
@@ -16,10 +16,11 @@
package com.intellij.ide.fileTemplates.ui;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.ide.fileTemplates.FileTemplateManager;
import com.intellij.ide.fileTemplates.FileTemplateUtil;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.ui.ListCellRendererWrapper;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.FixedSizeButton;
@@ -80,6 +81,15 @@ public class SelectTemplateDialog extends DialogWrapper{
}
if(myCbxTemplates == null){
myCbxTemplates = new JComboBox(model);
myCbxTemplates.setRenderer(new ListCellRendererWrapper<FileTemplate>(myCbxTemplates.getRenderer()) {
@Override
public void customize(JList list, FileTemplate fileTemplate, int index, boolean selected, boolean hasFocus) {
if (fileTemplate != null) {
setIcon(FileTemplateUtil.getIcon(fileTemplate));
setText(fileTemplate.getName());
}
}
});
}
else{
Object selected = myCbxTemplates.getSelectedItem();
@@ -267,6 +267,18 @@ public class ModuleRootManagerImpl extends ModuleRootManager implements ModuleCo
return myRootModel.getModuleDependencies(includeTests);
}
@NotNull
@Override
public Module[] getModuleDependencies() {
return myRootModel.getModuleDependencies();
}
@NotNull
@Override
public Module[] getModuleDependencies(boolean includeTests) {
return myRootModel.getModuleDependencies(includeTests);
}
public boolean isDependsOn(Module module) {
return myRootModel.isDependsOn(module);
}
@@ -16,6 +16,7 @@
package com.intellij.openapi.vcs.checkin;
import com.intellij.openapi.components.StorageScheme;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ex.ProjectEx;
import com.intellij.openapi.roots.ProjectFileIndex;
@@ -70,6 +71,10 @@ public class BeforeCheckinHandlerUtil {
private static boolean isFileUnderSourceRoot(@NotNull Project project, @NotNull VirtualFile file) {
ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex();
return index.isInSource(file) && !index.isInLibrarySource(file);
if (StdFileTypes.JAVA == file.getFileType()) {
return index.isInSource(file) && !index.isInLibrarySource(file);
} else {
return index.isInContent(file) && !index.isInLibrarySource(file) ;
}
}
}
@@ -31,6 +31,7 @@ import com.intellij.openapi.progress.util.ProgressIndicatorBase;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.ex.ProgressIndicatorEx;
import com.intellij.pom.PomManager;
@@ -407,6 +408,12 @@ public class DocumentCommitThread implements Runnable, Disposable {
catch (Exception e) {
s += e;
}
try {
Disposer.dispose(project);
}
catch (Throwable ignored) {
// do not fill log with endless exceptions
}
throw new RuntimeException(s);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* 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.
@@ -25,8 +25,12 @@ import java.util.EventListener;
* @see EditorMouseMotionListener
*/
public interface EditorMouseListener extends EventListener {
/**
* Called when a mouse button is pressed over the editor.
* <p/>
* <b>Note:</b> this callback is assumed to be at the very start of 'mouse press' processing, i.e. common actions
* like 'caret position change', 'selection change' etc implied by the 'mouse press' have not been performed yet.
*
* @param e the event containing information about the mouse press.
*/
@@ -34,13 +34,4 @@ public interface ContentBasedClassFileProcessor extends ContentBasedFileSubstitu
*/
@NotNull
SyntaxHighlighter createHighlighter(Project project, VirtualFile vFile);
/**
* Returns decompiled PSI associated with this classfile
*
* @param clsFile instance of ClsFile
* @return decompiled PSI file
*/
@Nullable
PsiFile getDecompiledPsiFile(PsiFile clsFile);
}
@@ -34,7 +34,7 @@ public class NonFocusableCheckBox extends JCheckBox {
}
private void initFocusability() {
if (!UISettings.getInstance().DISABLE_MNEMONICS_IN_CONTROLS) { // Or that won't be keyboard accessible at all
if (!UISettings.getShadowInstance().DISABLE_MNEMONICS_IN_CONTROLS) { // Or that won't be keyboard accessible at all
setFocusable(false);
}
}
@@ -53,7 +53,7 @@ public class DialogUtil{
}
if (mnemonic != '\0') {
button.setText(realText.toString());
if (UISettings.getInstance().DISABLE_MNEMONICS_IN_CONTROLS) {
if (UISettings.getShadowInstance().DISABLE_MNEMONICS_IN_CONTROLS) {
button.setMnemonic(0);
button.setDisplayedMnemonicIndex(-1);
button.setFocusable(true);
@@ -93,7 +93,7 @@ public class DialogUtil{
}
if (mnemonic != '\0') {
label.setText(realText.toString());
if (UISettings.getInstance().DISABLE_MNEMONICS_IN_CONTROLS) {
if (UISettings.getShadowInstance().DISABLE_MNEMONICS_IN_CONTROLS) {
label.setDisplayedMnemonic(0);
label.setDisplayedMnemonicIndex(-1);
}
@@ -15,7 +15,10 @@
*/
package com.intellij.help.impl;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.impl.IdeFocusManagerHeadless;
import com.intellij.ui.AppUIUtil;
import com.intellij.util.Alarm;
import org.jetbrains.annotations.NotNull;
import javax.help.*;
@@ -207,6 +210,9 @@ class IdeaHelpBroker extends DefaultHelpBroker implements KeyListener{
//myFrame.setLocationRelativeTo(null);
myFrame.setVisible(visible);
myFrame.setState(JFrame.NORMAL);
IdeFocusManager focusManager = IdeFocusManager.findInstance();
JComponent target = focusManager.getFocusTargetFor(myFrame.getRootPane());
focusManager.requestFocus(target != null ? target : myFrame, true);
}
}
@@ -671,8 +677,9 @@ class IdeaHelpBroker extends DefaultHelpBroker implements KeyListener{
if(myDialog.isShowing()){
myDialog.hide();
}
if(myOwnerWindow!=null)
if (myOwnerWindow != null) {
myOwnerWindow.removeWindowListener(dl);
}
myOwnerWindow=null;
modalDeactivated=true;
}
@@ -694,22 +701,24 @@ class IdeaHelpBroker extends DefaultHelpBroker implements KeyListener{
}
}
} else{
if(myFrame==null){
myFrame=new JFrame(helpTitle);
if (myFrame == null) {
myFrame = new JFrame(helpTitle);
resize = true;
AppUIUtil.updateFrameIcon(myFrame);
WindowListener l=new WindowAdapter(){
public void windowClosing(WindowEvent e){
WindowListener l = new WindowAdapter() {
public void windowClosing(WindowEvent e) {
myFrame.setVisible(false);
}
public void windowClosed(WindowEvent e){
public void windowClosed(WindowEvent e) {
myFrame.setVisible(false);
}
};
myFrame.addWindowListener(l);
} else
}
else {
pos = myFrame.getLocation();
}
if(myDialog!=null){
pos=myDialog.getLocation();
size=myDialog.getSize();
@@ -33,6 +33,7 @@ import com.intellij.openapi.actionSystem.ActionPopupMenu;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.event.EditorMouseEvent;
import com.intellij.openapi.editor.event.EditorMouseEventArea;
import com.intellij.openapi.editor.event.EditorMouseListener;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.editor.impl.EditorImpl;
@@ -49,6 +50,21 @@ import java.awt.event.MouseEvent;
import java.util.List;
public class EditorActionUtil {
/**
* Editor actions may be invoked multiple ways - programmatically, via keyboard/mouse shortcut, main/context menu etc.
* Action processing may also interfere with standard editor behavior (caret position change, selection change etc).
* <p/>
* E.g. consider a situation when context menu is shown on right mouse click -
* {@link EditorMouseListener#mousePressed(EditorMouseEvent) the contract says} that no common actions have been performed yet.
* However, some actions may operate on an 'active element' (an element under caret), hence, they would incorrectly because the
* caret position has not been changed yet.
* <p/>
* We address that problem by providing a special key that is intended to hold 'expected caret offset', i.e. offset where we
* expect the caret to be located at the near future.
*/
public static final Key<Integer> EXPECTED_CARET_OFFSET = Key.create("expectedEditorOffset");
protected static final Object EDIT_COMMAND_GROUP = Key.create("EditGroup");
public static final Object DELETE_COMMAND_GROUP = Key.create("DeleteGroup");
@@ -110,7 +110,7 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
DocumentBulkUpdateListener bulkUpdateListener = new DocumentBulkUpdateListener() {
@Override
public void updateStarted(@NotNull Document doc) {
if (doc != myEditor.getDocument() && myOffset >= doc.getTextLength()) return;
if (doc != myEditor.getDocument() && myOffset >= doc.getTextLength() || savedBeforeBulkCaretMarker != null) return;
savedBeforeBulkCaretMarker = doc.createRangeMarker(myOffset, myOffset);
}
@Override
@@ -237,7 +237,7 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
}
public void setIgnoreWrongMoves(boolean ignoreWrongMoves) {
this.myIgnoreWrongMoves = ignoreWrongMoves;
myIgnoreWrongMoves = ignoreWrongMoves;
}
@Override
@@ -695,9 +695,8 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
moveToOffset(newLength, performSoftWrapAdjustment);
}
else {
final int line;
try {
line = event.translateLineViaDiff(myLogicalCaret.line);
final int line = event.translateLineViaDiff(myLogicalCaret.line);
moveToLogicalPosition(new LogicalPosition(line, myLogicalCaret.column), performSoftWrapAdjustment, null, false);
}
catch (FilesTooBigForDiffException e1) {
@@ -41,6 +41,7 @@ import com.intellij.openapi.command.UndoConfirmationPolicy;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.actionSystem.*;
import com.intellij.openapi.editor.actions.EditorActionUtil;
import com.intellij.openapi.editor.colors.*;
import com.intellij.openapi.editor.colors.impl.DelegateColorScheme;
import com.intellij.openapi.editor.event.*;
@@ -5078,6 +5079,10 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
TooltipController.getInstance().cancelTooltip(FOLDING_TOOLTIP_GROUP, e, true);
}
private void runMousePressedCommand(@NotNull final MouseEvent e) {
final int clickOffset = logicalPositionToOffset(xyToLogicalPosition(e.getPoint()));
putUserData(EditorActionUtil.EXPECTED_CARET_OFFSET, clickOffset);
mySelectionTweaked = false;
myMousePressedEvent = e;
EditorMouseEvent event = new EditorMouseEvent(EditorImpl.this, e, getMouseEventArea(e));
@@ -44,19 +44,20 @@ public class RangeHighlighterTree extends RangeMarkerTree<RangeHighlighterEx> {
@NotNull
@Override
protected RHNode createNewNode(@NotNull RangeHighlighterEx key, int start, int end, boolean greedyToLeft, boolean greedyToRight, int layer) {
return new RHNode(key, start, end, greedyToLeft, greedyToRight,layer);
return new RHNode(this, key, start, end, greedyToLeft, greedyToRight,layer);
}
class RHNode extends RangeMarkerTree<RangeHighlighterEx>.RMNode {
static class RHNode extends RMNode<RangeHighlighterEx> {
final int myLayer;
public RHNode(@NotNull final RangeHighlighterEx key,
public RHNode(@NotNull RangeHighlighterTree rangeMarkerTree,
@NotNull final RangeHighlighterEx key,
int start,
int end,
boolean greedyToLeft,
boolean greedyToRight,
int layer) {
super(key, start, end, greedyToLeft, greedyToRight);
super(rangeMarkerTree, key, start, end, greedyToLeft, greedyToRight);
myLayer = layer;
}
@@ -36,6 +36,7 @@ import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.ModificationTracker;
import com.intellij.openapi.vfs.*;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
@@ -65,6 +66,13 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager {
private boolean myUseUTFGuessing = true;
private boolean myNative2AsciiForPropertiesFiles;
private Charset myDefaultCharsetForPropertiesFiles;
private long myModificationCount;
private final ModificationTracker myModificationTracker = new ModificationTracker() {
@Override
public long getModificationCount() {
return myModificationCount;
}
};
public EncodingProjectManagerImpl(Project project, GeneralSettings generalSettings, EditorSettingsExternalizable editorSettings, PsiDocumentManager documentManager) {
myProject = project;
@@ -138,6 +146,7 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager {
myEditorSettings.migrateCharsetSettingsTo(defaultManager);
}
}
myModificationCount++;
}
@Override
@@ -180,6 +189,10 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager {
return null;
}
public ModificationTracker getModificationTracker() {
return myModificationTracker;
}
@Override
public void setEncoding(@Nullable VirtualFile virtualFileOrDir, @Nullable Charset charset) {
if (charset == null) {
@@ -188,6 +201,7 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager {
else {
myMapping.put(virtualFileOrDir, charset);
}
myModificationCount++;
setAndSaveOrReload(virtualFileOrDir, charset);
}
@@ -252,6 +266,7 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager {
}
}
}
myModificationCount++;
}
//retrieves encoding for the Project node
@@ -532,6 +532,8 @@
<extensionPoint name="psi.clsCustomNavigationPolicy"
interface="com.intellij.psi.impl.compiled.ClsCustomNavigationPolicy" />
<extensionPoint name="psi.clsDecompiledFileProvider"
interface="com.intellij.psi.ClsFileDecompiledPsiFileProvider"/>
<extensionPoint name="codeBlockProvider"
beanClass="com.intellij.lang.LanguageExtensionPoint"/>
@@ -264,8 +264,8 @@ public class NameUtil {
continue;
}
answer.add(compoundSuggestion(prefix, upperCaseStyle, words, wordCount, startWord, c, isArray, true) + suffix);
answer.add(compoundSuggestion(prefix, upperCaseStyle, words, wordCount, startWord, c, isArray, false) + suffix);
answer.add(compoundSuggestion(prefix, upperCaseStyle, words, wordCount, startWord, c, isArray, true) + suffix);
}
return answer;
}
@@ -222,6 +222,9 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
if (fileSize > 5 * megabyte) { // file is longer than 5MB and (more than 50% of keys is garbage or approximate benefit larger than 100M)
int liveKeys = (int)(myLiveAndGarbageKeysCounter / LIVE_KEY_MASK);
int deadKeys = (int)(myLiveAndGarbageKeysCounter & 0xFFFFFFFF);
if (deadKeys < 50) return false;
final int benefitSize = 100 * megabyte;
final long avgValueSize = fileSize / (liveKeys + deadKeys);
@@ -64,4 +64,6 @@ public interface CommittedChangesProvider<T extends CommittedChangeList, U exten
*/
@Nullable
Pair<T, FilePath> getOneList(final VirtualFile file, final VcsRevisionNumber number) throws VcsException;
RepositoryLocation getForNonLocal(final VirtualFile file);
}
@@ -34,6 +34,8 @@ import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* @author irengrig
* Date: 3/16/11
@@ -60,6 +62,7 @@ public class ShowAllAffectedGenericAction extends AnAction {
public static void showSubmittedFiles(final Project project, final VcsRevisionNumber revision, final VirtualFile virtualFile, final VcsKey vcsKey) {
final AbstractVcs vcs = ProjectLevelVcsManager.getInstance(project).findVcsByName(vcsKey.getName());
if (vcs == null) return;
if (! isInLocalFSHack(virtualFile) && ! canPresentNonLocal(project, vcsKey, virtualFile)) return;
final String title = VcsBundle.message("paths.affected.in.revision",
revision instanceof ShortVcsRevisionNumber
@@ -71,9 +74,20 @@ public class ShowAllAffectedGenericAction extends AnAction {
@Override
public void run(@NotNull ProgressIndicator indicator) {
try {
final Pair<CommittedChangeList, FilePath> pair = vcs.getCommittedChangesProvider().getOneList(virtualFile, revision);
if (pair != null) {
list[0] = pair.getFirst();
final CommittedChangesProvider provider = vcs.getCommittedChangesProvider();
if (isInLocalFSHack(virtualFile)) {
final Pair<CommittedChangeList, FilePath> pair = provider.getOneList(virtualFile, revision);
if (pair != null) {
list[0] = pair.getFirst();
}
} else {
final RepositoryLocation local = provider.getForNonLocal(virtualFile);
if (local != null) {
final List<CommittedChangeList> changes = provider.getCommittedChanges(provider.createDefaultSettings(), local, 1);
if (changes != null && changes.size() == 1) {
list[0] = changes.get(0);
}
}
}
}
catch (VcsException e) {
@@ -95,6 +109,12 @@ public class ShowAllAffectedGenericAction extends AnAction {
});
}
private static boolean isInLocalFSHack(final VirtualFile vf) {
if (vf.isInLocalFileSystem()) return true;
final String url = vf.getPresentableUrl();
return ! url.contains("://") && ! url.contains(":\\\\");
}
private static String failedText(VirtualFile virtualFile, VcsRevisionNumber revision) {
return "Show all affected files for " + virtualFile.getPath() + " at " + revision.asString() + " failed";
}
@@ -108,6 +128,16 @@ public class ShowAllAffectedGenericAction extends AnAction {
return;
}
final VirtualFile revisionVirtualFile = e.getData(VcsDataKeys.VCS_VIRTUAL_FILE);
e.getPresentation().setEnabled((e.getData(VcsDataKeys.VCS_FILE_REVISION) != null) && (revisionVirtualFile != null));
boolean enabled = (e.getData(VcsDataKeys.VCS_FILE_REVISION) != null) && (revisionVirtualFile != null);
enabled = enabled && (isInLocalFSHack(revisionVirtualFile) || canPresentNonLocal(project, vcsKey, revisionVirtualFile));
e.getPresentation().setEnabled(enabled);
}
private static boolean canPresentNonLocal(Project project, VcsKey key, final VirtualFile file) {
final AbstractVcs vcs = ProjectLevelVcsManager.getInstance(project).findVcsByName(key.getName());
if (vcs == null) return false;
final CommittedChangesProvider provider = vcs.getCommittedChangesProvider();
if (provider == null) return false;
return provider.getForNonLocal(file) != null;
}
}
@@ -161,6 +161,11 @@ public class CompositeCommittedChangesProvider implements CommittedChangesProvid
throw new UnsupportedOperationException();
}
@Override
public RepositoryLocation getForNonLocal(VirtualFile file) {
throw new UnsupportedOperationException();
}
public static class CompositeChangeBrowserSettings extends ChangeBrowserSettings {
private final Map<AbstractVcs, ChangeBrowserSettings> myMap;
private final Set<AbstractVcs> myEnabledVcs = new HashSet<AbstractVcs>();
@@ -299,6 +299,7 @@ public abstract class ChangesTreeList<T> extends JPanel {
}
});
final Set<Object> wasSelected = new HashSet<Object>(Arrays.asList(myList.getSelectedValues()));
myList.setModel(new AbstractListModel() {
@Override
public int getSize() {
@@ -310,6 +311,12 @@ public abstract class ChangesTreeList<T> extends JPanel {
return sortedChanges.get(index);
}
});
for (int i = 0; i < sortedChanges.size(); i++) {
T t = sortedChanges.get(i);
if (wasSelected.contains(t)) {
myList.setSelectedIndex(i);
}
}
final DefaultTreeModel model = buildTreeModel(changes, myChangeDecorator);
TreeState state = null;
@@ -642,6 +642,7 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton {
VcsHistoryUtil.showDiff(project, myFilePath, left, right, leftTitle, rightTitle);
}
catch (final VcsException e) {
LOG.info(e);
WaitForProgressToShow.runOrInvokeLaterAboveProgress(new Runnable() {
public void run() {
Messages.showErrorDialog(VcsBundle.message("message.text.cannot.show.differences", e.getLocalizedMessage()),
@@ -650,7 +651,7 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton {
}, null, project);
}
catch (IOException e) {
LOG.error(e);
LOG.info(e);
}
catch (ProcessCanceledException ex) {
LOG.info(ex);
@@ -92,7 +92,6 @@ public class XFramesView extends XDebugViewBase {
CustomLineBorder border = new CustomLineBorder(CaptionPanel.CNT_ACTIVE_COLOR, 0, 0, 1, 0);
myThreadsPanel.setBorder(border);
myThreadsPanel.add(myToolbar.getComponent(), BorderLayout.EAST);
myThreadsPanel.add(myThreadComboBox, BorderLayout.CENTER);
myMainPanel.add(myThreadsPanel, BorderLayout.NORTH);
rebuildView(SessionEvent.RESUMED);
@@ -155,12 +154,10 @@ public class XFramesView extends XDebugViewBase {
}
XExecutionStack activeExecutionStack = suspendContext.getActiveExecutionStack();
myThreadComboBox.setSelectedItem(activeExecutionStack);
final boolean invisible = executionStacks.length == 1 && StringUtil.isEmpty(executionStacks[0].getDisplayName());
myThreadsPanel.removeAll();
if (invisible) {
myThreadsPanel.add(myToolbar.getComponent(), BorderLayout.WEST);
} else {
myThreadsPanel.add(myToolbar.getComponent(), BorderLayout.EAST);
myThreadsPanel.add(myToolbar.getComponent(), BorderLayout.EAST);
final boolean invisible = executionStacks.length == 1 && StringUtil.isEmpty(executionStacks[0].getDisplayName());
if (!invisible) {
myThreadsPanel.add(myThreadComboBox, BorderLayout.CENTER);
}
myToolbar.setAddSeparatorFirst(!invisible);
@@ -1,5 +1,5 @@
/*
* Copyright 2006-2011 Bas Leijdekkers
* Copyright 2006-201@ Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -73,6 +73,10 @@ public class UnqualifiedFieldAccessInspection extends BaseInspection {
if (field.hasModifierProperty(PsiModifier.STATIC)) {
return;
}
final PsiClass containingClass = field.getContainingClass();
if (containingClass instanceof PsiAnonymousClass) {
return;
}
registerError(expression);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2006-2011 Bas Leijdekkers
* Copyright 2006-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.
@@ -68,6 +68,10 @@ public class UnqualifiedMethodAccessInspection extends BaseInspection {
if (method.isConstructor() || method.hasModifierProperty(PsiModifier.STATIC)) {
return;
}
final PsiClass containingClass = method.getContainingClass();
if (containingClass instanceof PsiAnonymousClass) {
return;
}
registerError(expression);
}
}
@@ -9,4 +9,17 @@ public class UnqualifiedFieldAccess {
final String s = String.valueOf(field.hashCode());
System.out.println(s);
}
void foo() {
new Object() {
int i;
void foo() {
new Object() {
void foo() {
i = 0;
}
};
}
};
}
}
@@ -15,4 +15,16 @@ public class UnqualifiedMethodAccess extends JPanel {
void foo(String s) {
this.foo();
}
void anonymous() {
new Object() {
void bar() {
new Object() {
void foo() {
bar();
}
};
}
};
}
}
@@ -24,6 +24,7 @@
<orderEntry type="module" module-name="ui-designer-new" />
<orderEntry type="module" module-name="dom-impl" />
<orderEntry type="module" module-name="dom-openapi" />
<orderEntry type="module" module-name="xml" />
</component>
</module>
@@ -40,6 +40,7 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiErrorElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.xml.XmlFile;
@@ -56,7 +57,6 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.List;
/**
@@ -137,6 +137,8 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel {
parser.updateRootComponent(mySession, rootView);
RadViewComponent newRootComponent = parser.getRootComponent();
newRootComponent.setClientProperty(ModelParser.XML_FILE_KEY, myXmlFile);
PropertyParser propertyParser = new PropertyParser(myModule, myProfileAction.getProfileManager().getSelectedTarget());
newRootComponent.setClientProperty(PropertyParser.KEY, propertyParser);
propertyParser.loadRecursive(newRootComponent);
@@ -158,7 +160,10 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel {
final String layoutXmlText = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
@Override
public String compute() {
return myXmlFile.getText();
if (ModelParser.checkTag(myXmlFile.getRootTag())) {
return myXmlFile.getText();
}
return ModelParser.NO_ROOT_CONTENT;
}
});
createRenderer(layoutXmlText, new ThrowableRunnable<Throwable>() {
@@ -387,27 +392,4 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel {
myPSIChangeListener.start();
}
}
private static class RootView extends JComponent {
private int myX;
private int myY;
private BufferedImage myImage;
public RootView(BufferedImage image, int x, int y) {
myX = x;
myY = y;
setImage(image);
}
public void setImage(BufferedImage image) {
myImage = image;
setBounds(myX, myY, image.getWidth(), image.getHeight());
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(myImage, 0, 0, null);
}
}
}
@@ -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.android.designer.designSurface;
import com.intellij.android.designer.model.ModelParser;
import com.intellij.android.designer.model.RadViewComponent;
import com.intellij.designer.designSurface.EditOperation;
import com.intellij.designer.designSurface.FeedbackLayer;
import com.intellij.designer.designSurface.OperationContext;
import com.intellij.designer.designSurface.feedbacks.AlphaComponent;
import com.intellij.designer.model.RadComponent;
import javax.swing.*;
import java.awt.*;
import java.util.Collections;
import java.util.List;
/**
* @author Alexander Lobas
*/
public class DropToOperation implements EditOperation {
private final RadViewComponent myContainer;
private final OperationContext myContext;
private List<RadComponent> myComponents;
private JComponent myFeedback;
public DropToOperation(RadViewComponent container, OperationContext context) {
myContainer = container;
myContext = context;
}
@Override
public void setComponent(RadComponent component) {
myComponents = Collections.singletonList(component);
}
@Override
public void setComponents(List<RadComponent> components) {
myComponents = components;
}
@Override
public void showFeedback() {
FeedbackLayer layer = myContext.getArea().getFeedbackLayer();
if (myFeedback == null) {
myFeedback = new AlphaComponent(Color.green);
layer.add(myFeedback);
myFeedback.setBounds(myContainer.getBounds(layer));
layer.repaint();
}
}
@Override
public void eraseFeedback() {
if (myFeedback != null) {
FeedbackLayer layer = myContext.getArea().getFeedbackLayer();
layer.remove(myFeedback);
layer.repaint();
myFeedback = null;
}
}
@Override
public boolean canExecute() {
return true;
}
@Override
public void execute() throws Exception {
for (RadComponent component : myComponents) {
ModelParser.addComponent(myContainer, (RadViewComponent)component, null);
}
}
}
@@ -0,0 +1,75 @@
/*
* 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.android.designer.designSurface;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
/**
* @author Alexander Lobas
*/
public class RootView extends JComponent {
private int myX;
private int myY;
private BufferedImage myImage;
private List<EmptyRegion> myEmptyRegions;
public RootView(BufferedImage image, int x, int y) {
myX = x;
myY = y;
setImage(image);
}
public void setImage(BufferedImage image) {
myImage = image;
myEmptyRegions = new ArrayList<EmptyRegion>();
setBounds(myX, myY, image.getWidth(), image.getHeight());
}
public void addEmptyRegion(int x, int y, int width, int height) {
if (new Rectangle(0, 0, myImage.getWidth(), myImage.getHeight()).contains(x, y)) {
EmptyRegion r = new EmptyRegion();
r.myX = x;
r.myY = y;
r.myWidth = width;
r.myHeight = height;
r.myColor = new Color(~myImage.getRGB(x, y));
myEmptyRegions.add(r);
}
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(myImage, 0, 0, null);
for (EmptyRegion r : myEmptyRegions) {
g.setColor(r.myColor);
g.fillRect(r.myX, r.myY, r.myWidth, r.myHeight);
}
}
private static class EmptyRegion {
public Color myColor;
public int myX;
public int myY;
public int myWidth;
public int myHeight;
}
}
@@ -0,0 +1,36 @@
/*
* 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.android.designer.designSurface;
import com.intellij.android.designer.model.ModelParser;
import com.intellij.android.designer.model.RadViewComponent;
import com.intellij.designer.componentTree.TreeEditOperation;
import com.intellij.designer.designSurface.OperationContext;
import com.intellij.designer.model.RadComponent;
/**
* @author Alexander Lobas
*/
public class TreeDropToOperation extends TreeEditOperation {
public TreeDropToOperation(RadComponent host, OperationContext context) {
super(host, context);
}
@Override
protected void execute(RadComponent insertBefore) throws Exception {
ModelParser.addComponent((RadViewComponent)myHost, (RadViewComponent)myComponents.get(0), (RadViewComponent)insertBefore);
}
}
@@ -17,6 +17,7 @@ package com.intellij.android.designer.model;
import com.android.ide.common.rendering.api.RenderSession;
import com.android.ide.common.rendering.api.ViewInfo;
import com.intellij.android.designer.designSurface.RootView;
import com.intellij.designer.model.MetaManager;
import com.intellij.designer.model.MetaModel;
import com.intellij.designer.model.RadComponent;
@@ -26,10 +27,14 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiErrorElement;
import com.intellij.psi.XmlElementFactory;
import com.intellij.psi.XmlRecursiveElementVisitor;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.xml.util.XmlUtil;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.List;
@@ -38,6 +43,13 @@ import java.util.List;
* @author Alexander Lobas
*/
public class ModelParser extends XmlRecursiveElementVisitor {
public static final String NO_ROOT_CONTENT =
"<?xml version=\"1.0\" encoding=\"utf-8\"?><LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\" android:layout_width=\"fill_parent\" android:layout_height=\"fill_parent\" android:orientation=\"vertical\"></LinearLayout>";
public static final String XML_FILE_KEY = "XML_FILE";
private static final int EMPTY_COMPONENT_SIZE = 5;
private final MetaManager myMetaManager;
private final XmlFile myXmlFile;
private RadViewComponent myRootComponent;
@@ -61,11 +73,11 @@ public class ModelParser extends XmlRecursiveElementVisitor {
@Override
public String compute() {
XmlTag root = myXmlFile.getRootTag();
if (root != null) {
if (checkTag(root)) {
root.accept(ModelParser.this);
return myXmlFile.getText();
}
return myXmlFile.getText();
return NO_ROOT_CONTENT;
}
});
}
@@ -111,19 +123,58 @@ public class ModelParser extends XmlRecursiveElementVisitor {
return component;
}
public static void addComponent(RadViewComponent container, RadViewComponent newComponent, @Nullable RadViewComponent insertBefore)
throws Exception {
newComponent.setParent(container);
List<RadComponent> children = container.getChildren();
if (insertBefore == null) {
children.add(newComponent);
}
else {
children.add(children.indexOf(insertBefore), newComponent);
}
setComponentTag(container.getTag(), newComponent, insertBefore == null ? null : insertBefore.getTag());
PropertyParser propertyParser = container.getRoot().getClientProperty(PropertyParser.KEY);
propertyParser.load(newComponent);
}
public static void setComponentTag(final XmlTag parentTag, final RadViewComponent component, final XmlTag nextTag) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
Language language = StdFileTypes.XML.getLanguage();
XmlTag xmlTag =
XmlElementFactory.getInstance(parentTag.getProject()).createTagFromText(component.getMetaModel().getCreation(), language);
Project project;
RadViewComponent root = null;
XmlFile xmlFile = null;
if (nextTag == null) {
xmlTag = parentTag.addSubTag(xmlTag, false);
if (!checkTag(parentTag) && component.getParent() == component.getRoot()) {
root = (RadViewComponent)component.getParent();
xmlFile = root.getClientProperty(XML_FILE_KEY);
project = xmlFile.getProject();
}
else {
xmlTag = (XmlTag)parentTag.addBefore(xmlTag, nextTag);
project = parentTag.getProject();
}
Language language = StdFileTypes.XML.getLanguage();
XmlTag xmlTag =
XmlElementFactory.getInstance(project).createTagFromText("\n" + component.getMetaModel().getCreation(), language);
if (checkTag(parentTag)) {
if (nextTag == null) {
xmlTag = parentTag.addSubTag(xmlTag, false);
}
else {
xmlTag = (XmlTag)parentTag.addBefore(xmlTag, nextTag);
}
}
else {
xmlTag.setAttribute("xmlns:android", "http://schemas.android.com/apk/res/android");
xmlTag = (XmlTag)xmlFile.getDocument().add(xmlTag);
root.setTag(xmlFile.getDocument().getRootTag());
XmlUtil.expandTag(xmlTag);
}
component.setTag(xmlTag);
@@ -131,6 +182,15 @@ public class ModelParser extends XmlRecursiveElementVisitor {
});
}
public static boolean checkTag(XmlTag tag) {
try {
return tag != null && tag.getFirstChild() != null && !(tag.getFirstChild() instanceof PsiErrorElement) && tag.getProject() != null;
}
catch (Throwable e) {
return false;
}
}
//////////////////////////////////////////////////////////////////////////////////////////
//
//
@@ -145,27 +205,26 @@ public class ModelParser extends XmlRecursiveElementVisitor {
return myLayoutXmlText;
}
public void updateRootComponent(RenderSession session, JComponent nativeComponent) throws Exception {
RadViewComponent rootComponent = myRootComponent;
if (session.getRootViews().size() == 1) {
RadViewComponent newRootComponent = createComponent(myXmlFile.getRootTag(), myMetaManager.getModelByTag("<root>"));
rootComponent.setParent(newRootComponent);
newRootComponent.getChildren().add(rootComponent);
myRootComponent = rootComponent = newRootComponent;
public void updateRootComponent(RenderSession session, RootView nativeComponent) throws Exception {
if (myRootComponent == null) {
myRootComponent = createComponent(myXmlFile.getRootTag(), myMetaManager.getModelByTag("<root>"));
}
else if (session.getRootViews().size() == 1) {
RadViewComponent rootComponent = myRootComponent;
myRootComponent = createComponent(myXmlFile.getRootTag(), myMetaManager.getModelByTag("<root>"));
myRootComponent.getChildren().add(rootComponent);
rootComponent.setParent(myRootComponent);
}
updateRootComponent(rootComponent, session, nativeComponent);
updateRootComponent(myRootComponent, session, nativeComponent);
}
public static void updateRootComponent(RadViewComponent rootComponent,
RenderSession session,
JComponent nativeComponent) {
RootView nativeComponent) {
List<ViewInfo> views = session.getRootViews();
int size = views.size();
List<RadComponent> children = rootComponent.getChildren();
int size = children.size();
for (int i = 0; i < size; i++) {
updateComponent((RadViewComponent)children.get(i), views.get(i), nativeComponent, 0, 0);
}
@@ -176,7 +235,7 @@ public class ModelParser extends XmlRecursiveElementVisitor {
private static void updateComponent(RadViewComponent component,
ViewInfo view,
JComponent nativeComponent,
RootView nativeComponent,
int parentX,
int parentY) {
component.setViewInfo(view);
@@ -184,11 +243,18 @@ public class ModelParser extends XmlRecursiveElementVisitor {
int left = parentX + view.getLeft();
int top = parentY + view.getTop();
component.setBounds(left, top, view.getRight() - view.getLeft(), view.getBottom() - view.getTop());
int width = view.getRight() - view.getLeft();
int height = view.getBottom() - view.getTop();
if (width < EMPTY_COMPONENT_SIZE && height < EMPTY_COMPONENT_SIZE) {
nativeComponent.addEmptyRegion(left, top, EMPTY_COMPONENT_SIZE, EMPTY_COMPONENT_SIZE);
}
component.setBounds(left, top, Math.max(width, EMPTY_COMPONENT_SIZE), Math.max(height, EMPTY_COMPONENT_SIZE));
List<ViewInfo> views = view.getChildren();
List<RadComponent> children = component.getChildren();
int size = views.size();
int size = children.size();
for (int i = 0; i < size; i++) {
updateComponent((RadViewComponent)children.get(i), views.get(i), nativeComponent, left, top);
@@ -40,22 +40,7 @@ public class RadLinearLayout extends RadViewLayout {
}
private void addNewComponent(RadViewComponent newComponent, @Nullable RadViewComponent insertBefore) throws Exception {
RadViewComponent container = (RadViewComponent)myContainer;
newComponent.setParent(container);
List<RadComponent> children = container.getChildren();
if (insertBefore == null) {
children.add(newComponent);
}
else {
children.add(children.indexOf(insertBefore), newComponent);
}
ModelParser
.setComponentTag(container.getTag(), newComponent, insertBefore == null ? null : insertBefore.getTag());
PropertyParser propertyParser = container.getRoot().getClientProperty(PropertyParser.KEY);
propertyParser.load(newComponent);
ModelParser.addComponent((RadViewComponent)myContainer, newComponent, insertBefore);
}
private class TreeCreateOperation extends TreeEditOperation {
@@ -0,0 +1,38 @@
/*
* 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.android.designer.model;
import com.intellij.android.designer.designSurface.DropToOperation;
import com.intellij.android.designer.designSurface.TreeDropToOperation;
import com.intellij.designer.designSurface.EditOperation;
import com.intellij.designer.designSurface.OperationContext;
/**
* @author Alexander Lobas
*/
public class RadRootViewLayout extends RadViewLayout {
@Override
public EditOperation processChildOperation(OperationContext context) {
if (myContainer.getChildren().isEmpty() && (context.isCreate() || context.isPaste()) && context.getComponents().size() == 1) {
if (context.isTree()) {
return new TreeDropToOperation(myContainer, context);
}
return new DropToOperation((RadViewComponent)myContainer, context);
}
return null;
}
}
@@ -5,15 +5,17 @@
<!-- ================= Roots ================= -->
<meta model="com.intellij.android.designer.model.RadViewComponent"
layout="com.intellij.android.designer.model.RadViewLayout"
tag="&lt;root&gt;">
layout="com.intellij.android.designer.model.RadRootViewLayout"
tag="&lt;root&gt;"
delete="false">
<palette title="Device Screen" icon="/com/intellij/android/designer/icons/DeviceScreen.png"/>
</meta>
<meta model="com.intellij.android.designer.model.RadViewComponent"
layout="com.intellij.android.designer.model.RadViewLayout"
tag="merge">
tag="merge"
delete="false">
<palette title="Device Screen (#merge)" icon="/com/intellij/android/designer/icons/DeviceScreen.png"/>
</meta>
@@ -83,6 +83,9 @@ public class ResourceDialog extends DialogWrapper implements TreeSelectionListen
myContentPanel.addTab("Project", myProjectPanel.myComponent);
myContentPanel.addTab("System", mySystemPanel.myComponent);
myProjectPanel.myTreeBuilder.expandAll(null);
mySystemPanel.myTreeBuilder.expandAll(null);
myContentPanel.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
@@ -207,6 +207,11 @@ public class CvsCommittedChangesProvider implements CachingCommittedChangesProvi
return new Pair<CvsChangeList, FilePath>(result.get(), filePath);
}
@Override
public RepositoryLocation getForNonLocal(VirtualFile file) {
return null;
}
public List<CvsChangeList> getCommittedChanges(ChangeBrowserSettings settings, RepositoryLocation location, final int maxCount)
throws VcsException {
final CvsRepositoryLocation cvsLocation = (CvsRepositoryLocation) location;
@@ -266,6 +266,11 @@ public class GitCommittedChangeListProvider implements CommittedChangesProvider<
return new Pair<CommittedChangeList, FilePath>(commit, ((GitFileRevision) history.get(history.size() - 1)).getPath());
}
@Override
public RepositoryLocation getForNonLocal(VirtualFile file) {
return null;
}
public int getFormatVersion() {
return 0;
}
+3 -1
View File
@@ -53,7 +53,6 @@
<!--Generic application services-->
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.remote.GradleApiFacadeManager"/>
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.util.GradleLibraryManager"/>
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.task.GradleTaskManager"/>
<applicationService serviceInterface="org.jetbrains.plugins.gradle.notification.GradleProgressNotificationManager"
serviceImplementation="org.jetbrains.plugins.gradle.notification.GradleProgressNotificationManagerImpl"/>
<applicationService serviceInterface="org.jetbrains.plugins.gradle.config.PlatformFacade"
@@ -101,6 +100,9 @@
<component>
<implementation-class>org.jetbrains.plugins.gradle.notification.GradleConfigNotificationManager</implementation-class>
</component>
<component>
<implementation-class>org.jetbrains.plugins.gradle.task.GradleTaskManager</implementation-class>
</component>
</project-components>
<actions>
@@ -2,7 +2,6 @@ package org.jetbrains.plugins.gradle.action;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
@@ -32,7 +31,7 @@ public class GradleRefreshProjectAction extends AbstractGradleLinkedProjectActio
@Override
protected void doUpdate(@NotNull Presentation presentation, @NotNull Project project, @NotNull String linkedProjectPath) {
boolean enabled = false;
final GradleTaskManager taskManager = ServiceManager.getService(GradleTaskManager.class);
final GradleTaskManager taskManager = project.getComponent(GradleTaskManager.class);
if (taskManager != null) {
enabled = !taskManager.hasTaskOfTypeInProgress(GradleTaskType.RESOLVE_PROJECT);
}
@@ -37,6 +37,8 @@ import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.concurrent.TimeUnit;
@@ -117,6 +119,22 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
}
}
};
myComponent.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (!"ancestor".equals(evt.getPropertyName())) {
return;
}
// Configure the balloon to show on initial configurable drawing.
myShowBalloonIfNecessary = evt.getNewValue() != null && evt.getOldValue() == null;
if (evt.getNewValue() == null && evt.getOldValue() != null) {
// Cancel delayed balloons when the configurable is hidden.
myAlarm.cancelAllRequests();
}
}
});
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridwidth = GridBagConstraints.REMAINDER;
constraints.weightx = 1;
@@ -151,7 +169,6 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
@Override
public boolean isModified() {
myShowBalloonIfNecessary = true;
if (!myPathManuallyModified) {
return false;
}
@@ -169,17 +186,25 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
useNormalColorForPath();
String path = myGradleHomeComponent.getPath();
GradleSettings.applyGradleHome(path, myProject);
// There is a possible case that user defines gradle home for particular open project. We want to apply that value
// to the default project as well if it's still non-defined.
Project defaultProject = ProjectManager.getInstance().getDefaultProject();
if (defaultProject == myProject) {
if (isValidGradleHome(path)) {
myGradleHomeSettingType = GradleHomeSettingType.EXPLICIT_CORRECT;
// There is a possible case that user defines gradle home for particular open project. We want to apply that value
// to the default project as well if it's still non-defined.
Project defaultProject = ProjectManager.getInstance().getDefaultProject();
if (defaultProject != myProject && !isValidGradleHome(GradleSettings.getInstance(defaultProject).getGradleHome())) {
GradleSettings.applyGradleHome(path, defaultProject);
}
return;
}
if (isValidGradleHome(path) && !isValidGradleHome(GradleSettings.getInstance(defaultProject).getGradleHome())) {
GradleSettings.applyGradleHome(path, defaultProject);
}
if (StringUtil.isEmpty(path)) {
myGradleHomeSettingType = GradleHomeSettingType.UNKNOWN;
}
else {
myGradleHomeSettingType = GradleHomeSettingType.EXPLICIT_INCORRECT;
new DelayedBalloonInfo(MessageType.ERROR, myGradleHomeSettingType, 0).run();
}
}
private boolean isValidGradleHome(@Nullable String path) {
@@ -203,7 +228,7 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
GradleHomeSettingType.EXPLICIT_CORRECT :
GradleHomeSettingType.EXPLICIT_INCORRECT;
if (myGradleHomeSettingType == GradleHomeSettingType.EXPLICIT_INCORRECT) {
new DelayedBalloonInfo(MessageType.ERROR, myGradleHomeSettingType).run();
new DelayedBalloonInfo(MessageType.ERROR, myGradleHomeSettingType, 0).run();
}
else {
myAlarm.cancelAllRequests();
@@ -283,9 +308,13 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
private final long myTriggerTime;
DelayedBalloonInfo(@NotNull MessageType messageType, @NotNull GradleHomeSettingType settingType) {
this(messageType, settingType, BALLOON_DELAY_MILLIS);
}
DelayedBalloonInfo(@NotNull MessageType messageType, @NotNull GradleHomeSettingType settingType, long delayMillis) {
myMessageType = messageType;
myText = settingType.getDescription();
myTriggerTime = System.currentTimeMillis() + BALLOON_DELAY_MILLIS;
myTriggerTime = System.currentTimeMillis() + delayMillis;
}
@Override
@@ -296,11 +325,15 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
myAlarm.addRequest(this, diff);
return;
}
if (myGradleHomeComponent == null || !myGradleHomeComponent.getPathComponent().isShowing()) {
if (myGradleHomeComponent == null) {
myAlarm.cancelAllRequests();
myAlarm.addRequest(this, 200);
return;
}
if (!myGradleHomeComponent.getPathComponent().isShowing()) {
// Don't schedule the balloon if the configurable is hidden.
return;
}
GradleUtil.showBalloon(myGradleHomeComponent.getPathComponent(), myMessageType, myText);
}
}
@@ -338,7 +338,7 @@ public class GradleModulesImporter {
public void run(@NotNull final ProgressIndicator indicator) {
GradleResolveProjectTask task = new GradleResolveProjectTask(intellijProject, gradleProjectPath, true);
task.execute(indicator);
GradleProject projectWithResolvedLibraries = task.getProject();
GradleProject projectWithResolvedLibraries = task.getGradleProject();
gradleProjectRef.set(projectWithResolvedLibraries);
ApplicationManager.getApplication().invokeLater(setupExternalDependenciesTask, ModalityState.NON_MODAL);
}
@@ -14,11 +14,15 @@ import com.intellij.execution.process.ProcessTerminatedListener;
import com.intellij.execution.rmi.RemoteProcessSupport;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.ide.actions.OpenProjectFileChooserDescriptor;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.projectRoots.*;
import com.intellij.openapi.roots.DependencyScope;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.ShutDownTracker;
import com.intellij.openapi.util.text.StringUtil;
@@ -27,8 +31,10 @@ import com.intellij.psi.PsiBundle;
import com.intellij.util.Alarm;
import com.intellij.util.PathUtil;
import com.intellij.util.SystemProperties;
import com.intellij.util.containers.ConcurrentWeakHashMap;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.notification.GradleProgressNotificationManager;
import org.jetbrains.plugins.gradle.notification.GradleProgressNotificationManagerImpl;
import org.jetbrains.plugins.gradle.remote.impl.GradleApiFacadeImpl;
@@ -49,8 +55,8 @@ import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
/**
* Entry point to work with remote {@link GradleApiFacade}.
@@ -62,15 +68,19 @@ import java.util.concurrent.atomic.AtomicReference;
*/
public class GradleApiFacadeManager {
private static final Pair<GradleApiFacade, RemoteGradleProcessSettings> NULL_VALUE = Pair.empty();
private static final String REMOTE_PROCESS_TTL_IN_MS_KEY = "gradle.remote.process.ttl.ms";
private static final String MAIN_CLASS_NAME = GradleApiFacadeImpl.class.getName();
private static final int REMOTE_FAIL_RECOVERY_ATTEMPTS_NUMBER = 3;
private final AtomicReference<Pair<GradleApiFacade, RemoteGradleProcessSettings>> myFacade
= new AtomicReference<Pair<GradleApiFacade, RemoteGradleProcessSettings>>();
private final AtomicReference<RemoteGradleProgressNotificationManager> myExportedProgressManager
= new AtomicReference<RemoteGradleProgressNotificationManager>();
private final ConcurrentMap<String /*project name*/, GradleApiFacade> myFacadeWrappers
= new ConcurrentWeakHashMap<String, GradleApiFacade>();
private final ConcurrentMap<String /*project name*/, RemoteGradleProgressNotificationManager> myRemoteNotificationManagers
= new ConcurrentWeakHashMap<String, RemoteGradleProgressNotificationManager>();
private final ConcurrentMap<String /*project name*/, Pair<GradleApiFacade, RemoteGradleProcessSettings>> myRemoteFacades
= new ConcurrentWeakHashMap<String, Pair<GradleApiFacade, RemoteGradleProcessSettings>>();
@NotNull private final GradleLibraryManager myGradleLibraryManager;
@NotNull private final GradleProgressNotificationManagerImpl myProgressManager;
@@ -78,13 +88,12 @@ public class GradleApiFacadeManager {
// Please note that we don't use RemoteGradleProcessSettings as the 'Configuration' type parameter here because we need
// to apply the settings to the newly created process. I.e. every time new process is created we need to call
// 'GradleApiFacade.applySettings()'. So, we need to hold reference to the last returned 'GradleApiFacade' stub anyway.
private final RemoteProcessSupport<Object, GradleApiFacade, Object> mySupport;
private final GradleApiFacade myApiFacade;
private final RemoteProcessSupport<Object, GradleApiFacade, String> mySupport;
public GradleApiFacadeManager(@NotNull GradleLibraryManager gradleLibraryManager, @NotNull GradleProgressNotificationManager manager) {
myGradleLibraryManager = gradleLibraryManager;
myProgressManager = (GradleProgressNotificationManagerImpl)manager;
mySupport = new RemoteProcessSupport<Object, GradleApiFacade, Object>(GradleApiFacade.class) {
mySupport = new RemoteProcessSupport<Object, GradleApiFacade, String>(GradleApiFacade.class) {
@Override
protected void fireModificationCountChanged() {
}
@@ -95,13 +104,10 @@ public class GradleApiFacadeManager {
}
@Override
protected RunProfileState getRunProfileState(Object o, Object configuration, Executor executor) throws ExecutionException {
return createRunProfileState();
protected RunProfileState getRunProfileState(Object o, String configuration, Executor executor) throws ExecutionException {
return createRunProfileState(findProjectByName(configuration));
}
};
myApiFacade = (GradleApiFacade)Proxy.newProxyInstance(
GradleApiFacadeManager.class.getClassLoader(), new Class[]{GradleApiFacade.class}, new MyHandler()
);
ShutDownTracker.getInstance().registerShutdownTask(new Runnable() {
public void run() {
@@ -110,10 +116,21 @@ public class GradleApiFacadeManager {
});
}
private RunProfileState createRunProfileState() {
@NotNull
private static Project findProjectByName(@NotNull String name) {
final ProjectManager projectManager = ProjectManager.getInstance();
for (Project project : projectManager.getOpenProjects()) {
if (name.equals(project.getName())) {
return project;
}
}
return projectManager.getDefaultProject();
}
private RunProfileState createRunProfileState(@Nullable final Project project) {
return new CommandLineState(null) {
private SimpleJavaParameters createJavaParameters() throws ExecutionException {
Collection<File> gradleLibraries = myGradleLibraryManager.getAllLibraries();
Collection<File> gradleLibraries = myGradleLibraryManager.getAllLibraries(project);
GradleLog.LOG.assertTrue(gradleLibraries != null, GradleBundle.message("gradle.generic.text.error.sdk.undefined"));
if (gradleLibraries == null) {
throw new ExecutionException("Can't find gradle libraries");
@@ -193,19 +210,29 @@ public class GradleApiFacadeManager {
* @throws Exception in case of inability to return the facade
*/
@NotNull
public GradleApiFacade getFacade() throws Exception {
return myApiFacade;
public GradleApiFacade getFacade(@Nullable Project project) throws Exception {
if (project == null) {
project = ProjectManager.getInstance().getDefaultProject();
}
final GradleApiFacade facade = myFacadeWrappers.get(project.getName());
if (facade == null) {
final GradleApiFacade newFacade = (GradleApiFacade)Proxy.newProxyInstance(
GradleApiFacadeManager.class.getClassLoader(), new Class[]{GradleApiFacade.class}, new MyHandler(project)
);
myFacadeWrappers.putIfAbsent(project.getName(), newFacade);
}
return myFacadeWrappers.get(project.getName());
}
public Object doInvoke(Method method, Object[] args, int invocationNumber) throws Throwable {
GradleApiFacade facade = doGetFacade();
public Object doInvoke(@NotNull Project project, Method method, Object[] args, int invocationNumber) throws Throwable {
GradleApiFacade facade = doGetFacade(project);
try {
return method.invoke(facade, args);
}
catch (InvocationTargetException e) {
if (e.getTargetException() instanceof RemoteException && invocationNumber > 0) {
Thread.sleep(1000);
return doInvoke(method, args, invocationNumber - 1);
return doInvoke(project, method, args, invocationNumber - 1);
}
else {
throw e;
@@ -213,43 +240,57 @@ public class GradleApiFacadeManager {
}
}
@SuppressWarnings("ConstantConditions")
@NotNull
private GradleApiFacade doGetFacade() throws Exception {
if (!GradleUtil.isGradleAvailable()) {
private GradleApiFacade doGetFacade(@NotNull Project project) throws Exception {
if (project.isDisposed() || !GradleUtil.isGradleAvailable(project)) {
return GradleApiFacade.NULL_OBJECT;
}
Pair<GradleApiFacade, RemoteGradleProcessSettings> pair = myFacade.get();
Pair<GradleApiFacade, RemoteGradleProcessSettings> pair = myRemoteFacades.get(project.getName());
if (pair != null) {
if (isValid(pair)) {
if (isValid(pair, project)) {
return pair.first;
}
mySupport.stopAll(true);
myFacade.compareAndSet(pair, null);
myFacadeWrappers.clear();
myRemoteFacades.clear();
final Pair<GradleApiFacade, RemoteGradleProcessSettings> p = myRemoteFacades.putIfAbsent(project.getName(), NULL_VALUE);
if (p != null && p != NULL_VALUE) {
return p.first;
}
}
final GradleApiFacade facade = mySupport.acquire(this, "");
final GradleApiFacade facade = mySupport.acquire(this, project.getName());
if (facade == null) {
throw new IllegalStateException("Can't obtain facade to working with gradle api at the remote process");
throw new IllegalStateException("Can't obtain facade to working with gradle api at the remote process. Project: " + project);
}
Disposer.register(project, new Disposable() {
@Override
public void dispose() {
mySupport.stopAll(true);
myFacadeWrappers.clear();
myRemoteFacades.clear();
}
});
final GradleApiFacade result = new GradleApiFacadeWrapper(facade, myProgressManager);
Pair<GradleApiFacade, RemoteGradleProcessSettings> newPair
= new Pair<GradleApiFacade, RemoteGradleProcessSettings>(result, getRemoteSettings());
if (!myFacade.compareAndSet(null, newPair)) {
GradleLog.LOG.warn("Detected unexpected duplicate tooling api facade instance creation");
return myFacade.get().first;
= new Pair<GradleApiFacade, RemoteGradleProcessSettings>(result, getRemoteSettings(project));
if (myRemoteFacades.putIfAbsent(project.getName(), newPair) != null && !myRemoteFacades.replace(project.getName(), NULL_VALUE, newPair)) {
GradleLog.LOG.warn("Detected unexpected duplicate tooling api facade instance creation. Project: " + project);
return myRemoteFacades.get(project.getName()).first;
}
if (!StringUtil.isEmpty(newPair.second.getJavaHome())) {
GradleLog.LOG.info("Instructing gradle to use java from " + newPair.second.getJavaHome());
}
result.applySettings(newPair.second);
RemoteGradleProgressNotificationManager exported = myExportedProgressManager.get();
RemoteGradleProgressNotificationManager exported = myRemoteNotificationManagers.get(project.getName());
if (exported == null) {
try {
exported = (RemoteGradleProgressNotificationManager)UnicastRemoteObject.exportObject(myProgressManager, 0);
myExportedProgressManager.set(exported);
myRemoteNotificationManagers.putIfAbsent(project.getName(), exported);
}
catch (RemoteException e) {
exported = myExportedProgressManager.get();
exported = myRemoteNotificationManagers.get(project.getName());
}
}
if (exported == null) {
@@ -261,7 +302,11 @@ public class GradleApiFacadeManager {
return result;
}
private boolean isValid(@NotNull Pair<GradleApiFacade, RemoteGradleProcessSettings> pair) {
private boolean isValid(@NotNull Pair<GradleApiFacade, RemoteGradleProcessSettings> pair, @Nullable Project project) {
if (pair == NULL_VALUE) {
return false;
}
// Check remote process is alive.
try {
pair.first.getResolver();
@@ -272,8 +317,8 @@ public class GradleApiFacadeManager {
// Check that significant settings are not changed
RemoteGradleProcessSettings oldSettings = pair.second;
RemoteGradleProcessSettings currentSettings = getRemoteSettings();
RemoteGradleProcessSettings currentSettings = getRemoteSettings(project);
// We restart the slave process because there is a possible case that it was started with the incorrect classpath.
// For example, it could be started with gradle milestone-3 and that means that its classpath doesn't contain BasicIdeaProject.class.
// So, even if the user defines gradle milestone-7 to use, the slave process still is unable to operate because its classpath
@@ -285,8 +330,8 @@ public class GradleApiFacadeManager {
}
@NotNull
private RemoteGradleProcessSettings getRemoteSettings() {
File gradleHome = myGradleLibraryManager.getGradleHome();
private RemoteGradleProcessSettings getRemoteSettings(@Nullable Project project) {
File gradleHome = myGradleLibraryManager.getGradleHome(project);
RemoteGradleProcessSettings result = new RemoteGradleProcessSettings(gradleHome.getAbsolutePath());
String ttlAsString = System.getProperty(REMOTE_PROCESS_TTL_IN_MS_KEY);
if (ttlAsString != null) {
@@ -304,9 +349,16 @@ public class GradleApiFacadeManager {
}
private class MyHandler implements InvocationHandler {
@NotNull private final String myProjectName;
MyHandler(@NotNull Project project) {
myProjectName = project.getName();
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return doInvoke(method, args, REMOTE_FAIL_RECOVERY_ATTEMPTS_NUMBER);
return doInvoke(findProjectByName(myProjectName), method, args, REMOTE_FAIL_RECOVERY_ATTEMPTS_NUMBER);
}
}
}
@@ -3,7 +3,9 @@ package org.jetbrains.plugins.gradle.task;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.notification.GradleProgressNotificationManager;
import org.jetbrains.plugins.gradle.notification.GradleTaskNotificationEvent;
import org.jetbrains.plugins.gradle.notification.GradleTaskNotificationListener;
@@ -28,9 +30,11 @@ public abstract class AbstractGradleTask implements GradleTask {
private final AtomicReference<GradleTaskState> myState = new AtomicReference<GradleTaskState>(GradleTaskState.NOT_STARTED);
private final AtomicReference<Throwable> myError = new AtomicReference<Throwable>();
private final GradleTaskId myId;
@Nullable transient private final Project myIntellijProject;
@NotNull private final GradleTaskId myId;
protected AbstractGradleTask(@NotNull GradleTaskType type) {
protected AbstractGradleTask(Project project, @NotNull GradleTaskType type) {
myIntellijProject = project;
myId = GradleTaskId.create(type);
}
@@ -53,13 +57,18 @@ public abstract class AbstractGradleTask implements GradleTask {
return myError.get();
}
@Nullable
public Project getIntellijProject() {
return myIntellijProject;
}
public void refreshState() {
if (getState() != GradleTaskState.IN_PROGRESS) {
return;
}
final GradleApiFacadeManager manager = ServiceManager.getService(GradleApiFacadeManager.class);
try {
final GradleApiFacade facade = manager.getFacade();
final GradleApiFacade facade = manager.getFacade(myIntellijProject);
setState(facade.isTaskInProgress(getId()) ? GradleTaskState.IN_PROGRESS : GradleTaskState.FAILED);
}
catch (Throwable e) {
@@ -21,20 +21,19 @@ public class GradleResolveProjectTask extends AbstractGradleTask {
private final AtomicReference<GradleProject> myGradleProject = new AtomicReference<GradleProject>();
private final Project myIntellijProject;
private final String myProjectPath;
private final boolean myResolveLibraries;
public GradleResolveProjectTask(@Nullable Project project, @NotNull String projectPath, boolean resolveLibraries) {
super(GradleTaskType.RESOLVE_PROJECT);
myIntellijProject = project;
super(project, GradleTaskType.RESOLVE_PROJECT);
myProjectPath = projectPath;
myResolveLibraries = resolveLibraries;
}
protected void doExecute() throws Exception {
final GradleApiFacadeManager manager = ServiceManager.getService(GradleApiFacadeManager.class);
GradleProjectResolver resolver = manager.getFacade().getResolver();
GradleProjectResolver resolver = manager.getFacade(getIntellijProject()).getResolver();
setState(GradleTaskState.IN_PROGRESS);
final GradleProject project = resolver.resolveProjectInfo(getId(), myProjectPath, myResolveLibraries);
if (project == null) {
@@ -42,10 +41,11 @@ public class GradleResolveProjectTask extends AbstractGradleTask {
}
myGradleProject.set(project);
setState(GradleTaskState.FINISHED);
if (myIntellijProject == null || myIntellijProject.isDisposed()) {
final Project intellijProject = getIntellijProject();
if (intellijProject == null || intellijProject.isDisposed()) {
return;
}
final GradleProjectStructureChangesModel model = myIntellijProject.getComponent(GradleProjectStructureChangesModel.class);
final GradleProjectStructureChangesModel model = intellijProject.getComponent(GradleProjectStructureChangesModel.class);
if (model != null) {
// This task may be called during the 'import from gradle' processing, hence, no project-level IoC is up.
// Model update is necessary for the correct tool window project structure diff showing but we don't have
@@ -55,7 +55,7 @@ public class GradleResolveProjectTask extends AbstractGradleTask {
}
@Nullable
public GradleProject getProject() {
public GradleProject getGradleProject() {
return myGradleProject.get();
}
}
@@ -1,5 +1,8 @@
package org.jetbrains.plugins.gradle.task;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.project.Project;
import com.intellij.util.Alarm;
import com.intellij.util.containers.ConcurrentHashMap;
import org.jetbrains.annotations.NotNull;
@@ -23,7 +26,7 @@ import java.util.concurrent.TimeUnit;
* @author Denis Zhdanov
* @since 2/8/12 1:52 PM
*/
public class GradleTaskManager implements GradleTaskNotificationListener {
public class GradleTaskManager extends AbstractProjectComponent implements GradleTaskNotificationListener {
/**
* We receive information about the tasks being enqueued to the slave gradle projects here. However, there is a possible
@@ -45,9 +48,19 @@ public class GradleTaskManager implements GradleTaskNotificationListener {
@NotNull private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD);
@NotNull private final GradleApiFacadeManager myFacadeManager;
@NotNull private final GradleProgressNotificationManager myProgressNotificationManager;
public GradleTaskManager(@NotNull GradleApiFacadeManager facadeManager, @NotNull GradleProgressNotificationManager notificationManager) {
public GradleTaskManager(@NotNull Project project,
@NotNull GradleApiFacadeManager facadeManager,
@NotNull GradleProgressNotificationManager notificationManager)
{
super(project);
myFacadeManager = facadeManager;
myProgressNotificationManager = notificationManager;
if (ApplicationManager.getApplication().isUnitTestMode()) {
return;
}
notificationManager.addNotificationListener(this);
myAlarm.addRequest(new Runnable() {
@Override
@@ -67,7 +80,12 @@ public class GradleTaskManager implements GradleTaskNotificationListener {
}
}, DETECT_HANGED_TASKS_FREQUENCY_MILLIS);
}
@Override
public void disposeComponent() {
myProgressNotificationManager.removeNotificationListener(this);
}
/**
* Allows to check if any task of the given type is being executed at the moment.
*
@@ -106,7 +124,7 @@ public class GradleTaskManager implements GradleTaskNotificationListener {
public void update() {
try {
final Map<GradleTaskType, Set<GradleTaskId>> currentState = myFacadeManager.getFacade().getTasksInProgress();
final Map<GradleTaskType, Set<GradleTaskId>> currentState = myFacadeManager.getFacade(myProject).getTasksInProgress();
myTasksInProgress.clear();
for (Set<GradleTaskId> ids : currentState.values()) {
for (GradleTaskId id : ids) {
@@ -44,15 +44,6 @@ public class GradleLibraryManager {
GRADLE_ENV_PROPERTY_NAME = System.getProperty("gradle.home.env.key", "GRADLE_HOME");
}
@Nullable
public Collection<File> getAllLibraries() {
final Project[] projects = ProjectManager.getInstance().getOpenProjects();
if (projects.length == 1) {
return getAllLibraries(projects[0]);
}
return getAllLibraries(null);
}
/**
* Allows to get file handles for the gradle binaries to use.
*
@@ -208,7 +208,7 @@ public class GradleUtil {
public void execute(@NotNull ProgressIndicator indicator) {
GradleResolveProjectTask task = new GradleResolveProjectTask(project, gradleProjectPath, resolveLibraries);
task.execute(indicator);
gradleProject.set(task.getProject());
gradleProject.set(task.getGradleProject());
final Throwable error = task.getError();
if (error == null) {
return;
@@ -286,4 +286,9 @@ public class HgCachingCommitedChangesProvider
}
return null;
}
@Override
public RepositoryLocation getForNonLocal(VirtualFile file) {
return null;
}
}
@@ -216,10 +216,17 @@ public class MavenPropertyResolver {
MavenId parentId = selectedProject.getParentId();
if (parentId == null) return null;
unprefixed = unprefixed.substring("parent.".length());
if (unprefixed.equals("groupId")) {
return parentId.getGroupId();
}
if (unprefixed.equals("artifactId")) {
return parentId.getArtifactId();
}
selectedProject = projectsManager.findProject(parentId);
if (selectedProject == null) return null;
unprefixed = unprefixed.substring("parent.".length());
}
if (unprefixed.equals("basedir") || (hasPrefix && mavenProject == selectedProject && unprefixed.equals("baseUri"))) {
@@ -31,7 +31,6 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.SmartList;
import com.intellij.util.containers.CollectionFactory;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
@@ -737,7 +736,13 @@ public class MavenProject {
@Nullable
public MavenPlugin findPlugin(@Nullable String groupId, @Nullable String artifactId) {
for (MavenPlugin each : getPlugins()) {
return findPlugin(groupId, artifactId, false);
}
@Nullable
public MavenPlugin findPlugin(@Nullable String groupId, @Nullable String artifactId, final boolean explicitlyDeclaredOnly) {
final List<MavenPlugin> plugins = explicitlyDeclaredOnly ? getDeclaredPlugins() : getPlugins();
for (MavenPlugin each : plugins) {
if (each.getMavenId().equals(groupId, artifactId)) return each;
}
return null;
@@ -35,7 +35,7 @@ public class MavenAddArchetypeDialog extends DialogWrapper {
public MavenAddArchetypeDialog(Component parent) {
super(parent, false);
setTitle("Add archetype");
setTitle("Add Archetype");
init();
@@ -123,10 +123,10 @@ public class MavenPropertyResolverTest extends MavenImportingTestCase {
assertEquals("parent.value", resolve("${parentProp}", f));
assertEquals("module.value", resolve("${moduleProp}", f));
assertEquals("parent.value", resolve("${project.parentProp}", f));
assertEquals("parent.value", resolve("${pom.parentProp}", f));
assertEquals("module.value", resolve("${project.moduleProp}", f));
assertEquals("module.value", resolve("${pom.moduleProp}", f));
assertEquals("${project.parentProp}", resolve("${project.parentProp}", f));
assertEquals("${pom.parentProp}", resolve("${pom.parentProp}", f));
assertEquals("${project.moduleProp}", resolve("${project.moduleProp}", f));
assertEquals("${pom.moduleProp}", resolve("${pom.moduleProp}", f));
}
public void testProjectPropertiesRecursively() throws Exception {
@@ -556,17 +556,22 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
}
private void createPool() {
if (myPool != null) return;
final String property = System.getProperty(KEEP_CONNECTIONS_KEY);
final boolean keep;
if (StringUtil.isEmptyOrSpaces(property)) {
keep = ! ApplicationManager.getApplication().isUnitTestMode(); // default
keep = !ApplicationManager.getApplication().isUnitTestMode(); // default
} else {
keep = Boolean.getBoolean(KEEP_CONNECTIONS_KEY);
}
myPool = new DefaultSVNRepositoryPool(myConfiguration.getAuthenticationManager(this), myConfiguration.getOptions(myProject), 60*1000, keep);
}
@NotNull
private ISVNRepositoryPool getPool() {
if (myPool == null) {
createPool();
}
return myPool;
}
@@ -86,18 +86,22 @@ public class CopiesPanel {
myCurrentInfoList = null;
final Runnable focus = new Runnable() {
@Override
public void run() {
IdeFocusManager.getInstance(myProject).requestFocus(myRefreshLabel, true);
}
};
final Runnable refreshView = new Runnable() {
@Override
public void run() {
final List<WCInfo> infoList = myVcs.getAllWcInfos();
Runnable runnable = new Runnable() {
@Override
public void run() {
if (myCurrentInfoList != null) {
final List<OverrideEqualsWrapper<WCInfo>> newList =
ObjectsConvertor.convert(infoList, new Convertor<WCInfo, OverrideEqualsWrapper<WCInfo>>() {
@Override
public OverrideEqualsWrapper<WCInfo> convert(WCInfo o) {
return new OverrideEqualsWrapper<WCInfo>(InfoEqualityPolicy.getInstance(), o);
}
@@ -119,8 +123,14 @@ public class CopiesPanel {
}
};
final Runnable refreshOnPooled = new Runnable() {
@Override
public void run() {
ApplicationManager.getApplication().executeOnPooledThread(refreshView);
if (ApplicationManager.getApplication().isUnitTestMode()) {
refreshView.run();
}
else {
ApplicationManager.getApplication().executeOnPooledThread(refreshView);
}
}
};
myConnection.subscribe(SvnVcs.ROOTS_RELOADED, refreshOnPooled);
@@ -133,6 +143,7 @@ public class CopiesPanel {
panel.add(myPanel, BorderLayout.NORTH);
holderPanel.add(panel, BorderLayout.WEST);
myRefreshLabel = new MyLinkLabel(myTextHeight, "Refresh", new LinkListener() {
@Override
public void linkSelected(LinkLabel aSource, Object aLinkData) {
if (myRefreshLabel.isEnabled()) {
myVcs.invokeRefreshSvnRoots(true);
@@ -280,6 +291,7 @@ public class CopiesPanel {
private void mergeFrom(final WCInfo wcInfo, final VirtualFile root, final Component mergeLabel) {
SelectBranchPopup.showForBranchRoot(myProject, root, new SelectBranchPopup.BranchSelectedCallback() {
@Override
public void branchSelected(Project project, SvnBranchConfigurationNew configuration, String url, long revision) {
new QuickMerge(project, url, wcInfo, SVNPathUtil.tail(url), root).execute();
}
@@ -393,6 +405,7 @@ public class CopiesPanel {
}
}
@Override
public int getHashCode(WCInfo value) {
final HashCodeBuilder builder = new HashCodeBuilder();
builder.append(value.getPath());
@@ -404,6 +417,7 @@ public class CopiesPanel {
return builder.getCode();
}
@Override
public boolean isEqual(WCInfo val1, WCInfo val2) {
if (val1 == val2) return true;
if (val1 == null || val2 == null || val1.getClass() != val2.getClass()) return false;
@@ -425,6 +439,7 @@ public class CopiesPanel {
return ourComparator;
}
@Override
public int compare(WCInfo o1, WCInfo o2) {
return o1.getPath().compareTo(o2.getPath());
}
@@ -25,6 +25,7 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ContentRevision;
@@ -33,6 +34,7 @@ import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings;
import com.intellij.openapi.vcs.versionBrowser.ChangesBrowserSettingsEditor;
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.AsynchConsumer;
import com.intellij.util.Consumer;
@@ -563,6 +565,12 @@ public class SvnCommittedChangesProvider implements CachingCommittedChangesProvi
return new Pair<SvnChangeList, FilePath>(result[0], new FilePathImpl(file));
}
@Override
public RepositoryLocation getForNonLocal(VirtualFile file) {
final String url = file.getPresentableUrl();
return new SvnRepositoryLocation(FileUtil.toSystemIndependentName(url));
}
private static class RenameContext {
@NotNull
private String myCurrentPath;
@@ -619,10 +619,10 @@ public class SvnHistoryProvider implements VcsHistoryProvider, VcsCacheableHisto
super(vcs, url, pegRevision, lastPath, result, repoRootURL, null);
}
@Override
/*@Override
protected SvnFileRevision createRevision(final SVNLogEntry logEntry, final String copyPath) {
return new SvnFileRevision(myVcs, SVNRevision.UNDEFINED, logEntry, myUrl, copyPath, null);
}
}*/
}
private class MergeSourceColumnInfo extends ColumnInfo<VcsFileRevision, VcsFileRevision> {
@@ -246,9 +246,10 @@ public class TestNGRunnableState extends JavaCommandLineState {
LOG.info("Language level is " + effectiveLanguageLevel.toString());
LOG.info("is15 is " + is15);
final String pathToBundledJar = PathUtil.getJarPathForClass(AfterClass.class);
final String incompatibilityMessage = TestNGVersionChecker
.getVersionIncompatibilityMessage(project, config.getPersistantData().getScope().getSourceScope(config).getLibrariesScope(),
pathToBundledJar);
final SourceScope sourceScope = config.getPersistantData().getScope().getSourceScope(config);
final String incompatibilityMessage = sourceScope != null ?
TestNGVersionChecker.getVersionIncompatibilityMessage(project, sourceScope.getLibrariesScope(), pathToBundledJar) :
null;
if (incompatibilityMessage != null) {
javaParameters.getClassPath().add(pathToBundledJar);
}
@@ -92,6 +92,11 @@ public abstract class MetaManager {
meta.setLayout((Class<RadLayout>)classLoader.loadClass(layout));
}
String delete = element.getAttributeValue("delete");
if (delete != null) {
meta.setDelete(Boolean.parseBoolean(delete));
}
Element presentation = element.getChild("presentation");
if (presentation != null) {
meta.setPresentation(presentation.getAttributeValue("title"), presentation.getAttributeValue("icon"));
@@ -36,6 +36,7 @@ public class MetaModel {
private String myIconPath;
private Icon myIcon;
private String myCreation;
private boolean myDelete = true;
private List<String> myNormalProperties = Collections.emptyList();
private List<String> myImportantProperties = Collections.emptyList();
private List<String> myExpertProperties = Collections.emptyList();
@@ -75,6 +76,14 @@ public class MetaModel {
myCreation = creation;
}
public boolean canDelete() {
return myDelete;
}
public void setDelete(boolean delete) {
myDelete = delete;
}
public String getTitle() {
return myTitle;
}

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