mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -42,4 +42,6 @@ public interface ProjectFromSourcesBuilder {
|
||||
|
||||
@NotNull
|
||||
WizardContext getContext();
|
||||
|
||||
boolean hasRootsFromOtherDetectors(ProjectStructureDetector thisDetector);
|
||||
}
|
||||
|
||||
+10
@@ -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)
|
||||
|
||||
+92
-49
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-7
@@ -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) {
|
||||
|
||||
+3
-3
@@ -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);
|
||||
}
|
||||
|
||||
+7
-1
@@ -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()]);
|
||||
}
|
||||
};
|
||||
|
||||
+12
-4
@@ -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)) {
|
||||
|
||||
+25
-6
@@ -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
|
||||
|
||||
+8
-2
@@ -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();
|
||||
|
||||
+4
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
+26
@@ -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 {}
|
||||
+30
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+15
@@ -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
-3
@@ -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);
|
||||
}
|
||||
|
||||
+5
-1
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -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);
|
||||
}
|
||||
|
||||
+6
-1
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -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.
|
||||
*/
|
||||
|
||||
-9
@@ -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));
|
||||
|
||||
+5
-4
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+15
@@ -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
-4
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -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);
|
||||
|
||||
+5
-1
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-1
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+13
@@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+12
@@ -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>
|
||||
|
||||
|
||||
+7
-25
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+88
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+75
@@ -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;
|
||||
}
|
||||
}
|
||||
+36
@@ -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);
|
||||
|
||||
+1
-16
@@ -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 {
|
||||
|
||||
+38
@@ -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
-3
@@ -5,15 +5,17 @@
|
||||
<!-- ================= Roots ================= -->
|
||||
|
||||
<meta model="com.intellij.android.designer.model.RadViewComponent"
|
||||
layout="com.intellij.android.designer.model.RadViewLayout"
|
||||
tag="<root>">
|
||||
layout="com.intellij.android.designer.model.RadRootViewLayout"
|
||||
tag="<root>"
|
||||
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>
|
||||
|
||||
+3
@@ -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) {
|
||||
|
||||
+5
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
+1
-2
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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);
|
||||
}
|
||||
|
||||
+92
-40
@@ -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;
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ public class MavenAddArchetypeDialog extends DialogWrapper {
|
||||
|
||||
public MavenAddArchetypeDialog(Component parent) {
|
||||
super(parent, false);
|
||||
setTitle("Add archetype");
|
||||
setTitle("Add Archetype");
|
||||
|
||||
init();
|
||||
|
||||
|
||||
+4
-4
@@ -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> {
|
||||
|
||||
+4
-3
@@ -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
Reference in New Issue
Block a user