Merge remote branch 'origin/master'

This commit is contained in:
irengrig
2012-03-26 13:34:31 +04:00
123 changed files with 1866 additions and 621 deletions
+7 -1
View File
@@ -218,7 +218,7 @@ def layoutFull(String home, String targetDirectory, String patchedDescriptorDir
public def layoutCommunityPlugins(String home) {
dir("plugins") {
def simplePlugins = ["commander", "copyright", "properties", "java-i18n", "devkit", "eclipse", "hg4idea", "github"]
def simplePlugins = ["commander", "copyright", "properties", "java-i18n", "devkit", "eclipse", "hg4idea", "github", "ui-designer-new"]
simplePlugins.each {
layoutPlugin it
@@ -392,6 +392,12 @@ public def layoutCommunityPlugins(String home) {
jar("android-jps-plugin.jar") { module("android-jps-plugin") }
}
}
layoutPlugin("android-designer") {
jar("android-designer.jar") {
module("android-designer")
}
}
}
}
+9 -5
View File
@@ -1,10 +1,14 @@
import static org.jetbrains.jps.idea.IdeaProjectLoader.*
import static org.jetbrains.jps.idea.IdeaProjectLoader.guessHome
includeTargets << new File("${guessHome(this)}/build/scripts/common_tests.gant")
setProperty("testcases", ["com.intellij.AllTests"])
setProperty("jvm_args", [
"-Xmx350m",
"-XX:MaxPermSize=320m",
])
def isMac = System.getProperty("os.name").toLowerCase().startsWith("mac")
def args = [
"-Xmx350m",
"-XX:MaxPermSize=320m",
]
if (isMac) args << "-d32";
setProperty("jvm_args", args)
@@ -70,7 +70,8 @@ import org.jetbrains.jps.client.CompileServerClient;
import org.jetbrains.jps.server.ClasspathBootstrap;
import org.jetbrains.jps.server.Server;
import javax.tools.*;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -611,7 +612,6 @@ public class CompileServerManager implements ApplicationComponent{
cmdLine.addParameter("-D"+ GlobalOptions.USE_EXTERNAL_JAVAC_OPTION + "=true");
}
cmdLine.addParameter("-D"+ GlobalOptions.HOSTNAME_OPTION + "=" + NetUtils.getLocalHostString());
cmdLine.addParameter("-D"+ GlobalOptions.VM_EXE_PATH_OPTION + "=" + FileUtil.toSystemIndependentName(vmExecutablePath));
// javac's VM should use the same default locale that IDEA uses in order for javac to print messages in 'correct' language
final String lang = System.getProperty("user.language");
@@ -138,7 +138,7 @@ public class Dependency {
private static String[] parseParameterDescriptors(String signature) {
ArrayList<String> list = new ArrayList<String>();
String paramSignature = parseFieldType(signature);
while (paramSignature != null && !"".equals(paramSignature)) {
while (paramSignature != null && !paramSignature.isEmpty()) {
list.add(paramSignature);
signature = signature.substring(paramSignature.length());
paramSignature = parseFieldType(signature);
@@ -147,39 +147,40 @@ public class Dependency {
}
private static String parseFieldType(@NonNls String signature) {
if (signature.length() == 0) {
if (signature.isEmpty()) {
return null;
}
if (signature.charAt(0) == 'B') {
return "B";
}
if (signature.charAt(0) == 'C') {
return "C";
}
if (signature.charAt(0) == 'D') {
return "D";
}
if (signature.charAt(0) == 'F') {
return "F";
}
if (signature.charAt(0) == 'I') {
char first = signature.charAt(0);
if (first == 'I') {
return "I";
}
if (signature.charAt(0) == 'J') {
if (first == 'L') {
return signature.substring(0, signature.indexOf(';') + 1);
}
if (first == 'B') {
return "B";
}
if (first == 'C') {
return "C";
}
if (first == 'D') {
return "D";
}
if (first == 'F') {
return "F";
}
if (first == 'J') {
return "J";
}
if (signature.charAt(0) == 'S') {
if (first == 'S') {
return "S";
}
if (signature.charAt(0) == 'Z') {
if (first == 'Z') {
return "Z";
}
if (signature.charAt(0) == 'L') {
return signature.substring(0, signature.indexOf(";") + 1);
}
if (signature.charAt(0) == '[') {
if (first == '[') {
String s = parseFieldType(signature.substring(1));
return (s != null)? ("[" + s) : null;
return s == null ? null : "[" + s;
}
return null;
}
@@ -24,6 +24,7 @@ import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ModuleRootModel;
import com.intellij.openapi.util.Pair;
import com.intellij.util.Chunk;
import com.intellij.util.containers.ContainerUtil;
@@ -106,15 +107,16 @@ public final class ModuleCompilerUtil {
}
}
public static GraphGenerator<ModifiableRootModel> createGraphGenerator(final Map<Module, ModifiableRootModel> models) {
return GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<ModifiableRootModel>() {
public Collection<ModifiableRootModel> getNodes() {
public static <T extends ModuleRootModel> GraphGenerator<T> createGraphGenerator(final Map<Module, T> models) {
return GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<T>() {
public Collection<T> getNodes() {
return models.values();
}
public Iterator<ModifiableRootModel> getIn(final ModifiableRootModel model) {
public Iterator<T> getIn(final ModuleRootModel model) {
final Module[] modules = model.getModuleDependencies();
final List<ModifiableRootModel> dependencies = new ArrayList<ModifiableRootModel>();
final List<T> dependencies = new ArrayList<T>();
for (Module module : modules) {
dependencies.add(models.get(module));
}
@@ -162,7 +164,7 @@ public final class ModuleCompilerUtil {
return null;
}
public static Collection<Chunk<ModifiableRootModel>> buildChunks(final Map<Module, ModifiableRootModel> models) {
public static <T extends ModuleRootModel> Collection<Chunk<T>> buildChunks(final Map<Module, T> models) {
return toChunkGraph(createGraphGenerator(models)).getNodes();
}
}
@@ -42,4 +42,6 @@ public interface ProjectFromSourcesBuilder {
@NotNull
WizardContext getContext();
boolean hasRootsFromOtherDetectors(ProjectStructureDetector thisDetector);
}
@@ -32,6 +32,7 @@ import com.intellij.ide.util.projectWizard.importSources.ProjectStructureDetecto
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.module.*;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
@@ -262,6 +263,15 @@ public class ProjectFromSourcesBuilderImpl extends ProjectBuilder implements Pro
myUpdaters.add(updater);
}
public boolean hasRootsFromOtherDetectors(ProjectStructureDetector thisDetector) {
for (ProjectStructureDetector projectStructureDetector : Extensions.getExtensions(ProjectStructureDetector.EP_NAME)) {
if (projectStructureDetector != thisDetector && !getProjectRoots(projectStructureDetector).isEmpty()) {
return true;
}
}
return false;
}
@NotNull
private static Module createModule(ProjectDescriptor projectDescriptor, final ModuleDescriptor descriptor,
final Map<LibraryDescriptor, Library> projectLibs, final ModifiableModuleModel moduleModel)
@@ -18,16 +18,15 @@ package com.intellij.openapi.roots.ui.configuration;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.wm.impl.content.GraphicsConfig;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.components.JBList;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.components.labels.LinkLabel;
import com.intellij.ui.components.labels.LinkListener;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.BaseButtonBehavior;
import com.intellij.util.ui.TimedDeadzone;
@@ -45,6 +44,7 @@ import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.RoundRectangle2D;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
@@ -52,6 +52,7 @@ import java.util.List;
* User: spLeaner
*/
public class ConfigurationErrorsComponent extends JPanel implements Disposable, ListDataListener {
private static final int MAX_ERRORS_TO_SHOW = SystemInfo.getIntProperty("idea.project.structure.max.errors.to.show", 100);
private static final boolean ONE_LINE = true;
private static final boolean MULTI_LINE = false;
@@ -95,7 +96,7 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable,
private void ensureCurrentViewIs(final boolean oneLine, @Nullable final Object data) {
if (oneLine) {
if (myCurrentView instanceof OneLineErrorComponent) return;
myConfigurationErrorsListModel.setFilter(null);
myConfigurationErrorsListModel.setFilter(true, true);
OneLineErrorComponent c = new OneLineErrorComponent(myConfigurationErrorsListModel) {
@Override
public void onViewChange(Object data) {
@@ -109,14 +110,9 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable,
}
myCurrentView = c;
} else {
Condition<ConfigurationError> filter = data == null ? null : new Condition<ConfigurationError>() {
@Override
public boolean value(ConfigurationError error) {
return data == null ? true : "Ignored".equals(data) ? error.isIgnored() : !error.isIgnored();
}
};
myConfigurationErrorsListModel.setFilter(filter);
}
else {
myConfigurationErrorsListModel.setFilter(data == null || !"Ignored".equals(data), data == null || "Ignored".equals(data));
if (myCurrentView instanceof MultiLineErrorComponent) return;
MultiLineErrorComponent c = new MultiLineErrorComponent(myConfigurationErrorsListModel) {
@Override
@@ -568,13 +564,13 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable,
if (errors.size() == 1) {
mySingleErrorLabel.setText(myModel.getErrors().get(0).getPlainTextTitle());
} else {
myErrorsLabel.setText(String.format("%s errors found", errors.size()));
myErrorsLabel.setText(String.format("%s errors found", getErrorsCount(errors.size())));
}
}
final List<ConfigurationError> ignoredErrors = myModel.getIgnoredErrors();
if (ignoredErrors.size() > 0) {
myIgnoredErrorsLabel.setText(String.format("%s ignored error%s", ignoredErrors.size(), ignoredErrors.size() == 1 ? "" : "s"));
myIgnoredErrorsLabel.setText(String.format("%s ignored error%s", getErrorsCount(ignoredErrors.size()), ignoredErrors.size() == 1 ? "" : "s"));
}
removeAll();
@@ -595,6 +591,10 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable,
repaint();
}
private static String getErrorsCount(final int size) {
return size < MAX_ERRORS_TO_SHOW ? String.valueOf(size) : MAX_ERRORS_TO_SHOW + "+";
}
private JComponent wrapLabel(@NotNull final JLabel label, @NotNull final ConfigurationError configurationError) {
final JPanel result = new JPanel(new BorderLayout());
result.setBackground(label.getBackground());
@@ -653,7 +653,9 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable,
public void onClick(MouseEvent e) {
final Object o = myModel.getElementAt(0);
if (o instanceof ConfigurationError) {
((ConfigurationError)o).ignore(!((ConfigurationError)o).isIgnored());
final ConfigurationError error = (ConfigurationError)o;
error.ignore(!error.isIgnored());
myModel.update(error);
updateView();
}
}
@@ -678,72 +680,92 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable,
}
}
//todo[nik] move to ContainerUtil after 11.1
@NotNull
private static <T> List<T> concat(@NotNull final List<? extends T> list1, @NotNull final List<? extends T> list2) {
return new AbstractList<T>() {
public T get(int index) {
if (index < list1.size()) {
return list1.get(index);
}
return list2.get(index - list1.size());
}
public int size() {
return list1.size() + list2.size();
}
};
}
private static class ConfigurationErrorsListModel extends AbstractListModel implements ConfigurationErrors, Disposable {
private MessageBusConnection myConnection;
private List<ConfigurationError> myErrorsList = new ArrayList<ConfigurationError>();
private Condition<ConfigurationError> myFilter;
private List<ConfigurationError> myNotIgnoredErrors = new ArrayList<ConfigurationError>();
private List<ConfigurationError> myAllErrors;
private List<ConfigurationError> myIgnoredErrors = new ArrayList<ConfigurationError>();
private ConfigurationErrorsListModel(@NotNull final Project project) {
setFilter(true, true);
myConnection = project.getMessageBus().connect();
myConnection.subscribe(TOPIC, this);
}
public void setFilter(Condition<ConfigurationError> filter) {
myFilter = filter;
public void setFilter(boolean showNotIgnored, boolean showIgnored) {
if (showIgnored && showNotIgnored) {
myAllErrors = concat(myNotIgnoredErrors, myIgnoredErrors);
}
else if (showIgnored) {
myAllErrors = myIgnoredErrors;
}
else {
myAllErrors = myNotIgnoredErrors;
}
}
@Override
public int getSize() {
return myFilter == null ? myErrorsList.size() : ContainerUtil.filter(myErrorsList, myFilter).size();
return Math.min(myAllErrors.size(), MAX_ERRORS_TO_SHOW);
}
@Override
public Object getElementAt(int index) {
return myFilter == null ? myErrorsList.get(index) : ContainerUtil.filter(myErrorsList, myFilter).get(index);
return myAllErrors.get(index);
}
private boolean accept(ConfigurationError error) {
return myFilter == null || myFilter.value(error);
}
@Override
public void addError(@NotNull ConfigurationError error) {
if (!myErrorsList.contains(error) && accept(error)) {
int ndx = 0;
if (error.isIgnored()) {
ndx = myErrorsList.size();
if (!myAllErrors.contains(error)) {
List<ConfigurationError> targetList = error.isIgnored() ? myIgnoredErrors : myNotIgnoredErrors;
if (targetList.size() < MAX_ERRORS_TO_SHOW) {
targetList.add(0, error);
}
else {
targetList.add(error);
}
myErrorsList.add(ndx, error);
fireIntervalAdded(this, ndx, ndx);
int i = myAllErrors.indexOf(error);
if (i != -1 && i < MAX_ERRORS_TO_SHOW) {
fireIntervalAdded(this, i, i);
}
}
}
@Override
public void removeError(@NotNull ConfigurationError error) {
if (myErrorsList.contains(error)) {
final int ndx = myErrorsList.indexOf(error);
myErrorsList.remove(ndx);
fireIntervalRemoved(this, ndx, ndx);
final int i = myAllErrors.indexOf(error);
myIgnoredErrors.remove(error);
myNotIgnoredErrors.remove(error);
if (i != -1 && i < MAX_ERRORS_TO_SHOW) {
fireIntervalRemoved(this, i, i);
}
}
public List<ConfigurationError> getErrors() {
return ContainerUtil.filter(myErrorsList, new Condition<ConfigurationError>() {
@Override
public boolean value(final ConfigurationError error) {
return !error.isIgnored();
}
});
return myNotIgnoredErrors;
}
public List<ConfigurationError> getIgnoredErrors() {
return ContainerUtil.filter(myErrorsList, new Condition<ConfigurationError>() {
@Override
public boolean value(final ConfigurationError error) {
return error.isIgnored();
}
});
return myIgnoredErrors;
}
@Override
@@ -755,9 +777,30 @@ public class ConfigurationErrorsComponent extends JPanel implements Disposable,
}
public void update(final ConfigurationError error) {
final int ndx = myErrorsList.indexOf(error);
if (ndx >= 0) {
fireContentsChanged(this, ndx, ndx);
final int i0 = myAllErrors.indexOf(error);
if (error.isIgnored()) {
if (myNotIgnoredErrors.remove(error)) {
myIgnoredErrors.add(0, error);
}
}
else {
if (myIgnoredErrors.remove(error)) {
myNotIgnoredErrors.add(0, error);
}
}
final int i1 = myAllErrors.indexOf(error);
if (i0 == i1 && i0 != -1) {
if (i0 < MAX_ERRORS_TO_SHOW) {
fireContentsChanged(this, i0, i0);
}
}
else {
if (i0 != -1 && i0 < MAX_ERRORS_TO_SHOW) {
fireIntervalRemoved(this, i0, i0);
}
if (i1 != -1 && i1 < MAX_ERRORS_TO_SHOW) {
fireIntervalAdded(this, i1, i1);
}
}
}
}
@@ -18,7 +18,7 @@ package com.intellij.openapi.roots.ui.configuration;
import com.intellij.compiler.ModuleCompilerUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootModel;
import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext;
import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.*;
import com.intellij.openapi.util.text.StringUtil;
@@ -49,14 +49,13 @@ public class GeneralProjectSettingsElement extends ProjectStructureElement {
@Override
public void check(ProjectStructureProblemsHolder problemsHolder) {
final Graph<Chunk<ModifiableRootModel>> graph = ModuleCompilerUtil.toChunkGraph(
myContext.getModulesConfigurator().createGraphGenerator());
final Collection<Chunk<ModifiableRootModel>> chunks = graph.getNodes();
final Graph<Chunk<ModuleRootModel>> graph = ModuleCompilerUtil.toChunkGraph(myContext.getModulesConfigurator().createGraphGenerator());
final Collection<Chunk<ModuleRootModel>> chunks = graph.getNodes();
List<String> cycles = new ArrayList<String>();
for (Chunk<ModifiableRootModel> chunk : chunks) {
final Set<ModifiableRootModel> modules = chunk.getNodes();
for (Chunk<ModuleRootModel> chunk : chunks) {
final Set<ModuleRootModel> modules = chunk.getNodes();
List<String> names = new ArrayList<String>();
for (ModifiableRootModel model : modules) {
for (ModuleRootModel model : modules) {
names.add(model.getModule().getName());
}
if (modules.size() > 1) {
@@ -213,10 +213,10 @@ public class ModulesConfigurator implements ModulesProvider, ModuleEditor.Change
myAllModulesChangeListeners.add(listener);
}
public GraphGenerator<ModifiableRootModel> createGraphGenerator() {
final Map<Module, ModifiableRootModel> models = new HashMap<Module, ModifiableRootModel>();
public GraphGenerator<ModuleRootModel> createGraphGenerator() {
final Map<Module, ModuleRootModel> models = new HashMap<Module, ModuleRootModel>();
for (ModuleEditor moduleEditor : myModuleEditors) {
models.put(moduleEditor.getModule(), moduleEditor.getModifiableRootModel());
models.put(moduleEditor.getModule(), moduleEditor.getRootModel());
}
return ModuleCompilerUtil.createGraphGenerator(models);
}
@@ -0,0 +1,164 @@
/*
* 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.impl.source.resolve.reference.impl;
import com.intellij.codeInsight.completion.InsertHandler;
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.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 org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
/**
* @author Konstantin Bulenkov
*/
public class JavaLangClassMemberReference extends PsiReferenceBase<PsiLiteralExpression> implements InsertHandler<LookupElement> {
private final PsiClassObjectAccessExpression myContext;
public JavaLangClassMemberReference(PsiLiteralExpression literal, PsiClassObjectAccessExpression context) {
super(literal);
myContext = context;
}
@Override
public PsiElement resolve() {
final String name = (String)getElement().getValue();
final Type type = getType();
if (type != null) {
final PsiClass psiClass = getPsiClass();
if (psiClass != null) {
PsiMember member;
if (type == Type.FIELD || type == Type.DECLARED_FIELD) {
member = psiClass.findFieldByName(name, false);
} else {
final PsiMethod[] methods = psiClass.findMethodsByName(name, false);
member = methods.length == 0 ? null : methods[0];
}
return member;
}
}
return null;
}
@Nullable
private PsiClass getPsiClass() {
return PsiTypesUtil.getPsiClass(myContext.getOperand().getType());
}
@Nullable
private Type getType() {
boolean selfFound = false;
for (PsiElement child : myContext.getParent().getChildren()) {
if (!selfFound) {
if (child == myContext) {
selfFound = true;
}
continue;
}
if (child instanceof PsiIdentifier) {
return Type.fromString(child.getText());
}
}
return null;
}
@NotNull
@Override
public Object[] getVariants() {
final Type type = getType();
final PsiClass psiClass = getPsiClass();
if (psiClass != null && type != null) {
if (type == Type.DECLARED_FIELD) {
return psiClass.getFields();
} else if (type == Type.FIELD) {
final List<PsiField> fields = new ArrayList<PsiField>();
for (PsiField field : psiClass.getFields()) {
if (isPublic(field)) {
fields.add(field);
}
}
return fields.toArray();
} else if (type == Type.DECLARED_METHOD || type == Type.METHOD) {
final List<LookupElementBuilder> elements = new ArrayList<LookupElementBuilder>();
for (PsiMethod method : psiClass.getMethods()) {
if (type == Type.DECLARED_METHOD || isPublic(method)) {
elements.add(JavaLookupElementBuilder.forMethod(method, PsiSubstitutor.EMPTY).setInsertHandler(this));
}
}
return elements.toArray();
}
}
return EMPTY_ARRAY;
}
@Override
public void handleInsert(InsertionContext context, LookupElement item) {
final Object object = item.getObject();
if (object instanceof PsiMethod) {
final PsiElement newElement = PsiUtilCore.getElementAtOffset(context.getFile(), context.getStartOffset());
final int start = newElement.getTextRange().getEndOffset();
final PsiElement params = newElement.getParent().getParent();
final int end = params.getTextRange().getEndOffset() - 1;
final String types = getMethodTypes((PsiMethod)object);
context.getDocument().replaceString(start, end, types);
context.commitDocument();
final PsiElement firstParam = PsiUtilCore.getElementAtOffset(context.getFile(), context.getStartOffset());
final PsiMethodCallExpression methodCall = PsiTreeUtil.getParentOfType(firstParam, PsiMethodCallExpression.class);
if (methodCall != null) {
JavaCodeStyleManager.getInstance(context.getProject()).shortenClassReferences(methodCall);
}
}
}
private static boolean isPublic(final PsiMember psiField) {
return psiField.hasModifierProperty(PsiModifier.PUBLIC);
}
private static String getMethodTypes(PsiMethod method) {
final StringBuilder buf = new StringBuilder();
for (PsiParameter parameter : method.getParameterList().getParameters()) {
buf.append(", ").append(parameter.getType().getCanonicalText()).append(".class");
}
return buf.toString();
}
enum Type {
FIELD, DECLARED_FIELD, METHOD, DECLARED_METHOD;
@Nullable
static Type fromString(String s) {
if ("getField".equals(s)) return FIELD;
if ("getDeclaredField".equals(s)) return DECLARED_FIELD;
if ("getMethod".equals(s)) return METHOD;
if ("getDeclaredMethod".equals(s)) return DECLARED_METHOD;
return null;
}
}
}
@@ -0,0 +1,47 @@
/*
* 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.impl.source.resolve.reference.impl;
import com.intellij.codeInsight.completion.CompletionConfidence;
import com.intellij.codeInsight.completion.CompletionParameters;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.ThreeState;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Konstantin Bulenkov
*/
public class JavaReflectionCompletionConfidence extends CompletionConfidence {
@NotNull
@Override
public ThreeState shouldFocusLookup(@NotNull CompletionParameters parameters) {
return ThreeState.UNSURE;
}
@NotNull
@Override
public ThreeState shouldSkipAutopopup(@Nullable PsiElement contextElement, @NotNull PsiFile psiFile, int offset) {
if (contextElement != null) {
final PsiElement literal = contextElement.getParent();
if (literal != null && JavaReflectionReferenceContributor.PATTERN.accepts(literal)) {
return ThreeState.NO;
}
}
return super.shouldSkipAutopopup(contextElement, psiFile, offset);
}
}
@@ -0,0 +1,44 @@
/*
* 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.impl.source.resolve.reference.impl;
import com.intellij.patterns.PsiJavaElementPattern;
import com.intellij.psi.PsiLiteral;
import com.intellij.psi.PsiReferenceContributor;
import com.intellij.psi.PsiReferenceRegistrar;
import static com.intellij.patterns.PsiJavaPatterns.psiExpression;
import static com.intellij.patterns.PsiJavaPatterns.psiLiteral;
import static com.intellij.patterns.PsiJavaPatterns.psiMethod;
import static com.intellij.patterns.StandardPatterns.string;
import static com.intellij.psi.CommonClassNames.JAVA_LANG_CLASS;
/**
* @author Konstantin Bulenkov
*/
public class JavaReflectionReferenceContributor extends PsiReferenceContributor {
public static final PsiJavaElementPattern.Capture<PsiLiteral> PATTERN =
psiLiteral().inside(psiExpression().methodCall(psiMethod().withName(string().oneOf("getDeclaredField",
"getField",
"getMethod",
"getDeclaredMethod"))
.definedInClass(JAVA_LANG_CLASS)));
@Override
public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
registrar.registerReferenceProvider(PATTERN, new JavaReflectionReferenceProvider());
}
}
@@ -0,0 +1,50 @@
/*
* 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.impl.source.resolve.reference.impl;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Konstantin Bulenkov
*/
public class JavaReflectionReferenceProvider extends PsiReferenceProvider {
@NotNull
@Override
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
if (element instanceof PsiLiteralExpression) {
String value = getValue(((PsiLiteralExpression)element));
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) {
return new PsiReference[]{new JavaLangClassMemberReference((PsiLiteralExpression)element, classAccess)};
}
}
}
return PsiReference.EMPTY_ARRAY;
}
@Nullable
private static String getValue(PsiLiteralExpression element) {
final Object value = element.getValue();
return value instanceof String ? (String)value : null;
}
}
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.completion.CompletionResultSet;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CustomShortcutSet;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorFontType;
@@ -29,6 +30,7 @@ import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
@@ -558,7 +560,7 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase<Paramet
final int newParametersNumber = parameterInfos.size();
for (int i = 0; i < newParametersNumber; i++) {
ParameterTableModelItemBase<ParameterInfoImpl> item = parameterInfos.get(i);
final ParameterTableModelItemBase<ParameterInfoImpl> item = parameterInfos.get(i);
if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isIdentifier(item.parameter.getName())) {
return RefactoringMessageUtil.getIncorrectIdentifierMessage(item.parameter.getName());
@@ -582,7 +584,12 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase<Paramet
}
if (item.parameter.oldParameterIndex < 0) {
item.parameter.defaultValue = item.defaultValueCodeFragment.getText();
item.parameter.defaultValue = ApplicationManager.getApplication().runWriteAction(new Computable<String>() {
@Override
public String compute() {
return JavaCodeStyleManager.getInstance(myProject).qualifyClassReferences(item.defaultValueCodeFragment).getText();
}
});
String def = item.parameter.defaultValue;
def = def.trim();
if (!(type instanceof PsiEllipsisType)) {
@@ -375,7 +375,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
else {
newArg = factory.createExpressionFromText(info.getName(), list);
}
list.add(newArg);
JavaCodeStyleManager.getInstance(list.getProject()).shortenClassReferences(list.add(newArg));
}
}
else {
@@ -630,7 +630,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
else {
actualArg = changeInfo.getValue(i, callExpression);
}
callExpression.getArgumentList().add(actualArg);
JavaCodeStyleManager.getInstance(callExpression.getProject()).shortenClassReferences(callExpression.getArgumentList().add(actualArg));
}
}
@@ -28,6 +28,7 @@ import com.intellij.openapi.keymap.Keymap;
import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
@@ -189,13 +190,15 @@ public class JavaVariableInplaceIntroducer extends InplaceVariableIntroducer<Psi
if (getExprMarker() != null && occurrenceMarker.getStartOffset() == getExprMarker().getStartOffset() && myExpr != null) {
continue;
}
if (AbstractJavaInplaceIntroducer
.restoreExpression(containingFile, (PsiVariable)vars[0], elementFactory, occurrenceMarker, myExpressionText) ==
null) {
return;
}
AbstractJavaInplaceIntroducer
.restoreExpression(containingFile, (PsiVariable)vars[0], elementFactory, occurrenceMarker, myExpressionText);
}
final PsiExpression initializer = ((PsiVariable)vars[0]).getInitializer();
if (initializer != null && Comparing.strEqual(initializer.getText(), myExpressionText)) {
element.replace(JavaPsiFacade.getInstance(myProject).getElementFactory().createStatementFromText(myExpressionText, element));
} else {
element.delete();
}
element.delete();
}
}
}
@@ -13,21 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.designer.clipboard;
/**
* This class must be in main classloader because of JVM's restrictions (it's used as DataFlavor class)
*
* @author yole
*/
public final class SerializedComponentData {
private final String mySerializedComponents;
public SerializedComponentData(String components) {
mySerializedComponents = components;
class DeclaredField {
void foo() {
Test.class.getDeclaredField("<caret>");
}
}
public String getSerializedComponents() {
return mySerializedComponents;
}
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 DeclaredField {
void foo() {
Test.class.getDeclaredField("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 DecalredMethod {
void foo() {
Test.class.getDeclaredMethod("<caret>");
}
}
class Test {
public void method(){}
public void method2(A a, B b){}
public 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 DecalredMethod2 {
void foo() {
Test.class.getDeclaredMethod("m<caret>", A.class, B.class);
}
}
class Test {
void method(){}
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 DecalredMethod2 {
void foo() {
Test.class.getDeclaredMethod("method3");
}
}
class Test {
void method(){}
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 DecalredMethod {
void foo() {
Test.class.getDeclaredMethod("method2", A.class, B.class);
}
}
class Test {
public void method(){}
public void method2(A a, B b){}
public 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 Field {
void foo() {
Test.class.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 Field {
void foo() {
Test.class.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 DecalredMethod {
void foo() {
Test.class.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 DecalredMethod {
void foo() {
Test.class.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 {}
@@ -0,0 +1,62 @@
/*
* 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.codeInsight.completion;
import com.intellij.JavaTestUtil;
/**
* @author Konstantin Bulenkov
*/
public class JavaReflectionCompletionTest extends LightFixtureCompletionTestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
}
@Override
protected String getBasePath() {
return JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/completion/reflection/";
}
public void testField() throws Exception {
doTest(1, "num", "num2");
}
public void testDeclaredField() throws Exception {
doTest(1, "num", "num2", "num3");
}
public void testDeclaredMethod() throws Exception {
doTest(1, "method", "method2", "method3");
}
public void testDeclaredMethod2() throws Exception {
doTest(2, "method", "method2", "method3");
}
public void testMethod() throws Exception {
doTest(1, "method", "method2");
}
private void doTest(int index, String... expected) {
configureByFile(getTestName(false) + ".java");
assertStringItems(expected);
selectItem(getLookup().getItems().get(index));
myFixture.checkResultByFile(getTestName(false) + "_after.java");
}
}
@@ -5,10 +5,8 @@ package org.jetbrains.jps.api;
* Date: 1/24/12
*/
public interface GlobalOptions {
String USE_MEMORY_TEMP_CACHE_OPTION = "use.memory.temp.cache";
String USE_EXTERNAL_JAVAC_OPTION = "use.external.javac.process";
String HOSTNAME_OPTION = "localhost.name";
String VM_EXE_PATH_OPTION = "vm.executable.path";
String PING_INTERVAL_MS_OPTION = "server.ping.interval";
}
@@ -13,6 +13,7 @@ import org.jetbrains.jps.incremental.messages.UptoDateFilesSavedEvent;
import org.jetbrains.jps.incremental.storage.BuildDataManager;
import org.jetbrains.jps.incremental.storage.SourceToOutputMapping;
import org.jetbrains.jps.incremental.storage.TimestampStorage;
import org.jetbrains.jps.server.ProjectDescriptor;
import java.io.File;
import java.io.IOException;
@@ -29,51 +30,40 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler
private final boolean myIsProjectRebuild;
private final ProjectChunks myProductionChunks;
private final ProjectChunks myTestChunks;
private final FSState myFsState;
private final MessageHandler myDelegateMessageHandler;
private volatile boolean myCompilingTests = false;
private final BuildDataManager myDataManager;
private final ModuleRootsIndex myRootsIndex;
private final Set<Pair<Module, DirtyMarkScope>> myNonIncrementalModules = new HashSet<Pair<Module, DirtyMarkScope>>();
private final ProjectPaths myProjectPaths;
private volatile boolean myErrorsFound = false;
private final long myCompilationStartStamp;
private final ProjectDescriptor myProjectDescriptor;
private final TimestampStorage myTsStorage;
private final BuildLoggingManager myLoggingManager;
private final Map<String, String> myBuilderParams;
private final CanceledStatus myCancelStatus;
private float myDone = -1.0f;
public CompileContext(CompileScope scope,
boolean isMake,
ProjectDescriptor pd, boolean isMake,
boolean isProjectRebuild,
ProjectChunks productionChunks,
ProjectChunks testChunks,
FSState fsState,
final BuildDataManager dataManager,
TimestampStorage tsStorage,
MessageHandler delegateMessageHandler,
final ModuleRootsIndex rootsIndex,
BuildLoggingManager loggingManager, Map<String, String> builderParams,
Map<String, String> builderParams,
CanceledStatus cancelStatus) throws ProjectBuildException {
myTsStorage = tsStorage;
myLoggingManager = loggingManager;
myProjectDescriptor = pd;
myTsStorage = myProjectDescriptor.timestamps.getStorage();
myBuilderParams = Collections.unmodifiableMap(builderParams);
myCancelStatus = cancelStatus;
myCompilationStartStamp = System.currentTimeMillis();
myScope = scope;
myIsProjectRebuild = isProjectRebuild;
myIsMake = isProjectRebuild? false : isMake;
myIsMake = !isProjectRebuild && isMake;
myProductionChunks = productionChunks;
myTestChunks = testChunks;
myFsState = fsState;
myDelegateMessageHandler = delegateMessageHandler;
myDataManager = dataManager;
final Project project = scope.getProject();
myProjectPaths = new ProjectPaths(project);
myRootsIndex = rootsIndex;
}
public Project getProject() {
@@ -93,7 +83,7 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler
}
public BuildLoggingManager getLoggingManager() {
return myLoggingManager;
return myProjectDescriptor.getLoggingManager();
}
@Nullable
@@ -104,26 +94,26 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler
public void markDirty(final File file) throws IOException {
final RootDescriptor descriptor = getModuleAndRoot(file);
if (descriptor != null) {
myFsState.markDirty(file, descriptor, myTsStorage);
myProjectDescriptor.fsState.markDirty(file, descriptor, myTsStorage);
}
}
public void markDirtyIfNotDeleted(final File file) throws IOException {
final RootDescriptor descriptor = getModuleAndRoot(file);
if (descriptor != null) {
myFsState.markDirtyIfNotDeleted(file, descriptor, myTsStorage);
myProjectDescriptor.fsState.markDirtyIfNotDeleted(file, descriptor, myTsStorage);
}
}
public void markDeleted(File file) throws IOException {
final RootDescriptor descriptor = getModuleAndRoot(file);
if (descriptor != null) {
myFsState.registerDeleted(descriptor.module, file, descriptor.isTestRoot, myTsStorage);
myProjectDescriptor.fsState.registerDeleted(descriptor.module, file, descriptor.isTestRoot, myTsStorage);
}
}
public void markDirty(final ModuleChunk chunk) throws IOException {
myFsState.clearContextRoundData();
myProjectDescriptor.fsState.clearContextRoundData();
final Set<Module> modules = chunk.getModules();
for (Module module : modules) {
markDirtyFiles(module, myTsStorage, true, isCompilingTests()? DirtyMarkScope.TESTS : DirtyMarkScope.PRODUCTION, null);
@@ -182,7 +172,7 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler
}
public Mappings createDelta() {
return myDataManager.getMappings().createDelta();
return getDataManager().getMappings().createDelta();
}
public boolean isCompilingTests() {
@@ -208,18 +198,18 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler
}
void beforeCompileRound(@NotNull ModuleChunk chunk) {
myFsState.beforeNextRoundStart();
myProjectDescriptor.fsState.beforeNextRoundStart();
}
public void onChunkBuildStart(ModuleChunk chunk) {
myFsState.setContextChunk(chunk);
myProjectDescriptor.fsState.setContextChunk(chunk);
}
void onChunkBuildComplete(@NotNull ModuleChunk chunk) throws IOException {
myDataManager.closeSourceToOutputStorages(chunk, isCompilingTests());
myDataManager.flush(true);
myFsState.clearContextRoundData();
myFsState.clearContextChunk();
getDataManager().closeSourceToOutputStorages(chunk, isCompilingTests());
getDataManager().flush(true);
myProjectDescriptor.fsState.clearContextRoundData();
myProjectDescriptor.fsState.clearContextChunk();
if (!myErrorsFound && !myCancelStatus.isCanceled()) {
final boolean compilingTests = isCompilingTests();
@@ -231,12 +221,12 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler
myNonIncrementalModules.remove(new Pair<Module, DirtyMarkScope>(module, dirtyScope));
}
if (isProjectRebuild()) {
myFsState.markInitialScanPerformed(module, compilingTests);
myProjectDescriptor.fsState.markInitialScanPerformed(module, compilingTests);
}
final List<RootDescriptor> roots = myRootsIndex.getModuleRoots(module);
final List<RootDescriptor> roots = myProjectDescriptor.rootsIndex.getModuleRoots(module);
for (RootDescriptor descriptor : roots) {
if (compilingTests? descriptor.isTestRoot : !descriptor.isTestRoot) {
marked |= myFsState.markAllUpToDate(getScope(), descriptor, myTsStorage, myCompilationStartStamp);
marked |= myProjectDescriptor.fsState.markAllUpToDate(getScope(), descriptor, myTsStorage, myCompilationStartStamp);
}
}
}
@@ -251,7 +241,7 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler
}
public BuildDataManager getDataManager() {
return myDataManager;
return myProjectDescriptor.dataManager;
}
public TimestampStorage getTimestampStorage() {
@@ -274,7 +264,7 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler
public void processFilesToRecompile(ModuleChunk chunk, FileProcessor processor) throws IOException {
for (Module module : chunk.getModules()) {
myFsState.processFilesToRecompile(this, module, processor);
myProjectDescriptor.fsState.processFilesToRecompile(this, module, processor);
}
}
@@ -285,7 +275,7 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler
}
else {
if (isMake()) {
if (myFsState.markInitialScanPerformed(module, isCompilingTests())) {
if (myProjectDescriptor.fsState.markInitialScanPerformed(module, isCompilingTests())) {
initModuleFSState(module);
}
}
@@ -310,7 +300,7 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler
// can check if the file exists
final File file = new File(path);
if (!currentFiles.contains(file)) {
myFsState.registerDeleted(module, file, isCompilingTests(), myTsStorage);
myProjectDescriptor.fsState.registerDeleted(module, file, isCompilingTests(), myTsStorage);
}
}
}
@@ -322,16 +312,16 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler
@Nullable
public RootDescriptor getModuleAndRoot(File file) {
return myRootsIndex.getModuleAndRoot(file);
return getRootsIndex().getModuleAndRoot(file);
}
@NotNull
public List<RootDescriptor> getModuleRoots(Module module) {
return myRootsIndex.getModuleRoots(module);
return getRootsIndex().getModuleRoots(module);
}
public ModuleRootsIndex getRootsIndex() {
return myRootsIndex;
return myProjectDescriptor.rootsIndex;
}
public void setDone(float done) {
@@ -339,6 +329,10 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler
//processMessage(new ProgressMessage("", done));
}
public ProjectDescriptor getProjectDescriptor() {
return myProjectDescriptor;
}
public static enum DirtyMarkScope{
PRODUCTION, TESTS, BOTH
}
@@ -362,8 +356,8 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler
if (!rd.root.exists()) {
continue;
}
myFsState.clearRecompile(rd);
myFsState.clearDeletedPaths(module, isCompilingTests());
myProjectDescriptor.fsState.clearRecompile(rd);
myProjectDescriptor.fsState.clearDeletedPaths(module, isCompilingTests());
traverseRecursively(rd, rd.root, excludes, tsStorage, forceMarkDirty, currentFiles);
}
}
@@ -386,7 +380,7 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler
// if it is full project rebuild, all storages are already completely cleared;
// so passing null because there is no need to access the storage to clear non-existing data
final TimestampStorage _tsStorage = isProjectRebuild() ? null : tsStorage;
myFsState.markDirty(file, rd, _tsStorage);
myProjectDescriptor.fsState.markDirty(file, rd, _tsStorage);
}
if (currentFiles != null) {
currentFiles.add(file);
@@ -19,7 +19,6 @@ import org.jetbrains.jps.incremental.messages.ProgressMessage;
import org.jetbrains.jps.incremental.storage.BuildDataManager;
import org.jetbrains.jps.incremental.storage.SourceToFormMapping;
import org.jetbrains.jps.incremental.storage.SourceToOutputMapping;
import org.jetbrains.jps.incremental.storage.TimestampStorage;
import org.jetbrains.jps.server.ProjectDescriptor;
import java.io.File;
@@ -217,13 +216,9 @@ public class IncProjectBuilder {
}
private CompileContext createContext(CompileScope scope, boolean isMake, final boolean isProjectRebuild) throws ProjectBuildException {
final TimestampStorage tsStorage = myProjectDescriptor.timestamps.getStorage();
final FSState fsState = myProjectDescriptor.fsState;
final ModuleRootsIndex rootsIndex = myProjectDescriptor.rootsIndex;
final BuildDataManager dataManager = myProjectDescriptor.dataManager;
return new CompileContext(
scope, isMake, isProjectRebuild, myProductionChunks, myTestChunks, fsState, dataManager, tsStorage, myMessageDispatcher, rootsIndex,
myProjectDescriptor.getLoggingManager(), myBuilderParams, myCancelStatus
scope, myProjectDescriptor, isMake, isProjectRebuild, myProductionChunks, myTestChunks, myMessageDispatcher,
myBuilderParams, myCancelStatus
);
}
@@ -11,6 +11,7 @@ import com.intellij.uiDesigner.compiler.*;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.lw.CompiledClassPropertiesProvider;
import com.intellij.uiDesigner.lw.LwRootContainer;
import com.intellij.util.SystemProperties;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.ether.dependencyView.Callbacks;
@@ -30,7 +31,8 @@ import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.EmptyVisitor;
import javax.tools.*;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import java.io.*;
import java.net.MalformedURLException;
import java.net.ServerSocket;
@@ -46,6 +48,7 @@ import java.util.concurrent.TimeUnit;
*/
public class JavaBuilder extends ModuleLevelBuilder {
public static final String BUILDER_NAME = "java";
private static final String FORMS_BUILDER_NAME = "forms";
private static final String JAVA_EXTENSION = ".java";
private static final String FORM_EXTENSION = ".form";
public static final boolean USE_EMBEDDED_JAVAC = System.getProperty(GlobalOptions.USE_EXTERNAL_JAVAC_OPTION) == null;
@@ -421,21 +424,31 @@ public class JavaBuilder extends ModuleLevelBuilder {
});
}
private static JavacServerClient ensureJavacServerLaunched(CompileContext context) throws Exception {
final ExternalJavacDescriptor descriptor = ExternalJavacDescriptor.KEY.get(context);
if (descriptor != null) {
return descriptor.client;
}
// start server here
final String vmExecPath = System.getProperty(GlobalOptions.VM_EXE_PATH_OPTION, System.getProperty("java.home") + "/bin/java");
final String hostString = System.getProperty(GlobalOptions.HOSTNAME_OPTION, "localhost");
final int port = findFreePort();
final int heapSize = getJavacServerHeapSize(context);
// defaulting to the same jdk that used to run the server
String javaHome = SystemProperties.getJavaHome();
int javaVersion = convertToNumber(SystemProperties.getJavaVersion());
for (JavaSdk sdk : context.getProjectDescriptor().getProjectJavaSdks()) {
final String version = sdk.getVersion();
final int ver = convertToNumber(version);
if (ver > javaVersion) {
javaVersion = ver;
javaHome = sdk.getHomePath();
}
}
final BaseOSProcessHandler processHandler = JavacServerBootstrap.launchJavacServer(
vmExecPath, heapSize, port, Paths.getSystemRoot(), getCompilationVMOptions(context)
javaHome, heapSize, port, Paths.getSystemRoot(), getCompilationVMOptions(context)
);
final JavacServerClient client = new JavacServerClient();
try {
@@ -449,6 +462,26 @@ public class JavaBuilder extends ModuleLevelBuilder {
return client;
}
private static int convertToNumber(final String ver) {
final String prefix = "1.";
if (ver.startsWith(prefix)) {
final String versionNumberString;
final int dotIndex = ver.indexOf(".", prefix.length());
if (dotIndex > 0) {
versionNumberString = ver.substring(prefix.length(), dotIndex);
}
else {
versionNumberString = ver.substring(prefix.length());
}
try {
return Integer.parseInt(versionNumberString);
}
catch (NumberFormatException ignored) {
}
}
return 0;
}
private static int findFreePort() {
try {
final ServerSocket serverSocket = new ServerSocket(0);
@@ -711,7 +744,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
if (alreadyProcessedForm != null) {
context.processMessage(
new CompilerMessage(
BUILDER_NAME, BuildMessage.Kind.WARNING,
FORMS_BUILDER_NAME, BuildMessage.Kind.WARNING,
formFile.getAbsolutePath() + ": The form is bound to the class " + classToBind + ".\nAnother form " + alreadyProcessedForm.getAbsolutePath() + " is also bound to this class",
formFile.getAbsolutePath())
);
@@ -737,7 +770,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
final FormErrorInfo[] warnings = codeGenerator.getWarnings();
for (final FormErrorInfo warning : warnings) {
context.processMessage(
new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.WARNING, warning.getErrorMessage(), formFile.getAbsolutePath()));
new CompilerMessage(FORMS_BUILDER_NAME, BuildMessage.Kind.WARNING, warning.getErrorMessage(), formFile.getAbsolutePath()));
}
final FormErrorInfo[] errors = codeGenerator.getErrors();
@@ -750,7 +783,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
}
message.append(formFile.getAbsolutePath()).append(": ").append(error.getErrorMessage());
}
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, message.toString()));
context.processMessage(new CompilerMessage(FORMS_BUILDER_NAME, BuildMessage.Kind.ERROR, message.toString()));
}
else {
final File sourceFile = outputClassFile.getSourceFile();
@@ -761,7 +794,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
}
catch (Exception e) {
success = false;
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, "Forms instrumentation failed" + e.getMessage(),
context.processMessage(new CompilerMessage(FORMS_BUILDER_NAME, BuildMessage.Kind.ERROR, "Forms instrumentation failed" + e.getMessage(),
formFile.getAbsolutePath()));
}
finally {
@@ -22,14 +22,9 @@ import java.util.List;
*/
public class JavacServerBootstrap {
public static BaseOSProcessHandler launchJavacServer(String vmExecutablePath,
int heapSize,
int port,
File workingDir,
List<String> vmOptions) throws Exception {
public static BaseOSProcessHandler launchJavacServer(String sdkHomePath, int heapSize, int port, File workingDir, List<String> vmOptions) throws Exception {
final List<String> cmdLine = new ArrayList<String>();
appendParam(cmdLine, vmExecutablePath);
appendParam(cmdLine, getVMExecutablePath(sdkHomePath));
appendParam(cmdLine, "-server");
appendParam(cmdLine, "-XX:MaxPermSize=150m");
//appendParam(cmdLine, "-XX:ReservedCodeCacheSize=64m");
@@ -64,7 +59,7 @@ public class JavacServerBootstrap {
appendParam(cmdLine, "-classpath");
final List<File> cp = ClasspathBootstrap.getJavacServerClasspath();
final List<File> cp = ClasspathBootstrap.getJavacServerClasspath(sdkHomePath);
final StringBuilder classpath = new StringBuilder();
for (File file : cp) {
if (classpath.length() > 0) {
@@ -155,4 +150,8 @@ public class JavacServerBootstrap {
}
cmdLine.add(param);
}
public static String getVMExecutablePath(String sdkHome) {
return sdkHome + "/bin/java";
}
}
@@ -18,8 +18,11 @@ package org.jetbrains.jps.server;
import com.google.protobuf.Message;
import com.intellij.compiler.notNullVerification.NotNullVerifyingInstrumenter;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.uiDesigner.compiler.AlienFormFileException;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.util.SystemProperties;
import com.jgoodies.forms.layout.CellConstraints;
import net.n3.nanoxml.IXMLBuilder;
import org.codehaus.groovy.GroovyException;
@@ -30,16 +33,21 @@ import org.jetbrains.jps.javac.JavacServer;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.commons.EmptyVisitor;
import javax.tools.*;
import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.util.*;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
/**
* @author Eugene Zhuravlev
* Date: 9/12/11
*/
public class ClasspathBootstrap {
public static final String JPS_RUNTIME_PATH = "rt/jps-incremental";
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.server.ClasspathBootstrap");
private static class OptimizedFileManagerClassHolder {
static final String CLASS_NAME = "org.jetbrains.jps.javac.OptimizedFileManager";
@@ -119,31 +127,47 @@ public class ClasspathBootstrap {
return new ArrayList<File>(cp);
}
public static List<File> getJavacServerClasspath() {
public static List<File> getJavacServerClasspath(String sdkHome) {
final Set<File> cp = new LinkedHashSet<File>();
cp.add(getResourcePath(JavacServer.class));
for (String path : PathManager.getUtilClassPath()) { cp.add(new File(path)); } // util
cp.add(getResourcePath(JavacServer.class)); // self
// util
for (String path : PathManager.getUtilClassPath()) {
cp.add(new File(path));
}
cp.add(getResourcePath(Message.class)); // protobuf
cp.add(getResourcePath(Version.class)); // netty
final Class<StandardJavaFileManager> optimizedFileManagerClass = getOptimizedFileManagerClass();
if (optimizedFileManagerClass != null) {
cp.add(getResourcePath(optimizedFileManagerClass)); // optimizedFileManager
cp.add(getResourcePath(optimizedFileManagerClass)); // optimizedFileManager, if applicable
}
try {
final Class<?> cmdLineWrapper = Class.forName("com.intellij.rt.execution.CommandLineWrapper");
cp.add(getResourcePath(cmdLineWrapper)); // idea_rt.jar
}
catch (Throwable ignored) {
catch (Throwable th) {
LOG.info(th);
}
final JavaCompiler systemCompiler = ToolProvider.getSystemJavaCompiler();
if (systemCompiler != null) {
try {
cp.add(getResourcePath(systemCompiler.getClass())); // tools.jar
final String localJarPath = FileUtil.toSystemIndependentName(getResourcePath(systemCompiler.getClass()).getPath());
final String localJavaHome = SystemProperties.getJavaHome();
String relPath = FileUtil.getRelativePath(FileUtil.toSystemIndependentName(localJavaHome), localJarPath, '/');
if (relPath != null) {
if (relPath.contains("..")) {
relPath = FileUtil.getRelativePath(FileUtil.toSystemIndependentName(new File(localJavaHome).getParent()), localJarPath, '/');
}
if (relPath != null) {
final File targetFile = new File(sdkHome +"/" +relPath);
cp.add(targetFile); // tools.jar
}
}
}
catch (Throwable ignored) {
catch (Throwable th) {
LOG.info(th);
}
}
@@ -1,6 +1,9 @@
package org.jetbrains.jps.server;
import org.jetbrains.jps.JavaSdk;
import org.jetbrains.jps.Module;
import org.jetbrains.jps.Project;
import org.jetbrains.jps.Sdk;
import org.jetbrains.jps.incremental.BuildLoggingManager;
import org.jetbrains.jps.incremental.FSState;
import org.jetbrains.jps.incremental.ModuleRootsIndex;
@@ -8,6 +11,8 @@ import org.jetbrains.jps.incremental.storage.BuildDataManager;
import org.jetbrains.jps.incremental.storage.ProjectTimestamps;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
/**
* @author Eugene Zhuravlev
@@ -21,6 +26,7 @@ public final class ProjectDescriptor {
private final BuildLoggingManager myLoggingManager;
public ModuleRootsIndex rootsIndex;
private int myUseCounter = 1;
private Set<JavaSdk> myProjectJavaSdks;
public ProjectDescriptor(Project project,
FSState fsState,
@@ -33,6 +39,20 @@ public final class ProjectDescriptor {
this.dataManager = dataManager;
myLoggingManager = loggingManager;
this.rootsIndex = new ModuleRootsIndex(project);
myProjectJavaSdks = new HashSet<JavaSdk>();
for (Module module : project.getModules().values()) {
final Sdk sdk = module.getSdk();
if (sdk instanceof JavaSdk && !myProjectJavaSdks.contains(sdk)) {
final JavaSdk javaSdk = (JavaSdk)sdk;
if (javaSdk.getVersion() != null && javaSdk.getHomePath() != null) {
myProjectJavaSdks.add(javaSdk);
}
}
}
}
public Set<JavaSdk> getProjectJavaSdks() {
return myProjectJavaSdks;
}
public BuildLoggingManager getLoggingManager() {
@@ -365,7 +365,9 @@ class ClassfileAnalyzer {
public FieldVisitor visitField(int access, String n, String desc, String signature, Object value) {
processSignature(signature);
fields.add(new FieldRepr(context, access, context.get(n), context.get(desc), context.get(signature), value));
if ((access & Opcodes.ACC_SYNTHETIC) == 0) {
fields.add(new FieldRepr(context, access, context.get(n), context.get(desc), context.get(signature), value));
}
return new EmptyVisitor() {
@Override
@@ -388,7 +390,9 @@ class ClassfileAnalyzer {
return new EmptyVisitor() {
@Override
public void visitEnd() {
methods.add(new MethodRepr(context, access, context.get(n), context.get(signature), desc, exceptions, defaultValue.get()));
if ((access & Opcodes.ACC_SYNTHETIC) == 0 || (access & Opcodes.ACC_BRIDGE) > 0) {
methods.add(new MethodRepr(context, access, context.get(n), context.get(signature), desc, exceptions, defaultValue.get()));
}
}
@Override
+14 -2
View File
@@ -1,5 +1,7 @@
package org.jetbrains.jps
import org.jetbrains.annotations.Nullable
/**
* @author Eugene.Kudelevsky
*/
@@ -12,7 +14,17 @@ public abstract class JavaSdk extends Sdk {
super(project, name, initializer)
}
abstract String getJavacExecutable();
@Nullable
public String getHomePath() {
return null;
}
abstract String getJavaExecutable();
@Nullable
public String getVersion() {
return null;
}
public abstract String getJavacExecutable();
public abstract String getJavaExecutable();
}
@@ -15,11 +15,21 @@ class JavaSdkImpl extends JavaSdk {
this.jdkPath = jdkPath
}
String getJavacExecutable() {
@Override
public String getHomePath() {
return jdkPath;
}
@Override
public String getVersion() {
return version;
}
public String getJavacExecutable() {
return jdkPath + File.separator + "bin" + File.separator + "javac";
}
String getJavaExecutable() {
public String getJavaExecutable() {
return jdkPath + File.separator + "bin" + File.separator + "java";
}
}
@@ -180,8 +180,6 @@ abstract class CharArray implements CharSequenceBackedByArray {
}
private void assertConsistency() {
if (!myDebug) return;
if (isDeferredChangeMode()) {
assert myOriginalSequence == null;
}
@@ -194,6 +192,8 @@ abstract class CharArray implements CharSequenceBackedByArray {
int count = myCount + myDeferredShift;
assert count == origLen || origLen==-1;
assert count == stringLen || stringLen==-1;
if (!myDebug) return;
final String stringFromCharArray;
if (myArray != null) {
@@ -72,7 +72,7 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
private int myCheckGuardedBlocks = 0;
private boolean myGuardsSuppressed = false;
private boolean myEventsHandling = false;
private final boolean myAssertWriteAccess;
private final boolean myAssertThreading;
private volatile boolean myDoingBulkUpdate = false;
private volatile boolean myAcceptSlashR = false;
private boolean myChangeInProgress;
@@ -90,7 +90,7 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
myLineSet.documentCreated(this);
setCyclicBufferSize(0);
setModificationStamp(LocalTimeCounter.currentTime());
myAssertWriteAccess = !forUseInNonAWTThread;
myAssertThreading = !forUseInNonAWTThread;
}
public boolean setAcceptSlashR(boolean accept) {
@@ -424,7 +424,7 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
}
private void assertWriteAccess() {
if (myAssertWriteAccess) {
if (myAssertThreading) {
final Application application = ApplicationManager.getApplication();
if (application != null) {
application.assertWriteAccessAllowed();
@@ -826,14 +826,12 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
@Override
protected void assertReadAccess() {
DocumentImpl.assertReadAccess();
}
}
private static void assertReadAccess() {
final Application application = ApplicationManager.getApplication();
if (application != null) {
application.assertReadAccessAllowed();
if (myAssertThreading) {
final Application application = ApplicationManager.getApplication();
if (application != null) {
application.assertReadAccessAllowed();
}
}
}
}
}
@@ -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) {
@@ -32,6 +32,8 @@ import com.intellij.profile.codeInspection.InspectionProfileManager;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashMap;
import gnu.trove.TObjectIntHashMap;
import gnu.trove.TObjectIntProcedure;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -52,7 +54,7 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
private final Map<String, Color> ourRendererColors = new THashMap<String, Color>();
@NonNls private static final String COLOR = "color";
private final JDOMExternalizableStringList myOrder = new JDOMExternalizableStringList();
private final TObjectIntHashMap<HighlightSeverity> myOrder = new TObjectIntHashMap<HighlightSeverity>();
private JDOMExternalizableStringList myReadOrder;
private static final Map<String, HighlightInfoType> STANDARD_SEVERITIES = new THashMap<String, HighlightInfoType>();
@@ -161,38 +163,51 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
}
}
myOrder.clear();
myOrder.readExternal(element);
myReadOrder = new JDOMExternalizableStringList();
myReadOrder.addAll(myOrder);
final List<String> knownSeverities = getDefaultOrder();
myOrder.retainAll(knownSeverities);
myReadOrder.readExternal(element);
for (int i = 0; i < myReadOrder.size(); i++) {
String name = myReadOrder.get(i);
HighlightSeverity severity = getSeverity(name);
if (severity == null) continue;
myOrder.put(severity, i);
}
final List<HighlightSeverity> knownSeverities = getDefaultOrder();
myOrder.retainEntries(new TObjectIntProcedure<HighlightSeverity>() {
@Override
public boolean execute(HighlightSeverity severity, int order) {
return knownSeverities.contains(severity);
}
});
if (myOrder.isEmpty()) {
myOrder.addAll(knownSeverities);
setFromList(knownSeverities);
}
//enforce include all known
List<HighlightSeverity> list = getOrderAsList();
for (int i = 0; i < knownSeverities.size(); i++) {
String stdSeverity = knownSeverities.get(i);
if (!myOrder.contains(stdSeverity)) {
for (int oIdx = 0; oIdx < myOrder.size(); oIdx++) {
final String orderSeverity = myOrder.get(oIdx);
final HighlightInfoType type = STANDARD_SEVERITIES.get(orderSeverity);
if (type != null && knownSeverities.indexOf(type.getSeverity(null).toString()) > i) {
myOrder.add(oIdx, stdSeverity);
HighlightSeverity stdSeverity = knownSeverities.get(i);
if (!list.contains(stdSeverity)) {
for (int oIdx = 0; oIdx < list.size(); oIdx++) {
HighlightSeverity orderSeverity = list.get(oIdx);
HighlightInfoType type = STANDARD_SEVERITIES.get(orderSeverity.toString());
if (type != null && knownSeverities.indexOf(type.getSeverity(null)) > i) {
list.add(oIdx, stdSeverity);
myReadOrder = null;
break;
}
}
}
}
setFromList(list);
}
@Override
public void writeExternal(Element element) throws WriteExternalException {
for (String severity : getOrder()) {
List<HighlightSeverity> list = getOrderAsList();
for (HighlightSeverity s : list) {
Element info = new Element(INFO);
String severity = s.toString();
final SeverityBasedTextAttributes infoType = ourMap.get(severity);
if (infoType != null) {
infoType.writeExternal(info);
@@ -203,29 +218,57 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
element.addContent(info);
}
}
if (myReadOrder != null && !myReadOrder.isEmpty()) {
myReadOrder.writeExternal(element);
}
else {
if (!getDefaultOrder().equals(getOrder())) {
getOrder().writeExternal(element);
}
else if (!getDefaultOrder().equals(list)) {
final JDOMExternalizableStringList ext = new JDOMExternalizableStringList(Collections.nCopies(myOrder.size(), ""));
myOrder.forEachEntry(new TObjectIntProcedure<HighlightSeverity>() {
@Override
public boolean execute(HighlightSeverity orderSeverity, int oIdx) {
ext.set(oIdx, orderSeverity.toString());
return true;
}
});
ext.writeExternal(element);
}
}
@NotNull
private List<HighlightSeverity> getOrderAsList() {
List<HighlightSeverity> list = new ArrayList<HighlightSeverity>();
for (Object o : getOrder().keys()) {
list.add((HighlightSeverity)o);
}
Collections.sort(list, this);
return list;
}
public int getSeveritiesCount() {
return createCurrentSeverities().size();
}
public HighlightSeverity getSeverityByIndex(final int i) {
return getSeverity(getOrder().get(i));
final HighlightSeverity[] found = new HighlightSeverity[1];
getOrder().forEachEntry(new TObjectIntProcedure<HighlightSeverity>() {
@Override
public boolean execute(HighlightSeverity severity, int order) {
if (order == i) {
found[0] = severity;
return false;
}
return true;
}
});
return found[0];
}
public int getSeverityMaxIndex() {
return getOrder().size();
}
public HighlightSeverity getSeverity(final String name) {
public HighlightSeverity getSeverity(@NotNull String name) {
final HighlightInfoType type = STANDARD_SEVERITIES.get(name);
if (type != null) return type.getSeverity(null);
final SeverityBasedTextAttributes attributes = ourMap.get(name);
@@ -233,6 +276,7 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
return null;
}
@NotNull
private List<String> createCurrentSeverities() {
List<String> list = new ArrayList<String>();
list.addAll(STANDARD_SEVERITIES.keySet());
@@ -241,7 +285,7 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
return list;
}
public Icon getRendererIconByIndex(final int i) {
public Icon getRendererIconByIndex(int i) {
final HighlightSeverity severity = getSeverityByIndex(i);
HighlightDisplayLevel level = HighlightDisplayLevel.find(severity);
if (level != null) {
@@ -251,23 +295,36 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
return HighlightDisplayLevel.createIconByMask(ourRendererColors.get(severity.toString()));
}
public boolean isSeverityValid(final String severity) {
public boolean isSeverityValid(@NotNull String severity) {
return createCurrentSeverities().contains(severity);
}
@Override
public int compare(final HighlightSeverity s1, final HighlightSeverity s2) {
return getOrder().indexOf(s1.myName) - getOrder().indexOf(s2.myName);
TObjectIntHashMap<HighlightSeverity> order = getOrder();
return order.get(s1) - order.get(s2);
}
private JDOMExternalizableStringList getOrder() {
@NotNull
private TObjectIntHashMap<HighlightSeverity> getOrder() {
if (myOrder.isEmpty()) {
myOrder.addAll(getDefaultOrder());
List<HighlightSeverity> order = getDefaultOrder();
setFromList(order);
}
return myOrder;
}
private List<String> getDefaultOrder() {
private void setFromList(@NotNull List<HighlightSeverity> order) {
myOrder.clear();
for (int i = 0; i < order.size(); i++) {
HighlightSeverity severity = order.get(i);
myOrder.put(severity, i);
}
}
@NotNull
private List<HighlightSeverity> getDefaultOrder() {
Collection<SeverityBasedTextAttributes> values = ourMap.values();
List<HighlightSeverity> order = new ArrayList<HighlightSeverity>(STANDARD_SEVERITIES.size() + values.size());
for (HighlightInfoType type : STANDARD_SEVERITIES.values()) {
@@ -277,29 +334,23 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
order.add(attributes.getSeverity());
}
ContainerUtil.sort(order);
List<String> result = new ArrayList<String>(order.size());
for (HighlightSeverity severity : order) {
result.add(severity.toString());
}
return result;
return order;
}
public void setOrder(List<String> order) {
myOrder.clear();
myOrder.addAll(order);
public void setOrder(@NotNull List<HighlightSeverity> order) {
setFromList(order);
myReadOrder = null;
}
public int getSeverityIdx(@NotNull HighlightSeverity severity) {
return getOrder().indexOf(severity.toString());
return getOrder().get(severity);
}
public boolean isDefaultSeverity(HighlightSeverity severity) {
public boolean isDefaultSeverity(@NotNull HighlightSeverity severity) {
return STANDARD_SEVERITIES.containsKey(severity.myName);
}
public static boolean isGotoBySeverityEnabled(HighlightSeverity minSeverity) {
public static boolean isGotoBySeverityEnabled(@NotNull HighlightSeverity minSeverity) {
for (SeveritiesProvider provider : Extensions.getExtensions(SeveritiesProvider.EP_NAME)) {
if (provider.isGotoBySeverityEnabled(minSeverity)) return true;
}
@@ -80,6 +80,7 @@ public class SeverityEditorDialog extends DialogWrapper {
super(parent, true);
mySeverityRegistrar = severityRegistrar;
myOptionsList.setCellRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
final Component rendererComponent = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof SeverityBasedTextAttributes) {
@@ -89,6 +90,7 @@ public class SeverityEditorDialog extends DialogWrapper {
}
});
myOptionsList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
if (myCurrentSelection != null) {
apply(myCurrentSelection);
@@ -110,6 +112,7 @@ public class SeverityEditorDialog extends DialogWrapper {
InspectionsBundle.message("highlight.severity.create.dialog.title"),
Messages.getQuestionIcon(),
"", new InputValidator() {
@Override
public boolean checkInput(final String inputString) {
final ListModel listModel = myOptionsList.getModel();
for (int i = 0; i < listModel.getSize(); i++) {
@@ -119,6 +122,7 @@ public class SeverityEditorDialog extends DialogWrapper {
return true;
}
@Override
public boolean canClose(final String inputString) {
return checkInput(inputString);
}
@@ -201,6 +205,7 @@ public class SeverityEditorDialog extends DialogWrapper {
final JPanel disabled = new JPanel(new GridBagLayout());
final JButton button = new JButton(InspectionsBundle.message("severities.default.settings.message"));
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
editColorsAndFonts();
}
@@ -230,6 +235,7 @@ public class SeverityEditorDialog extends DialogWrapper {
final SearchableConfigurable javaPage = colorAndFontOptions.findSubConfigurable(InspectionColorSettingsPage.class);
LOG.assertTrue(javaPage != null);
optionsEditor.select(javaPage).doWhenDone(new Runnable() {
@Override
public void run() {
final Runnable runnable = javaPage.enableSearch(toConfigure);
if (runnable != null) {
@@ -261,6 +267,7 @@ public class SeverityEditorDialog extends DialogWrapper {
final List<SeverityRegistrar.SeverityBasedTextAttributes> infoTypes = new ArrayList<SeverityRegistrar.SeverityBasedTextAttributes>();
infoTypes.addAll(mySeverityRegistrar.getRegisteredHighlightingInfoTypes());
Collections.sort(infoTypes, new Comparator<SeverityRegistrar.SeverityBasedTextAttributes>() {
@Override
public int compare(SeverityBasedTextAttributes attributes1,
SeverityBasedTextAttributes attributes2) {
return -mySeverityRegistrar.compare(attributes1.getSeverity(), attributes2.getSeverity());
@@ -306,16 +313,17 @@ public class SeverityEditorDialog extends DialogWrapper {
myOptionsPanel.reset(description);
}
@Override
protected void doOKAction() {
apply((SeverityBasedTextAttributes)myOptionsList.getSelectedValue());
final Collection<SeverityRegistrar.SeverityBasedTextAttributes> infoTypes =
new HashSet<SeverityRegistrar.SeverityBasedTextAttributes>(mySeverityRegistrar.getRegisteredHighlightingInfoTypes());
final ListModel listModel = myOptionsList.getModel();
final List<String> order = new ArrayList<String>();
final List<HighlightSeverity> order = new ArrayList<HighlightSeverity>();
for (int i = listModel.getSize() - 1; i >= 0; i--) {
final SeverityBasedTextAttributes info =
(SeverityBasedTextAttributes)listModel.getElementAt(i);
order.add(info.getSeverity().myName);
order.add(info.getSeverity());
if (!mySeverityRegistrar.isDefaultSeverity(info.getSeverity())) {
infoTypes.remove(info);
final Color stripeColor = info.getAttributes().getErrorStripeColor();
@@ -329,6 +337,7 @@ public class SeverityEditorDialog extends DialogWrapper {
super.doOKAction();
}
@Override
@Nullable
protected JComponent createCenterPanel() {
return myPanel;
@@ -349,15 +358,18 @@ public class SeverityEditorDialog extends DialogWrapper {
super(name, group, attributes, type, null, null, null);
}
@Override
public void apply(EditorColorsScheme scheme) {
}
@Override
public boolean isErrorStripeEnabled() {
return true;
}
@Override
public TextAttributes getTextAttributes() {
return super.getTextAttributes();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@ import com.intellij.ide.IdeBundle;
import com.intellij.ide.dnd.FileCopyPasteUtil;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actions.EditorActionUtil;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.markup.TextAttributes;
@@ -109,7 +110,7 @@ public class CopyReferenceAction extends AnAction {
private static PsiElement getElementToCopy(final Editor editor, final DataContext dataContext) {
PsiElement element = null;
if (editor != null) {
PsiReference reference = TargetElementUtilBase.findReference(editor, editor.getCaretModel().getOffset());
PsiReference reference = TargetElementUtilBase.findReference(editor);
if (reference != null) {
element = reference.getElement();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@ import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx;
@@ -55,6 +56,7 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.*;
import java.util.*;
@@ -351,4 +353,9 @@ public class FileTemplateUtil{
CreateFromTemplateHandler handler = findHandler(template);
return handler.canCreate(dirs);
}
@Nullable
public static Icon getIcon(@NotNull FileTemplate fileTemplate) {
return FileTypeManager.getInstance().getFileTypeByExtension(fileTemplate.getExtension()).getIcon();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,10 +17,10 @@
package com.intellij.ide.fileTemplates.actions;
import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.ide.fileTemplates.FileTemplateUtil;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDirectory;
import org.jetbrains.annotations.Nullable;
@@ -30,7 +30,7 @@ public class CreateFromTemplateAction extends CreateFromTemplateActionBase {
private final FileTemplate myTemplate;
public CreateFromTemplateAction(FileTemplate template){
super(template.getName(), null, FileTypeManagerEx.getInstanceEx().getFileTypeByExtension(template.getExtension()).getIcon());
super(template.getName(), null, FileTemplateUtil.getIcon(template));
myTemplate = template;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,7 @@
package com.intellij.ide.fileTemplates.impl;
import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.ide.fileTemplates.FileTemplateUtil;
import com.intellij.ui.components.JBList;
import org.jetbrains.annotations.NotNull;
@@ -52,7 +52,7 @@ abstract class FileTemplateTabAsList extends FileTemplateTab {
Icon icon = null;
if (value instanceof FileTemplate) {
FileTemplate template = (FileTemplate) value;
icon = FileTypeManager.getInstance().getFileTypeByExtension(template.getExtension()).getIcon();
icon = FileTemplateUtil.getIcon(template);
final boolean internalTemplate = AllFileTemplatesConfigurable.isInternalTemplate(template.getName(), getTitle());
if (internalTemplate) {
setFont(getFont().deriveFont(Font.BOLD));
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,10 +16,11 @@
package com.intellij.ide.fileTemplates.ui;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.ide.fileTemplates.FileTemplateManager;
import com.intellij.ide.fileTemplates.FileTemplateUtil;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.ui.ListCellRendererWrapper;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.FixedSizeButton;
@@ -80,6 +81,15 @@ public class SelectTemplateDialog extends DialogWrapper{
}
if(myCbxTemplates == null){
myCbxTemplates = new JComboBox(model);
myCbxTemplates.setRenderer(new ListCellRendererWrapper<FileTemplate>(myCbxTemplates.getRenderer()) {
@Override
public void customize(JList list, FileTemplate fileTemplate, int index, boolean selected, boolean hasFocus) {
if (fileTemplate != null) {
setIcon(FileTemplateUtil.getIcon(fileTemplate));
setText(fileTemplate.getName());
}
}
});
}
else{
Object selected = myCbxTemplates.getSelectedItem();
@@ -210,6 +210,10 @@ public class ScopeTreeViewPanel extends JPanel implements Disposable {
});
}
};
doWhenDone(runnable);
}
private void doWhenDone(Runnable runnable) {
if (myActionCallback == null || ApplicationManager.getApplication().isUnitTestMode()) {
runnable.run();
}
@@ -646,7 +650,7 @@ public class ScopeTreeViewPanel extends JPanel implements Disposable {
}, false);
}
else if (propertyName.equals(PsiTreeChangeEvent.PROP_DIRECTORY_NAME)) {
queueRefreshScope(scope);
queueRefreshScope(scope, (PsiDirectory)element);
}
}
}
@@ -665,7 +669,7 @@ public class ScopeTreeViewPanel extends JPanel implements Disposable {
}
}
else if (element instanceof PsiDirectory && element.isValid()) {
queueRefreshScope(scope);
queueRefreshScope(scope, (PsiDirectory)element);
}
}
@@ -673,11 +677,22 @@ public class ScopeTreeViewPanel extends JPanel implements Disposable {
return InjectedLanguageManager.getInstance(myProject).isInjectedFragment(psiFile);
}
private void queueRefreshScope(final NamedScope scope) {
private void queueRefreshScope(final NamedScope scope, final PsiDirectory dir) {
myUpdateQueue.cancelAllUpdates();
queueUpdate(new Runnable() {
public void run() {
myTreeExpansionMonitor.freeze();
refreshScope(scope);
doWhenDone(new Runnable() {
@Override
public void run() {
myTreeExpansionMonitor.restore();
final PackageDependenciesNode dirNode = myBuilder.findNode(dir, dir);
if (dirNode != null) {
TreeUtil.selectPath(myTree, new TreePath(dirNode.getPath()));
}
}
});
}
}, false);
}
@@ -31,6 +31,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.LayeredIcon;
import com.intellij.ui.LightColors;
import com.intellij.ui.components.JBLabel;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ui.EmptyIcon;
@@ -156,6 +157,9 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C
label.setIcon(EMPTY_ICON);
panel.add(label, BorderLayout.WEST);
panel.add(new JBLabel("Settings"), BorderLayout.EAST);
if (!isSelected) {
panel.setBackground(LightColors.SLIGHTLY_GRAY);
}
} else if (value instanceof String) {
final JBLabel label = new JBLabel((String)value);
label.setIcon(EMPTY_ICON);
@@ -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);
}
@@ -203,11 +203,11 @@ public class FormatterUtil {
if (isWhitespaceOrEmpty(node)) return true;
for (WhiteSpaceFormattingStrategy strategy : WhiteSpaceFormattingStrategyFactory.getAllStrategies()) {
if (!strategy.containsWhitespacesOnly(node)) {
return false;
if (strategy.containsWhitespacesOnly(node)) {
return true;
}
}
return true;
return false;
}
public static void replaceWhiteSpace(final String whiteSpace,
@@ -39,6 +39,7 @@ class LeafPatcher extends RecursiveTreeElementWalkingVisitor {
private String prevElementTail;
private int shredNo;
private String hostText;
private TextRange rangeInHost;
private final Place myShreds;
private final List<LiteralTextEscaper<? extends PsiLanguageInjectionHost>> myEscapers;
final Map<LeafElement, String> newTexts = new THashMap<LeafElement, String>();
@@ -74,7 +75,11 @@ class LeafPatcher extends RecursiveTreeElementWalkingVisitor {
private StringBuilder constructTextFromHostPSI(int startOffset, int endOffset) {
PsiLanguageInjectionHost.Shred current = myShreds.get(shredNo);
if (hostText == null) hostText = current.getHost().getText();
if (hostText == null) {
hostText = current.getHost().getText();
rangeInHost = current.getRangeInsideHost();
}
StringBuilder text = new StringBuilder(endOffset-startOffset);
while (startOffset < endOffset) {
TextRange shredRange = current.getRange();
@@ -82,6 +87,7 @@ class LeafPatcher extends RecursiveTreeElementWalkingVisitor {
if (startOffset >= shredRange.getEndOffset()) {
current = myShreds.get(++shredNo);
hostText = current.getHost().getText();
rangeInHost = current.getRangeInsideHost();
continue;
}
assert startOffset >= shredRange.getStartOffset();
@@ -96,9 +102,11 @@ class LeafPatcher extends RecursiveTreeElementWalkingVisitor {
String suffix = current.getSuffix();
if (startOffset < shredRange.getEndOffset() - suffix.length()) {
// inside host body, cut out from the host text
int startOffsetInHost = myEscapers.get(shredNo).getOffsetInHost(startOffset - shredRange.getStartOffset() - prefix.length(), current.getRangeInsideHost());
int startOffsetInHost = myEscapers.get(shredNo).getOffsetInHost(
startOffset - shredRange.getStartOffset() - prefix.length(), rangeInHost);
int endOffsetCut = Math.min(endOffset, shredRange.getEndOffset() - suffix.length());
int endOffsetInHost = myEscapers.get(shredNo).getOffsetInHost(endOffsetCut - shredRange.getStartOffset() - prefix.length(), current.getRangeInsideHost());
int endOffsetInHost = myEscapers.get(shredNo).getOffsetInHost(
endOffsetCut - shredRange.getStartOffset() - prefix.length(), rangeInHost);
if (endOffsetInHost != -1) {
text.append(hostText, startOffsetInHost, endOffsetInHost);
startOffset = endOffsetCut;
@@ -50,43 +50,44 @@ public class IdeaGateway {
private static final Key<ContentAndTimestamps> SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY
= Key.create("LocalHistory.SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY");
public boolean isVersioned(VirtualFile f) {
public boolean isVersioned(@NotNull VirtualFile f) {
if (!f.isInLocalFileSystem()) return false;
String fileName = f.getName();
if (!f.isDirectory() && fileName.endsWith(".class")) return false;
for (Project each : ProjectManager.getInstance().getOpenProjects()) {
Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
for (Project each : openProjects) {
if (each.isDefault()) continue;
if (!each.isInitialized()) continue;
if (each.getWorkspaceFile() == f) return false;
if (ProjectRootManager.getInstance(each).getFileIndex().isIgnored(f)) return false;
}
return !FileTypeManager.getInstance().isFileIgnored(f);
// optimisation: FileTypeManager.isFileIgnored(f) already checked inside ProjectFileIndex.isIgnored()
return openProjects.length != 0 || !FileTypeManager.getInstance().isFileIgnored(f);
}
public boolean areContentChangesVersioned(VirtualFile f) {
if (!isVersioned(f) || f.isDirectory()) return false;
return areContentChangesVersioned(f.getName());
public boolean areContentChangesVersioned(@NotNull VirtualFile f) {
return isVersioned(f) && !f.isDirectory() && areContentChangesVersioned(f.getName());
}
public boolean areContentChangesVersioned(String fileName) {
public boolean areContentChangesVersioned(@NotNull String fileName) {
return !FileTypeManager.getInstance().getFileTypeByFileName(fileName).isBinary();
}
public boolean ensureFilesAreWritable(Project p, List<VirtualFile> ff) {
public boolean ensureFilesAreWritable(@NotNull Project p, @NotNull List<VirtualFile> ff) {
ReadonlyStatusHandler h = ReadonlyStatusHandler.getInstance(p);
return !h.ensureFilesWritable(VfsUtil.toVirtualFileArray(ff)).hasReadonlyFiles();
}
@Nullable
public VirtualFile findVirtualFile(String path) {
public VirtualFile findVirtualFile(@NotNull String path) {
return LocalFileSystem.getInstance().findFileByPath(path);
}
@NotNull
public VirtualFile findOrCreateFileSafely(VirtualFile parent, String name, boolean isDirectory) throws IOException {
public VirtualFile findOrCreateFileSafely(@NotNull VirtualFile parent, @NotNull String name, boolean isDirectory) throws IOException {
VirtualFile f = parent.findChild(name);
if (f != null && f.isDirectory() != isDirectory) {
f.delete(this);
@@ -101,7 +102,7 @@ public class IdeaGateway {
}
@NotNull
public VirtualFile findOrCreateFileSafely(String path, boolean isDirectory) throws IOException {
public VirtualFile findOrCreateFileSafely(@NotNull String path, boolean isDirectory) throws IOException {
VirtualFile f = findVirtualFile(path);
if (f != null && f.isDirectory() != isDirectory) {
f.delete(this);
@@ -117,13 +118,14 @@ public class IdeaGateway {
return f;
}
public List<VirtualFile> getAllFilesFrom(String path) {
public List<VirtualFile> getAllFilesFrom(@NotNull String path) {
VirtualFile f = findVirtualFile(path);
if (f == null) return Collections.emptyList();
return collectFiles(f, new ArrayList<VirtualFile>());
}
private List<VirtualFile> collectFiles(VirtualFile f, List<VirtualFile> result) {
@NotNull
private static List<VirtualFile> collectFiles(@NotNull VirtualFile f, @NotNull List<VirtualFile> result) {
if (f.isDirectory()) {
for (VirtualFile child : iterateDBChildren(f)) {
collectFiles(child, result);
@@ -135,12 +137,14 @@ public class IdeaGateway {
return result;
}
@NotNull
public static Collection<VirtualFile> iterateDBChildren(VirtualFile f) {
if (!(f instanceof NewVirtualFile)) return Collections.emptyList();
NewVirtualFile nf = (NewVirtualFile)f;
return nf.getCachedChildren();
}
@NotNull
public RootEntry createTransientRootEntry() {
ApplicationManager.getApplication().assertReadAccessAllowed();
RootEntry root = new RootEntry();
@@ -149,19 +153,19 @@ public class IdeaGateway {
}
@Nullable
public Entry createTransientEntry(VirtualFile file) {
public Entry createTransientEntry(@NotNull VirtualFile file) {
ApplicationManager.getApplication().assertReadAccessAllowed();
return doCreateEntry(file, false);
}
@Nullable
public Entry createEntryForDeletion(VirtualFile file) {
public Entry createEntryForDeletion(@NotNull VirtualFile file) {
ApplicationManager.getApplication().assertReadAccessAllowed();
return doCreateEntry(file, true);
}
@Nullable
private Entry doCreateEntry(VirtualFile file, boolean forDeletion) {
private Entry doCreateEntry(@NotNull VirtualFile file, boolean forDeletion) {
if (!file.isDirectory()) {
if (!isVersioned(file)) return null;
@@ -182,18 +186,19 @@ public class IdeaGateway {
return newDir;
}
private void doCreateChildren(DirectoryEntry parent, Collection<VirtualFile> children, final boolean forDeletion) {
private void doCreateChildren(@NotNull DirectoryEntry parent, Collection<VirtualFile> children, final boolean forDeletion) {
List<Entry> entries = ContainerUtil.mapNotNull(children, new NullableFunction<VirtualFile, Entry>() {
@Override
public Entry fun(VirtualFile each) {
public Entry fun(@NotNull VirtualFile each) {
return doCreateEntry(each, forDeletion);
}
});
parent.addChildren(entries);
}
public void registerUnsavedDocuments(final LocalHistoryFacade vcs) {
public void registerUnsavedDocuments(@NotNull final LocalHistoryFacade vcs) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
vcs.beginChangeSet();
for (Document d : FileDocumentManager.getInstance().getUnsavedDocuments()) {
@@ -206,12 +211,11 @@ public class IdeaGateway {
});
}
private boolean shouldRegisterDocument(VirtualFile f) {
if (f == null || !f.isValid()) return false;
return areContentChangesVersioned(f);
private boolean shouldRegisterDocument(@Nullable VirtualFile f) {
return f != null && f.isValid() && areContentChangesVersioned(f);
}
private void registerDocumentContents(LocalHistoryFacade vcs, VirtualFile f, Document d) {
private void registerDocumentContents(@NotNull LocalHistoryFacade vcs, @NotNull VirtualFile f, Document d) {
Pair<StoredContent, Long> contentAndStamp = acquireAndUpdateActualContent(f, d);
if (contentAndStamp != null) {
vcs.contentChanged(f.getPath(), contentAndStamp.first, contentAndStamp.second);
@@ -220,7 +224,7 @@ public class IdeaGateway {
// returns null is content has not been changes since last time
@Nullable
public Pair<StoredContent, Long> acquireAndUpdateActualContent(VirtualFile f, @Nullable Document d) {
public Pair<StoredContent, Long> acquireAndUpdateActualContent(@NotNull VirtualFile f, @Nullable Document d) {
ContentAndTimestamps contentAndStamp = f.getUserData(SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY);
if (contentAndStamp == null) {
if (d != null) saveDocumentContent(f, d);
@@ -241,7 +245,7 @@ public class IdeaGateway {
return Pair.create(contentAndStamp.content, contentAndStamp.registeredTimestamp);
}
private void saveDocumentContent(VirtualFile f, Document d) {
private static void saveDocumentContent(@NotNull VirtualFile f, @NotNull Document d) {
f.putUserData(SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY,
new ContentAndTimestamps(Clock.getTime(),
StoredContent.acquireContent(bytesFromDocument(d)),
@@ -249,7 +253,7 @@ public class IdeaGateway {
}
@NotNull
public Pair<StoredContent, Long> acquireAndClearCurrentContent(VirtualFile f, @Nullable Document d) {
public Pair<StoredContent, Long> acquireAndClearCurrentContent(@NotNull VirtualFile f, @Nullable Document d) {
ContentAndTimestamps contentAndStamp = f.getUserData(SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY);
f.putUserData(SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY, null);
@@ -274,7 +278,7 @@ public class IdeaGateway {
}
@NotNull
private Pair<StoredContent, Long> getActualContentNoAcquire(VirtualFile f) {
private static Pair<StoredContent, Long> getActualContentNoAcquire(@NotNull VirtualFile f) {
ContentAndTimestamps result = f.getUserData(SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY);
if (result == null) {
return Pair.create(StoredContent.transientContent(f), f.getTimeStamp());
@@ -282,7 +286,7 @@ public class IdeaGateway {
return Pair.create(result.content, result.registeredTimestamp);
}
private byte[] bytesFromDocument(Document d) {
private static byte[] bytesFromDocument(@NotNull Document d) {
try {
return d.getText().getBytes(getFile(d).getCharset().name());
}
@@ -291,7 +295,7 @@ public class IdeaGateway {
}
}
public String stringFromBytes(byte[] bytes, String path) {
public String stringFromBytes(@NotNull byte[] bytes, @NotNull String path) {
try {
VirtualFile file = findVirtualFile(path);
if (file == null) {
@@ -308,15 +312,18 @@ public class IdeaGateway {
FileDocumentManager.getInstance().saveAllDocuments();
}
private VirtualFile getFile(Document d) {
@Nullable
private static VirtualFile getFile(@NotNull Document d) {
return FileDocumentManager.getInstance().getFile(d);
}
public Document getDocument(String path) {
@Nullable
public Document getDocument(@NotNull String path) {
return FileDocumentManager.getInstance().getDocument(findVirtualFile(path));
}
public FileType getFileType(String fileName) {
@NotNull
public FileType getFileType(@NotNull String fileName) {
return FileTypeManager.getInstance().getFileTypeByFileName(fileName);
}
@@ -92,14 +92,17 @@ public class HighlightSeverity implements Comparable<HighlightSeverity>, JDOMExt
return myName;
}
@Override
public int compareTo(final HighlightSeverity highlightSeverity) {
return myVal - highlightSeverity.myVal;
}
@Override
public void readExternal(Element element) throws InvalidDataException {
DefaultJDOMExternalizer.readExternal(this, element);
}
@Override
public void writeExternal(final Element element) throws WriteExternalException {
DefaultJDOMExternalizer.writeExternal(this, element);
}
@@ -111,9 +114,7 @@ public class HighlightSeverity implements Comparable<HighlightSeverity>, JDOMExt
final HighlightSeverity that = (HighlightSeverity)o;
if (!myName.equals(that.myName)) return false;
return true;
return myName.equals(that.myName);
}
public int hashCode() {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,8 +25,12 @@ import java.util.EventListener;
* @see EditorMouseMotionListener
*/
public interface EditorMouseListener extends EventListener {
/**
* Called when a mouse button is pressed over the editor.
* <p/>
* <b>Note:</b> this callback is assumed to be at the very start of 'mouse press' processing, i.e. common actions
* like 'caret position change', 'selection change' etc implied by the 'mouse press' have not been performed yet.
*
* @param e the event containing information about the mouse press.
*/
@@ -34,36 +34,43 @@ import java.util.Collection;
public abstract class NewVirtualFile extends VirtualFile implements VirtualFileWithId {
private volatile long myModificationStamp = LocalTimeCounter.currentTime();
@Override
public boolean isValid() {
ApplicationManager.getApplication().assertReadAccessAllowed();
return exists();
}
@Override
@NotNull
public byte[] contentsToByteArray() throws IOException {
throw new IOException("not applicable to the "+this);
}
@Override
@NotNull
public abstract NewVirtualFileSystem getFileSystem();
@Override
public abstract NewVirtualFile getParent();
@Override
@Nullable
public abstract NewVirtualFile getCanonicalFile();
@Override
@Nullable
public abstract NewVirtualFile findChild(@NotNull @NonNls final String name);
@Nullable
public abstract NewVirtualFile refreshAndFindChild(final String name);
public abstract NewVirtualFile refreshAndFindChild(@NotNull String name);
@Nullable
public abstract NewVirtualFile findChildIfCached(final String name);
public abstract NewVirtualFile findChildIfCached(@NotNull String name);
public abstract void setTimeStamp(final long time) throws IOException;
@Override
public abstract int getId();
@Nullable
@@ -72,10 +79,12 @@ public abstract class NewVirtualFile extends VirtualFile implements VirtualFileW
@Nullable
public abstract NewVirtualFile findChildByIdIfCached(int id);
@Override
public void refresh(final boolean asynchronous, final boolean recursive, final Runnable postRunnable) {
RefreshQueue.getInstance().refresh(asynchronous, recursive, postRunnable, this);
}
@Override
public long getModificationStamp() {
return myModificationStamp;
}
@@ -94,6 +103,7 @@ public abstract class NewVirtualFile extends VirtualFile implements VirtualFileW
public abstract void markClean();
@Override
public void move(final Object requestor, @NotNull final VirtualFile newParent) throws IOException {
if (!exists()) {
throw new IOException("File to move does not exist: " + getPath());
@@ -113,6 +123,7 @@ public abstract class NewVirtualFile extends VirtualFile implements VirtualFileW
}
EncodingRegistry.doActionAndRestoreEncoding(this, new ThrowableComputable<VirtualFile, IOException>() {
@Override
public VirtualFile compute() throws IOException {
getFileSystem().moveFile(requestor, NewVirtualFile.this, newParent);
return NewVirtualFile.this;
@@ -120,8 +131,10 @@ public abstract class NewVirtualFile extends VirtualFile implements VirtualFileW
});
}
@NotNull
public abstract Collection<VirtualFile> getCachedChildren();
@NotNull
/** iterated children will NOT contain NullVirtualFile.INSTANCE */
public abstract Iterable<VirtualFile> iterInDbChildren();
@@ -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();
@@ -25,7 +25,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.WaitForProgressToShow;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
@@ -182,7 +182,7 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider {
}
if (key.get() == null) {
final Ref<PasswordSafeException> ex = new Ref<PasswordSafeException>();
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
WaitForProgressToShow.runOrInvokeAndWaitAboveProgress(new Runnable() {
public void run() {
if (key.get() == null) {
try {
@@ -104,6 +104,11 @@ public class MasterPasswordDialog extends DialogWrapper {
* @throws PasswordSafeException if the master password is not provided.
*/
public static void askPassword(Project project, MasterKeyPasswordSafe safe) throws PasswordSafeException {
// trying empty password: people who have set up empty password, don't want to get disturbed by the prompt.
if (safe.setMasterPassword("")) {
return;
}
String error = null;
retries:
for (int count = 0; count < NUMBER_OF_RETRIES; count++) {
@@ -103,10 +103,13 @@ public class ActionInstallPlugin extends AnAction implements DumbAware {
pluginNode = (PluginNode)descr;
}
else if (descr instanceof IdeaPluginDescriptorImpl) {
pluginNode = new PluginNode(descr.getPluginId());
final PluginId pluginId = descr.getPluginId();
pluginNode = new PluginNode(pluginId);
pluginNode.setName(descr.getName());
pluginNode.setDepends(Arrays.asList(descr.getDependentPluginIds()), descr.getOptionalDependentPluginIds());
pluginNode.setSize("-1");
pluginNode.setRepositoryName(((InstalledPluginsTableModel)host.getPluginsModel())
.getPluginHostUrl(pluginId.getIdString()));
}
if (pluginNode != null) {
@@ -119,7 +122,6 @@ public class ActionInstallPlugin extends AnAction implements DumbAware {
@Override
public void run() {
installedPluginsToModel(list);
installed.setRequireShutdown(true);
if (!installed.isDisposed()) {
getPluginTable().updateUI();
final InstalledPluginsTableModel pluginsModel = (InstalledPluginsTableModel)installed.getPluginsModel();
@@ -140,10 +142,23 @@ public class ActionInstallPlugin extends AnAction implements DumbAware {
}
}
}
suggestToEnableInstalledPlugins(pluginsModel, disabled, disabledDependants, list);
if (suggestToEnableInstalledPlugins(pluginsModel, disabled, disabledDependants, list)) {
installed.setRequireShutdown(true);
}
}
else {
notifyPluginsWereInstalled();
boolean needToRestart = false;
for (PluginNode node : list) {
final IdeaPluginDescriptor pluginDescriptor = PluginManager.getPlugin(node.getPluginId());
if (pluginDescriptor == null || pluginDescriptor.isEnabled()) {
needToRestart = true;
break;
}
}
if (needToRestart) {
notifyPluginsWereInstalled();
}
}
}
};
@@ -162,7 +177,7 @@ public class ActionInstallPlugin extends AnAction implements DumbAware {
}
}
private static void suggestToEnableInstalledPlugins(final InstalledPluginsTableModel pluginsModel,
private static boolean suggestToEnableInstalledPlugins(final InstalledPluginsTableModel pluginsModel,
final Set<IdeaPluginDescriptor> disabled,
final Set<IdeaPluginDescriptor> disabledDependants,
final ArrayList<PluginNode> list) {
@@ -201,6 +216,7 @@ public class ActionInstallPlugin extends AnAction implements DumbAware {
Messages.showYesNoCancelDialog(message + "</body></html>", CommonBundle.getWarningTitle(), "Enable all",
"Enable updated plugin" + (disabled.size() > 1 ? "s" : ""), CommonBundle.getCancelButtonText(),
Messages.getQuestionIcon());
if (result == DialogWrapper.NEXT_USER_EXIT_CODE) return false;
} else {
message += "<br>Would you like to enable ";
if (!disabled.isEmpty()) {
@@ -211,6 +227,7 @@ public class ActionInstallPlugin extends AnAction implements DumbAware {
}
message += "?</body></html>";
result = Messages.showOkCancelDialog(message, CommonBundle.getWarningTitle(), Messages.getQuestionIcon());
if (result == DialogWrapper.CANCEL_EXIT_CODE) return false;
}
if (result == DialogWrapper.OK_EXIT_CODE) {
@@ -220,6 +237,7 @@ public class ActionInstallPlugin extends AnAction implements DumbAware {
pluginsModel.enableRows(disabled.toArray(new IdeaPluginDescriptor[disabled.size()]), true);
}
}
return true;
}
private void installedPluginsToModel(ArrayList<PluginNode> list) {
@@ -103,6 +103,10 @@ public class InstalledPluginsTableModel extends PluginTableModel {
}
}
public String getPluginHostUrl(String idString) {
return myPlugin2host.get(idString);
}
public static int getCheckboxColumn() {
return 0;
}
@@ -24,6 +24,8 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.updateSettings.impl.PluginDownloader;
import com.intellij.openapi.updateSettings.impl.UpdateChecker;
import com.intellij.openapi.util.Comparing;
import com.intellij.ui.GuiUtils;
import com.intellij.util.ArrayUtil;
@@ -156,7 +158,28 @@ public class PluginInstaller {
}
synchronized (PluginManager.lock) {
final PluginDownloader downloader = PluginDownloader.createDownloader(pluginNode);
PluginDownloader downloader = null;
final String repositoryName = pluginNode.getRepositoryName();
if (repositoryName != null) {
try {
final ArrayList<PluginDownloader> downloaders = new ArrayList<PluginDownloader>();
if (!UpdateChecker.checkPluginsHost(repositoryName, downloaders)) {
return false;
}
for (PluginDownloader pluginDownloader : downloaders) {
if (Comparing.strEqual(pluginDownloader.getPluginId(), pluginNode.getPluginId().getIdString())) {
downloader = pluginDownloader;
break;
}
}
if (downloader == null) return false;
}
catch (Exception e) {
return false;
}
} else {
downloader = PluginDownloader.createDownloader(pluginNode);
}
if (downloader.prepareToInstall(ProgressManager.getInstance().getProgressIndicator())) {
downloader.install();
pluginNode.setStatus(PluginNode.STATUS_DOWNLOADED);
@@ -64,6 +64,13 @@ public class NotificationTestAction extends AnAction implements DumbAware {
"You can<br> close this very<p> very very very long notification by clicking <a href=\"close\">this link</a>. Long long long long. It should be long. Very long. Too long. And even longer.",
type, listener);
messageBus.syncPublisher(Notifications.TOPIC).notify(notification);
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
public void run() {
//DebugUtil.sleep(1000);
messageBus.syncPublisher(Notifications.TOPIC).notify(notification);
}
});
}
}
@@ -71,15 +71,18 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl {
final XmlElementStorage storage = new XmlElementStorage(pathMacroManager.createTrackingSubstitutor(), componentManager,
ROOT_TAG_NAME, StreamProvider.DEFAULT, "", ComponentRoamingManager.getInstance(),
ComponentVersionProvider.EMPTY) {
@Override
@Nullable
protected Document loadDocument() throws StateStorageException {
return document;
}
@Override
protected MySaveSession createSaveSession(final MyExternalizationSession externalizationSession) {
return new DefaultSaveSession(externalizationSession);
}
@Override
@NotNull
protected StorageData createStorageData() {
return new BaseStorageData(ROOT_TAG_NAME);
@@ -90,14 +93,17 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl {
super(externalizationSession);
}
@Override
protected void doSave() throws StateStorageException {
myProjectManager.setDefaultProjectRootElement(getDocumentToSave().getRootElement());
}
@Override
public Collection<IFile> getStorageFilesToSave() throws StateStorageException {
return Collections.emptyList();
}
@Override
public List<IFile> getAllStorageFiles() {
return Collections.emptyList();
}
@@ -105,75 +111,92 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl {
};
return new StateStorageManager() {
@Override
public void addMacro(String macro, String expansion) {
throw new UnsupportedOperationException("Method addMacro not implemented in " + getClass());
}
@Override
@Nullable
public TrackingPathMacroSubstitutor getMacroSubstitutor() {
return null;
}
@Override
@Nullable
public StateStorage getStateStorage(@NotNull Storage storageSpec) throws StateStorageException {
return storage;
}
@Override
@Nullable
public StateStorage getFileStateStorage(String fileName) {
return storage;
}
@Override
public void clearStateStorage(@NotNull String file) {
}
@Override
public ExternalizationSession startExternalization() {
return new MyExternalizationSession(storage);
}
@Override
public SaveSession startSave(final ExternalizationSession externalizationSession) {
return new MySaveSession(storage, externalizationSession);
}
@Override
public void finishSave(SaveSession saveSession) {
storage.finishSave(((MySaveSession)saveSession).saveSession);
}
@Override
public String expandMacroses(final String file) {
throw new UnsupportedOperationException("Method expandMacroses not implemented in " + getClass());
}
@Override
@Nullable
public StateStorage getOldStorage(Object component, final String componentName, final StateStorageOperation operation)
throws StateStorageException {
return storage;
}
@Override
public void registerStreamProvider(final StreamProvider streamProvider, final RoamingType type) {
throw new UnsupportedOperationException("Method registerStreamProvider not implemented in " + getClass());
}
@Override
public void unregisterStreamProvider(final StreamProvider streamProvider, final RoamingType roamingType) {
throw new UnsupportedOperationException("Method unregisterStreamProvider not implemented in " + getClass());
}
@Override
public StreamProvider[] getStreamProviders(final RoamingType roamingType) {
throw new UnsupportedOperationException("Method getStreamProviders not implemented in " + getClass());
}
@Override
public Collection<String> getStorageFileNames() {
throw new UnsupportedOperationException("Method getStorageFileNames not implemented in " + getClass());
}
@Override
public void reset() {
}
};
}
@Override
public String getLocation() {
throw new UnsupportedOperationException("Method getLocation not implemented in " + getClass());
}
@Override
public void load() throws IOException, StateStorageException {
if (myElement == null) return;
super.load();
@@ -186,11 +209,13 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl {
externalizationSession = storage.startExternalization();
}
@Override
public void setState(@NotNull final Storage[] storageSpecs, final Object component, final String componentName, final Object state)
throws StateStorageException {
externalizationSession.setState(component, componentName, state, null);
}
@Override
public void setStateInOldStorage(final Object component, final String componentName, final Object state) throws StateStorageException {
externalizationSession.setState(component, componentName, state, null);
}
@@ -204,19 +229,23 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl {
}
//returns set of component which were changed, null if changes are much more than just component state.
@Override
@Nullable
public Set<String> analyzeExternalChanges(Set<Pair<VirtualFile, StateStorage>> files) {
throw new UnsupportedOperationException("Method analyzeExternalChanges not implemented in " + getClass());
}
@Override
public List<IFile> getAllStorageFilesToSave() throws StateStorageException {
return Collections.emptyList();
}
@Override
public List<IFile> getAllStorageFiles() {
return Collections.emptyList();
}
@Override
public void save() throws StateStorageException {
saveSession.save();
}
@@ -28,17 +28,16 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.options.StreamProvider;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileAdapter;
import com.intellij.openapi.vfs.VirtualFileEvent;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import com.intellij.openapi.vfs.tracker.VirtualFileTracker;
import com.intellij.util.io.fs.FileSystem;
import com.intellij.util.io.fs.IFile;
import com.intellij.util.messages.MessageBus;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.picocontainer.PicoContainer;
@@ -50,8 +49,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import static com.intellij.util.io.fs.FileSystem.FILE_SYSTEM;
public class FileBasedStorage extends XmlElementStorage {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.components.impl.stores.FileBasedStorage");
@@ -60,6 +57,7 @@ public class FileBasedStorage extends XmlElementStorage {
protected final String myRootElementName;
private static boolean myConfigDirectoryRefreshed = false;
private volatile VirtualFile myCachedVirtualFile;
public FileBasedStorage(@Nullable TrackingPathMacroSubstitutor pathMacroManager,
StreamProvider streamProvider,
@@ -84,7 +82,7 @@ public class FileBasedStorage extends XmlElementStorage {
myRootElementName = rootElementName;
myFilePath = filePath;
myFile = FILE_SYSTEM.createFile(myFilePath);
myFile = FileSystem.FILE_SYSTEM.createFile(myFilePath);
VirtualFileTracker virtualFileTracker = (VirtualFileTracker)picoContainer.getComponentInstanceOfType(VirtualFileTracker.class);
MessageBus messageBus = (MessageBus)picoContainer.getComponentInstanceOfType(MessageBus.class);
@@ -96,8 +94,21 @@ public class FileBasedStorage extends XmlElementStorage {
final Listener listener = messageBus.syncPublisher(STORAGE_TOPIC);
virtualFileTracker.addTracker(fileUrl, new VirtualFileAdapter() {
@Override
public void fileMoved(VirtualFileMoveEvent event) {
myCachedVirtualFile = null;
}
@Override
public void fileDeleted(VirtualFileEvent event) {
myCachedVirtualFile = null;
}
@Override
public void contentsChanged(final VirtualFileEvent event) {
if (!isDisposed()) listener.storageFileChanged(event, FileBasedStorage.this);
if (!isDisposed()) {
listener.storageFileChanged(event, FileBasedStorage.this);
}
}
}, false, this);
}
@@ -125,6 +136,7 @@ public class FileBasedStorage extends XmlElementStorage {
}
}
@Override
protected MySaveSession createSaveSession(final MyExternalizationSession externalizationSession) {
return new FileSaveSession(externalizationSession);
}
@@ -135,7 +147,7 @@ public class FileBasedStorage extends XmlElementStorage {
}
protected class FileSaveSession extends MySaveSession {
private class FileSaveSession extends MySaveSession {
protected FileSaveSession(MyExternalizationSession externalizationSession) {
super(externalizationSession);
}
@@ -156,16 +168,19 @@ public class FileBasedStorage extends XmlElementStorage {
return hash;
}
@Override
protected void doSave() throws StateStorageException {
if (!myBlockSavingTheContent) {
if (ApplicationManager.getApplication().isUnitTestMode() && myFile != null && StringUtil.startsWithChar(myFile.getPath(), '$')) {
throw new StateStorageException("It seems like some macros were not expanded for path: " + myFile.getPath());
}
StorageUtil.save(myFile, getDocumentToSave(), this);
if (myBlockSavingTheContent) {
return;
}
if (ApplicationManager.getApplication().isUnitTestMode() && myFile != null && StringUtil.startsWithChar(myFile.getPath(), '$')) {
throw new StateStorageException("It seems like some macros were not expanded for path: " + myFile.getPath());
}
myCachedVirtualFile = StorageUtil.save(myFile, getDocumentToSave(), this);
}
@Override
public Collection<IFile> getStorageFilesToSave() throws StateStorageException {
boolean needsSave = needsSave();
if (needsSave) {
@@ -179,18 +194,21 @@ public class FileBasedStorage extends XmlElementStorage {
}
}
@Override
public List<IFile> getAllStorageFiles() {
return Collections.singletonList(myFile);
}
}
@Override
protected void loadState(final StorageData result, final Element element) throws StateStorageException {
((FileStorageData)result).myFileName = myFile.getAbsolutePath();
((FileStorageData)result).myFilePath = myFile.getAbsolutePath();
super.loadState(result, element);
}
@Override
@NotNull
protected StorageData createStorageData() {
return new FileStorageData(myRootElementName);
@@ -210,10 +228,12 @@ public class FileBasedStorage extends XmlElementStorage {
myFilePath = storageData.myFilePath;
}
@Override
public StorageData clone() {
return new FileStorageData(this);
}
@NonNls
public String toString() {
return "FileStorageData[" + myFileName + "]";
}
@@ -221,13 +241,18 @@ public class FileBasedStorage extends XmlElementStorage {
@Nullable
public VirtualFile getVirtualFile() {
return StorageUtil.getVirtualFile(myFile);
VirtualFile virtualFile = myCachedVirtualFile;
if (virtualFile == null) {
myCachedVirtualFile = virtualFile = StorageUtil.getVirtualFile(myFile);
}
return virtualFile;
}
public File getFile() {
return new File(myFile.getPath());
}
@Override
@Nullable
protected Document loadDocument() throws StateStorageException {
myBlockSavingTheContent = false;
@@ -289,14 +314,14 @@ public class FileBasedStorage extends XmlElementStorage {
return myFilePath;
}
@Override
public void setDefaultState(final Element element) {
element.setName(myRootElementName);
super.setDefaultState(element);
}
protected boolean physicalContentNeedsSave(final Document doc) {
if (!myFile.exists()) return true;
return !StorageUtil.contentEquals(doc, myFile);
return !myFile.exists() || !StorageUtil.contentEquals(doc, myFile);
}
@Nullable
@@ -307,7 +332,6 @@ public class FileBasedStorage extends XmlElementStorage {
File file = new File(myFile.getAbsolutePath());
JDOMUtil.writeDocument(document, file, "\n");
return file;
}
return null;
@@ -90,7 +90,8 @@ public class StorageUtil {
}
}
static void save(final IFile file, final Parent element, final Object requestor) throws StateStorageException {
static VirtualFile save(final IFile file, final Parent element, final Object requestor) throws StateStorageException {
final VirtualFile[] result = new VirtualFile[1];
final String filePath = file.getCanonicalPath();
try {
final Ref<IOException> refIOException = Ref.create(null);
@@ -98,7 +99,7 @@ public class StorageUtil {
final Pair<String, String> pair = loadFile(file);
final byte[] text = JDOMUtil.writeParent(element, pair.second).getBytes(CharsetToolkit.UTF8);
if (file.exists()) {
if (new String(text).equals(pair.first)) return;
if (new String(text).equals(pair.first)) return null;
IFile backupFile = deleteBackup(filePath);
file.renameTo(backupFile);
}
@@ -114,6 +115,7 @@ public class StorageUtil {
final VirtualFile virtualFile = getOrCreateVirtualFile(requestor, file);
virtualFile.setBinaryContent(text, -1, -1, requestor);
result[0] = virtualFile;
}
catch (IOException e) {
refIOException.set(e);
@@ -129,6 +131,7 @@ public class StorageUtil {
catch (IOException e) {
throw new StateStorageException(e);
}
return result[0];
}
static IFile deleteBackup(final String path) {
@@ -72,6 +72,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
protected Map<String, Long> myProviderVersions = null;
protected ComponentVersionListener myListener = new ComponentVersionListener(){
@Override
public void componentStateChanged(String componentName) {
myLocalVersionProvider.changeVersion(componentName, System.currentTimeMillis());
}
@@ -97,6 +98,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
myLocalVersionProvider = localComponentVersionsProvider;
myRemoteVersionProvider = new ComponentVersionProvider(){
@Override
public long getVersion(String name) {
if (myProviderVersions == null) {
loadProviderVersions();
@@ -106,6 +108,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
}
@Override
public void changeVersion(String name, long version) {
if (myProviderVersions == null) {
loadProviderVersions();
@@ -138,11 +141,13 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
return state;
}
@Override
public boolean hasState(final Object component, final String componentName, final Class<?> aClass, final boolean reloadData) throws StateStorageException {
final StorageData storageData = getStorageData(reloadData);
return storageData.hasState(componentName);
}
@Override
@Nullable
public <T> T getState(final Object component, final String componentName, Class<T> stateClass, @Nullable T mergeInto) throws StateStorageException {
final Element element = getState(componentName);
@@ -229,6 +234,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
}
}
@Override
@NotNull
public ExternalizationSession startExternalization() {
try {
@@ -242,6 +248,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
}
}
@Override
@NotNull
public SaveSession startSave(final ExternalizationSession externalizationSession) {
assert mySession == externalizationSession;
@@ -253,18 +260,22 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
private SaveSession createNullSession() {
return new SaveSession(){
@Override
public void save() throws StateStorageException {
}
@Override
public Set<String> analyzeExternalChanges(final Set<Pair<VirtualFile, StateStorage>> changedFiles) {
return Collections.emptySet();
}
@Override
public Collection<IFile> getStorageFilesToSave() throws StateStorageException {
return Collections.emptySet();
}
@Override
public List<IFile> getAllStorageFiles() {
return Collections.emptyList();
}
@@ -273,6 +284,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
protected abstract MySaveSession createSaveSession(final MyExternalizationSession externalizationSession);
@Override
public void finishSave(final SaveSession saveSession) {
try {
LOG.assertTrue(mySession == saveSession, "mySession=" + mySession + " saveSession=" + saveSession);
@@ -294,6 +306,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
myListener = listener;
}
@Override
public void setState(final Object component, final String componentName, final Object state, final Storage storageSpec) throws StateStorageException {
assert mySession == this;
@@ -401,6 +414,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
return null;
}
@Override
public final void save() throws StateStorageException {
assert mySession == this;
@@ -483,6 +497,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
return myStorageData;
}
@Override
@Nullable
public Set<String> analyzeExternalChanges(final Set<Pair<VirtualFile,StateStorage>> changedFiles) {
try {
@@ -532,6 +547,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
return result;
}
@Override
public void dispose() {
myDisposed = true;
}
@@ -647,6 +663,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
clearHash();
}
@Override
public StorageData clone() {
return new StorageData(this);
}
@@ -724,6 +741,7 @@ public abstract class XmlElementStorage implements StateStorage, Disposable {
myLoadedData = null;
}
@Override
public void reload(@NotNull final Set<String> changedComponents) throws StateStorageException {
final StorageData storageData = loadData(false, myListener);
@@ -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");
@@ -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));
@@ -629,7 +629,7 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi
int[] starts = getBlockSelectionStarts();
int[] ends = getBlockSelectionEnds();
int width = Math.abs(myBlockEnd.column - myBlockStart.column);
final StringBuffer buf = new StringBuffer();
final StringBuilder buf = new StringBuilder();
for (int i = 0; i < starts.length; i++) {
if (i > 0) buf.append('\n');
final int len = ends[i] - starts[i];
@@ -644,7 +644,7 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi
return text.subSequence(selectionStart, selectionEnd).toString();
}
private static void appendCharSequence(@NotNull StringBuffer buf, @NotNull CharSequence s, int srcOffset, int len) {
private static void appendCharSequence(@NotNull StringBuilder buf, @NotNull CharSequence s, int srcOffset, int len) {
if (srcOffset < 0 || len < 0 || srcOffset > s.length() - len) {
throw new IndexOutOfBoundsException("srcOffset " + srcOffset + ", len " + len + ", s.length() " + s.length());
}
@@ -47,7 +47,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
private static volatile int ourLockedCheckCounter = 0;
@NonNls private static final String NAME = "Progress Cancel Checker";
private static final boolean DISABLED = Comparing.equal(System.getProperty(PROCESS_CANCELED_EXCEPTION), "disabled");
private static final boolean DISABLED = "disabled".equals(System.getProperty(PROCESS_CANCELED_EXCEPTION));
private volatile boolean enabled = true;
@@ -29,6 +29,7 @@ import com.intellij.openapi.vfs.newvfs.*;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
import com.intellij.util.containers.ConcurrentHashSet;
import com.intellij.util.messages.MessageBus;
import com.intellij.util.text.CaseInsensitiveStringHashingStrategy;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -41,7 +42,10 @@ import java.util.*;
import java.util.zip.ZipFile;
public class JarFileSystemImpl extends JarFileSystem implements ApplicationComponent {
private final Set<String> myNoCopyJarPaths = new ConcurrentHashSet<String>();
private final Set<String> myNoCopyJarPaths = SystemInfo.isFileSystemCaseSensitive ?
new ConcurrentHashSet<String>() :
new ConcurrentHashSet<String>(CaseInsensitiveStringHashingStrategy.INSTANCE);
@NonNls private static final String IDEA_JARS_NOCOPY = "idea.jars.nocopy";
private File myNoCopyJarDir;
@@ -149,9 +153,6 @@ public class JarFileSystemImpl extends JarFileSystem implements ApplicationCompo
if (index < 0) return;
String path = pathInJar.substring(0, index);
path = path.replace('/', File.separatorChar);
if (!SystemInfo.isFileSystemCaseSensitive) {
path = path.toLowerCase();
}
myNoCopyJarPaths.add(path);
}
@@ -268,12 +269,7 @@ public class JarFileSystemImpl extends JarFileSystem implements ApplicationCompo
String property = System.getProperty(IDEA_JARS_NOCOPY);
if (Boolean.TRUE.toString().equalsIgnoreCase(property)) return false;
String path = originalJar.getPath();
if (!SystemInfo.isFileSystemCaseSensitive) {
path = path.toLowerCase();
}
if (myNoCopyJarPaths.contains(path)) return false;
if (myNoCopyJarPaths.contains(originalJar.getPath())) return false;
if (myNoCopyJarDir!=null && FileUtil.isAncestor(myNoCopyJarDir, originalJar, false)) return false;
return true;
@@ -45,11 +45,13 @@ public class VirtualFileImpl extends VirtualFileSystemEntry {
return null;
}
@NotNull
@Override
public Collection<VirtualFile> getCachedChildren() {
return Collections.emptyList();
}
@NotNull
@Override
public Iterable<VirtualFile> iterInDbChildren() {
return ContainerUtil.emptyIterable();
@@ -65,13 +67,13 @@ public class VirtualFileImpl extends VirtualFileSystemEntry {
@Override
@Nullable
public NewVirtualFile refreshAndFindChild(final String name) {
public NewVirtualFile refreshAndFindChild(@NotNull final String name) {
return null;
}
@Override
@Nullable
public NewVirtualFile findChildIfCached(final String name) {
public NewVirtualFile findChildIfCached(@NotNull final String name) {
return null;
}
@@ -131,7 +131,7 @@ public class IdeGlassPaneImpl extends JPanel implements IdeGlassPaneEx, IdeEvent
}
int button1 = MouseEvent.BUTTON1_MASK | MouseEvent.BUTTON1_DOWN_MASK;
final boolean pureMouse1Event = (me.getModifiersEx() | button1) == button1;
if (pureMouse1Event && me.getClickCount() == 1 && !me.isPopupTrigger()) {
if (pureMouse1Event && me.getClickCount() <= 1 && !me.isPopupTrigger()) {
final Point point = SwingUtilities.convertPoint(meComponent, me.getPoint(), myRootPane.getContentPane());
if (myRootPane.getMenuBar() != null && myRootPane.getMenuBar().isVisible()) {
@@ -1333,7 +1333,14 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
FrameStateManager.getInstance().getApplicationActive().doWhenDone(new Runnable() {
@Override
public void run() {
((BalloonImpl)balloon).setHideOnClickOutside(true);
final Alarm alarm = new Alarm();
alarm.addRequest(new Runnable() {
@Override
public void run() {
((BalloonImpl)balloon).setHideOnClickOutside(true);
Disposer.dispose(alarm);
}
}, 100);
}
});
listenerWrapper.myBalloon = balloon;
@@ -338,7 +338,7 @@ checkbox.mark.modified.tabs.with.asterisk=Mark modified tabs with asterisk
group.code.folding=Code Folding
checkbox.collapse.xml.tags=XML tags
checkbox.collapse.anonymous.classes=<html>Anonymous classes</html>
checkbox.collapse.closures=<html>Closures</html>
checkbox.collapse.closures=<html>"Closures" (anonymous classes implementing one method)</html>
checkbox.collapse.generic.constructor.parameters=<html>Generic constructor and method parameters</html>
checkbox.collapse.i18n.messages=<html>I18n Strings</html>
checkbox.collapse.annotations=<html>Annotations</html>
@@ -25,6 +25,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Clock;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.text.DateFormatUtil;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.ArrayList;
@@ -91,7 +92,7 @@ public class SelectionReverterTest extends IntegrationTestCase {
final List<VirtualFile> files = new ArrayList<VirtualFile>();
myGateway = new IdeaGateway() {
@Override
public boolean ensureFilesAreWritable(Project p, List<VirtualFile> ff) {
public boolean ensureFilesAreWritable(@NotNull Project p, @NotNull List<VirtualFile> ff) {
files.addAll(ff);
return true;
}
@@ -24,6 +24,7 @@ import com.intellij.history.core.revisions.Revision;
import com.intellij.history.core.tree.RootEntry;
import com.intellij.history.integration.IdeaGateway;
import com.intellij.util.diff.FilesTooBigForDiffException;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
import java.util.List;
@@ -133,7 +134,7 @@ public class SelectionCalculatorTest extends LocalHistoryTestCase {
private static class MyIdeaGateway extends IdeaGateway {
@Override
public String stringFromBytes(byte[] bytes, String path) {
public String stringFromBytes(@NotNull byte[] bytes, @NotNull String path) {
return new String(bytes);
}
}
@@ -289,6 +289,13 @@ public class NameUtilTest extends UsefulTestCase {
TextRange.from(0, 2));
}
public void testPreferCapsMatching() {
String sample = "getCurrentUser";
// 0 4 10
assertOrderedEquals(new NameUtil.MinusculeMatcher("getCU", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample),
TextRange.from(0, 4), TextRange.from(10, 1));
}
public void testMatchingDegree() {
assertPreference("OCO", "OneCoolObject", "OCObject");
assertPreference("MUp", "MavenUmlProvider", "MarkUp");
@@ -296,6 +303,7 @@ public class NameUtilTest extends UsefulTestCase {
assertPreference("CertificateExce", "CertificateEncodingException", "CertificateException");
assertPreference("boo", "Boolean", "boolean", NameUtil.MatchingCaseSensitivity.NONE);
assertPreference("Boo", "boolean", "Boolean", NameUtil.MatchingCaseSensitivity.NONE);
assertPreference("getCU", "getCurrentSomething", "getCurrentUser");
}
private static void assertPreference(@NonNls String pattern,
@@ -17,9 +17,11 @@ package com.intellij.openapi.util;
import com.intellij.openapi.diagnostic.Logger;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import sun.reflect.Reflection;
import java.util.ArrayList;
import java.util.Collection;
@SuppressWarnings({"HardCodedStringLiteral"})
public class JDOMExternalizableStringList extends ArrayList<String> implements JDOMExternalizable {
@@ -32,6 +34,17 @@ public class JDOMExternalizableStringList extends ArrayList<String> implements J
private static final String ATTR_CLASS = "class";
private static final String ATTR_VALUE = "itemvalue";
public JDOMExternalizableStringList(int initialCapacity) {
super(initialCapacity);
}
public JDOMExternalizableStringList() {
}
public JDOMExternalizableStringList(@NotNull Collection<? extends String> c) {
super(c);
}
public void readExternal(Element element) throws InvalidDataException {
clear();
@@ -423,6 +423,9 @@ public class NameUtil {
if (patternIndex == myPattern.length) {
return FList.emptyList();
}
if ('*' == myPattern[patternIndex]) {
return skipChars(name, patternIndex, nameIndex, true);
}
if (nameIndex == name.length()) {
return null;
}
@@ -430,9 +433,6 @@ public class NameUtil {
if ('.' == myPattern[patternIndex] && name.charAt(nameIndex) != '.') {
return skipChars(name, patternIndex, nameIndex, false);
}
if ('*' == myPattern[patternIndex]) {
return skipChars(name, patternIndex, nameIndex, true);
}
if (patternIndex == 0 && myOptions != MatchingCaseSensitivity.NONE && name.charAt(nameIndex) != myPattern[0]) {
return null;
@@ -455,26 +455,22 @@ public class NameUtil {
int nextStart = NameUtil.nextWord(name, nameIndex);
boolean uppers = isWordStart(myPattern[patternIndex]);
int lastUpper = isWordStart(myPattern[patternIndex]) ? 0 : -1;
int i = 1;
while (true) {
if (patternIndex + i == myPattern.length) {
//end of pattern reached, the last word matches
return FList.<TextRange>emptyList().prepend(TextRange.from(nameIndex, i));
}
if (i + nameIndex == nextStart) {
//whole word match
if (patternIndex + i == myPattern.length || i + nameIndex == nextStart) {
break;
}
char p = myPattern[patternIndex + i];
if (uppers && isWordStart(p) && myOptions != MatchingCaseSensitivity.ALL) {
char w = name.charAt(i + nameIndex);
if (lastUpper == i - 1 && isWordStart(p) && myOptions != MatchingCaseSensitivity.ALL) {
if (p == w) {
lastUpper = i;
}
p = StringUtil.toLowerCase(p);
} else {
uppers = false;
}
char w = name.charAt(i + nameIndex);
if (myOptions != MatchingCaseSensitivity.ALL) {
w = StringUtil.toLowerCase(w);
}
@@ -484,29 +480,38 @@ public class NameUtil {
i++;
}
if (myPattern[patternIndex + i] == '*') {
nextStart = nameIndex + i;
if (isFinalSpaceMatch(name, patternIndex, nameIndex, nextStart, i)) {
return FList.<TextRange>emptyList().prepend(TextRange.from(nameIndex, i));
}
// there's more in the pattern, but no more words
if (nextStart == name.length()) {
if (patternIndex + i == myPattern.length - 1) {
char last = myPattern[patternIndex + i];
if (' ' == last && (i == 1 && isWordStart(myPattern[patternIndex]) || i + nameIndex == name.length()) ||
'*' == last) {
return FList.<TextRange>emptyList().prepend(TextRange.from(nameIndex, i));
return matchAfterFragment(name, patternIndex, nameIndex, nextStart, lastUpper, i);
}
private boolean isFinalSpaceMatch(String name, int patternIndex, int nameIndex, int nextStart, int i) {
return nextStart == name.length() &&
patternIndex + i == myPattern.length - 1 &&
' ' == myPattern[patternIndex + i] &&
(i == 1 && isWordStart(myPattern[patternIndex]) || i + nameIndex == name.length());
}
@Nullable
private FList<TextRange> matchAfterFragment(String name, int patternIndex, int nameIndex, int nextStart, int lastUpper, int matchLen) {
int star = patternIndex + matchLen < myPattern.length && myPattern[patternIndex + matchLen] == '*' ? matchLen : -1;
if (lastUpper >= 0) {
FList<TextRange> ranges = matchName(name, patternIndex + lastUpper + 1, lastUpper == star ? nameIndex + lastUpper : nextStart);
if (ranges != null) {
return prependRange(ranges, nameIndex, lastUpper + 1);
}
}
while (matchLen > 0) {
if (matchLen != lastUpper) {
FList<TextRange> ranges = matchName(name, patternIndex + matchLen, matchLen == star ? matchLen + lastUpper : nextStart);
if (ranges != null) {
return prependRange(ranges, nameIndex, matchLen);
}
}
return null;
}
while (i > 0) {
FList<TextRange> ranges = matchName(name, patternIndex + i, nextStart);
if (ranges != null) {
return prependRange(ranges, nameIndex, i);
}
i--;
matchLen--;
}
return null;
}
@@ -19,7 +19,6 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Getter;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vcs.Details;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.FilePathImpl;
@@ -27,7 +26,6 @@ import com.intellij.openapi.vcs.GenericDetailsLoader;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
import com.intellij.util.PairConsumer;
import com.intellij.util.ThreeState;
import com.intellij.util.containers.SLRUMap;
import com.intellij.vcsUtil.UIVcsUtil;
import org.jetbrains.annotations.Nullable;
@@ -198,9 +196,11 @@ public class ShortDiffDetails implements RefreshablePanel, Disposable {
@Override
public void dispose() {
if (myDetailsLoader != null) {
myDetailsLoader.dispose();
Disposer.dispose(myDetailsLoader);
}
if (myDetailsPanel != null) {
myDetailsPanel.clear();
}
myDetailsPanel.clear();
myDetailsCache.clear();
}
@@ -236,7 +236,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
throw new IllegalArgumentException("nothing found to execute commit with");
}
myAllOfDefaultChangeListChangesIncluded = changes.containsAll(defaultChangeList.getChanges());
myAllOfDefaultChangeListChangesIncluded = new HashSet<Change>(changes).containsAll(new HashSet<Change>(defaultChangeList.getChanges()));
myIsAlien = isAlien;
if (isAlien) {
@@ -42,12 +42,12 @@ import com.intellij.openapi.vcs.update.RefreshVFsSynchronously;
import com.intellij.util.Consumer;
import com.intellij.util.NullableFunction;
import com.intellij.util.WaitForProgressToShow;
import com.intellij.util.containers.hash.HashSet;
import com.intellij.util.ui.ConfirmationDialog;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
public class CommitHelper {
@@ -326,7 +326,7 @@ public class CommitHelper {
myAfterVcsRefreshModification = ChangeListsModificationAfterCommit.NOTHING;
if (myChangeList instanceof LocalChangeList) {
final LocalChangeList localList = (LocalChangeList) myChangeList;
final boolean containsAll = myIncludedChanges.containsAll(myChangeList.getChanges());
final boolean containsAll = new HashSet<Change>(myIncludedChanges).containsAll(new HashSet<Change>(myChangeList.getChanges()));
if (containsAll && !localList.isDefault() && !localList.isReadOnly()) {
myAfterVcsRefreshModification = ChangeListsModificationAfterCommit.DELETE_LIST;
}
@@ -87,7 +87,9 @@ public class LineStatusTracker {
myUpToDateDocument.putUserData(UndoConstants.DONT_RECORD_UNDO, Boolean.TRUE);
myProject = project;
myBaseLoaded = BaseLoadState.LOADING;
myRanges = new ArrayList<Range>();
synchronized (myLock) {
myRanges = new ArrayList<Range>();
}
myAnathemaThrown = false;
myFileEditorManager = FileEditorManager.getInstance(myProject);
}
@@ -205,7 +207,6 @@ public class LineStatusTracker {
}
removeAnathema();
removeHighlightersFromMarkupModel();
myRanges.clear();
myReleased = true;
}
}
@@ -238,7 +239,6 @@ public class LineStatusTracker {
myBulkUpdate = true;
removeAnathema();
removeHighlightersFromMarkupModel();
myRanges.clear();
}
}
@@ -249,6 +249,7 @@ public class LineStatusTracker {
range.getHighlighter().dispose();
}
}
myRanges.clear();
}
}
@@ -279,9 +280,7 @@ public class LineStatusTracker {
myUpToDateDocument.setReadOnly(true);
removeAnathema();
removeHighlightersFromMarkupModel();
myRanges.clear();
myBaseLoaded = BaseLoadState.LOADING;
return;
}
}
@@ -299,7 +298,7 @@ public class LineStatusTracker {
synchronized (myLock) {
if (myReleased) return;
if (myBulkUpdate || myAnathemaThrown || (BaseLoadState.LOADED != myBaseLoaded)) return;
if (myBulkUpdate || myAnathemaThrown || BaseLoadState.LOADED != myBaseLoaded) return;
try {
myFirstChangedLine = myDocument.getLineNumber(e.getOffset());
myLastChangedLine = myDocument.getLineNumber(e.getOffset() + e.getOldLength());
@@ -317,7 +316,7 @@ public class LineStatusTracker {
myUpToDateFirstLine = firstChangedRange.getUOffset1();
}
else {
myUpToDateFirstLine = firstChangedRange.getUOffset2() + (myFirstChangedLine - firstChangedRange.getOffset2());
myUpToDateFirstLine = firstChangedRange.getUOffset2() + myFirstChangedLine - firstChangedRange.getOffset2();
}
Range myLastChangedRange = getLastRangeBeforeLine(myLastChangedLine);
@@ -330,7 +329,7 @@ public class LineStatusTracker {
myLastChangedLine = myLastChangedRange.getOffset2();
}
else {
myUpToDateLastLine = myLastChangedRange.getUOffset2() + (myLastChangedLine - myLastChangedRange.getOffset2());
myUpToDateLastLine = myLastChangedRange.getUOffset2() + myLastChangedLine - myLastChangedRange.getOffset2();
}
} catch (ProcessCanceledException ignore) {
}
@@ -353,7 +352,7 @@ public class LineStatusTracker {
synchronized (myLock) {
if (myReleased) return;
if (myBulkUpdate || myAnathemaThrown || (BaseLoadState.LOADED != myBaseLoaded)) return;
if (myBulkUpdate || myAnathemaThrown || BaseLoadState.LOADED != myBaseLoaded) return;
try {
int line = myDocument.getLineNumber(e.getOffset() + e.getNewLength());
@@ -415,7 +414,6 @@ public class LineStatusTracker {
} catch (FilesTooBigForDiffException e1) {
installAnathema();
removeHighlightersFromMarkupModel();
myRanges.clear();
}
}
}
@@ -48,12 +48,12 @@ public class AndroidLogcatColorPage implements ColorSettingsPage {
"<assert>08-04 16:24:11.166: ASSERT/Assertion(4687): Expected true but was false</assert>";
static {
ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("verbose.level.title", AndroidLogcatConstants.VERBOSE_OUTPUT_KEY);
ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("debug.level.title", AndroidLogcatConstants.DEBUG_OUTPUT_KEY);
ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("info.level.title", AndroidLogcatConstants.INFO_OUTPUT_KEY);
ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("warning.level.title", AndroidLogcatConstants.WARNING_OUTPUT_KEY);
ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("error.level.title", AndroidLogcatConstants.ERROR_OUTPUT_KEY);
ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("assert.level.title", AndroidLogcatConstants.ASSERT_OUTPUT_KEY);
ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("verbose", AndroidLogcatConstants.VERBOSE_OUTPUT_KEY);
ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("debug", AndroidLogcatConstants.DEBUG_OUTPUT_KEY);
ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("info", AndroidLogcatConstants.INFO_OUTPUT_KEY);
ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("warning", AndroidLogcatConstants.WARNING_OUTPUT_KEY);
ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("error", AndroidLogcatConstants.ERROR_OUTPUT_KEY);
ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("assert", AndroidLogcatConstants.ASSERT_OUTPUT_KEY);
}
private static final AttributesDescriptor[] ATTRIBUTES_DESCRIPTORS =
@@ -135,6 +135,7 @@ public class GitVcs extends AbstractVcs<CommittedChangeList> {
private GitBranchWidget myBranchWidget;
private GitVersion myVersion = GitVersion.NULL; // version of Git which this plugin uses.
private static final int MAX_CONSOLE_OUTPUT_SIZE = 10000;
@Nullable
public static GitVcs getInstance(Project project) {
@@ -409,6 +410,9 @@ public class GitVcs extends AbstractVcs<CommittedChangeList> {
* @param style a style to use
*/
private void showMessage(@NotNull String message, final TextAttributes style) {
if (message.length() > MAX_CONSOLE_OUTPUT_SIZE) {
message = message.substring(0, MAX_CONSOLE_OUTPUT_SIZE);
}
myVcsManager.addMessageToConsoleWindow(message, style);
}
@@ -621,10 +621,8 @@ public abstract class GitHandler {
boolean suspendable = false;
switch (myCommand.lockingPolicy()) {
case META:
// do nothing no locks are taken for metadata
break;
case READ:
vcs.getCommandLock().readLock().lock();
// need to lock only write operations: reads can be performed even when a write operation is going on
break;
case WRITE_SUSPENDABLE:
suspendable = true;
@@ -716,10 +714,7 @@ public abstract class GitHandler {
finally {
switch (myCommand.lockingPolicy()) {
case META:
// do nothing no locks are taken for metadata
break;
case READ:
vcs.getCommandLock().readLock().unlock();
break;
case WRITE_SUSPENDABLE:
case WRITE:
@@ -277,7 +277,7 @@ class GitPushResult {
sb.append(successReport);
if (!updatedFiles.isEmpty()) {
sb.append("<a href='UpdatedFiles'>View files updated during the push<a/>");
sb.append("<a href='UpdatedFiles'>View files updated during the push</a>");
}
NotificationListener viewUpdateFilesListener = new ViewUpdatedFilesNotificationListener(updatedFiles);
+3 -1
View File
@@ -53,7 +53,6 @@
<!--Generic application services-->
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.remote.GradleApiFacadeManager"/>
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.util.GradleLibraryManager"/>
<applicationService serviceImplementation="org.jetbrains.plugins.gradle.task.GradleTaskManager"/>
<applicationService serviceInterface="org.jetbrains.plugins.gradle.notification.GradleProgressNotificationManager"
serviceImplementation="org.jetbrains.plugins.gradle.notification.GradleProgressNotificationManagerImpl"/>
<applicationService serviceInterface="org.jetbrains.plugins.gradle.config.PlatformFacade"
@@ -101,6 +100,9 @@
<component>
<implementation-class>org.jetbrains.plugins.gradle.notification.GradleConfigNotificationManager</implementation-class>
</component>
<component>
<implementation-class>org.jetbrains.plugins.gradle.task.GradleTaskManager</implementation-class>
</component>
</project-components>
<actions>
@@ -2,7 +2,6 @@ package org.jetbrains.plugins.gradle.action;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
@@ -32,7 +31,7 @@ public class GradleRefreshProjectAction extends AbstractGradleLinkedProjectActio
@Override
protected void doUpdate(@NotNull Presentation presentation, @NotNull Project project, @NotNull String linkedProjectPath) {
boolean enabled = false;
final GradleTaskManager taskManager = ServiceManager.getService(GradleTaskManager.class);
final GradleTaskManager taskManager = project.getComponent(GradleTaskManager.class);
if (taskManager != null) {
enabled = !taskManager.hasTaskOfTypeInProgress(GradleTaskType.RESOLVE_PROJECT);
}
@@ -37,6 +37,8 @@ import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.concurrent.TimeUnit;
@@ -117,6 +119,22 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
}
}
};
myComponent.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (!"ancestor".equals(evt.getPropertyName())) {
return;
}
// Configure the balloon to show on initial configurable drawing.
myShowBalloonIfNecessary = evt.getNewValue() != null && evt.getOldValue() == null;
if (evt.getNewValue() == null && evt.getOldValue() != null) {
// Cancel delayed balloons when the configurable is hidden.
myAlarm.cancelAllRequests();
}
}
});
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridwidth = GridBagConstraints.REMAINDER;
constraints.weightx = 1;
@@ -151,7 +169,6 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
@Override
public boolean isModified() {
myShowBalloonIfNecessary = true;
if (!myPathManuallyModified) {
return false;
}
@@ -169,17 +186,25 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
useNormalColorForPath();
String path = myGradleHomeComponent.getPath();
GradleSettings.applyGradleHome(path, myProject);
// There is a possible case that user defines gradle home for particular open project. We want to apply that value
// to the default project as well if it's still non-defined.
Project defaultProject = ProjectManager.getInstance().getDefaultProject();
if (defaultProject == myProject) {
if (isValidGradleHome(path)) {
myGradleHomeSettingType = GradleHomeSettingType.EXPLICIT_CORRECT;
// There is a possible case that user defines gradle home for particular open project. We want to apply that value
// to the default project as well if it's still non-defined.
Project defaultProject = ProjectManager.getInstance().getDefaultProject();
if (defaultProject != myProject && !isValidGradleHome(GradleSettings.getInstance(defaultProject).getGradleHome())) {
GradleSettings.applyGradleHome(path, defaultProject);
}
return;
}
if (isValidGradleHome(path) && !isValidGradleHome(GradleSettings.getInstance(defaultProject).getGradleHome())) {
GradleSettings.applyGradleHome(path, defaultProject);
}
if (StringUtil.isEmpty(path)) {
myGradleHomeSettingType = GradleHomeSettingType.UNKNOWN;
}
else {
myGradleHomeSettingType = GradleHomeSettingType.EXPLICIT_INCORRECT;
new DelayedBalloonInfo(MessageType.ERROR, myGradleHomeSettingType, 0).run();
}
}
private boolean isValidGradleHome(@Nullable String path) {
@@ -203,7 +228,7 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
GradleHomeSettingType.EXPLICIT_CORRECT :
GradleHomeSettingType.EXPLICIT_INCORRECT;
if (myGradleHomeSettingType == GradleHomeSettingType.EXPLICIT_INCORRECT) {
new DelayedBalloonInfo(MessageType.ERROR, myGradleHomeSettingType).run();
new DelayedBalloonInfo(MessageType.ERROR, myGradleHomeSettingType, 0).run();
}
else {
myAlarm.cancelAllRequests();
@@ -283,9 +308,13 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
private final long myTriggerTime;
DelayedBalloonInfo(@NotNull MessageType messageType, @NotNull GradleHomeSettingType settingType) {
this(messageType, settingType, BALLOON_DELAY_MILLIS);
}
DelayedBalloonInfo(@NotNull MessageType messageType, @NotNull GradleHomeSettingType settingType, long delayMillis) {
myMessageType = messageType;
myText = settingType.getDescription();
myTriggerTime = System.currentTimeMillis() + BALLOON_DELAY_MILLIS;
myTriggerTime = System.currentTimeMillis() + delayMillis;
}
@Override
@@ -296,11 +325,15 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
myAlarm.addRequest(this, diff);
return;
}
if (myGradleHomeComponent == null || !myGradleHomeComponent.getPathComponent().isShowing()) {
if (myGradleHomeComponent == null) {
myAlarm.cancelAllRequests();
myAlarm.addRequest(this, 200);
return;
}
if (!myGradleHomeComponent.getPathComponent().isShowing()) {
// Don't schedule the balloon if the configurable is hidden.
return;
}
GradleUtil.showBalloon(myGradleHomeComponent.getPathComponent(), myMessageType, myText);
}
}
@@ -338,7 +338,7 @@ public class GradleModulesImporter {
public void run(@NotNull final ProgressIndicator indicator) {
GradleResolveProjectTask task = new GradleResolveProjectTask(intellijProject, gradleProjectPath, true);
task.execute(indicator);
GradleProject projectWithResolvedLibraries = task.getProject();
GradleProject projectWithResolvedLibraries = task.getGradleProject();
gradleProjectRef.set(projectWithResolvedLibraries);
ApplicationManager.getApplication().invokeLater(setupExternalDependenciesTask, ModalityState.NON_MODAL);
}
@@ -14,11 +14,15 @@ import com.intellij.execution.process.ProcessTerminatedListener;
import com.intellij.execution.rmi.RemoteProcessSupport;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.ide.actions.OpenProjectFileChooserDescriptor;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.projectRoots.*;
import com.intellij.openapi.roots.DependencyScope;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.ShutDownTracker;
import com.intellij.openapi.util.text.StringUtil;
@@ -27,8 +31,10 @@ import com.intellij.psi.PsiBundle;
import com.intellij.util.Alarm;
import com.intellij.util.PathUtil;
import com.intellij.util.SystemProperties;
import com.intellij.util.containers.ConcurrentWeakHashMap;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.notification.GradleProgressNotificationManager;
import org.jetbrains.plugins.gradle.notification.GradleProgressNotificationManagerImpl;
import org.jetbrains.plugins.gradle.remote.impl.GradleApiFacadeImpl;
@@ -49,8 +55,8 @@ import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
/**
* Entry point to work with remote {@link GradleApiFacade}.
@@ -62,15 +68,19 @@ import java.util.concurrent.atomic.AtomicReference;
*/
public class GradleApiFacadeManager {
private static final Pair<GradleApiFacade, RemoteGradleProcessSettings> NULL_VALUE = Pair.empty();
private static final String REMOTE_PROCESS_TTL_IN_MS_KEY = "gradle.remote.process.ttl.ms";
private static final String MAIN_CLASS_NAME = GradleApiFacadeImpl.class.getName();
private static final int REMOTE_FAIL_RECOVERY_ATTEMPTS_NUMBER = 3;
private final AtomicReference<Pair<GradleApiFacade, RemoteGradleProcessSettings>> myFacade
= new AtomicReference<Pair<GradleApiFacade, RemoteGradleProcessSettings>>();
private final AtomicReference<RemoteGradleProgressNotificationManager> myExportedProgressManager
= new AtomicReference<RemoteGradleProgressNotificationManager>();
private final ConcurrentMap<String /*project name*/, GradleApiFacade> myFacadeWrappers
= new ConcurrentWeakHashMap<String, GradleApiFacade>();
private final ConcurrentMap<String /*project name*/, RemoteGradleProgressNotificationManager> myRemoteNotificationManagers
= new ConcurrentWeakHashMap<String, RemoteGradleProgressNotificationManager>();
private final ConcurrentMap<String /*project name*/, Pair<GradleApiFacade, RemoteGradleProcessSettings>> myRemoteFacades
= new ConcurrentWeakHashMap<String, Pair<GradleApiFacade, RemoteGradleProcessSettings>>();
@NotNull private final GradleLibraryManager myGradleLibraryManager;
@NotNull private final GradleProgressNotificationManagerImpl myProgressManager;
@@ -78,13 +88,12 @@ public class GradleApiFacadeManager {
// Please note that we don't use RemoteGradleProcessSettings as the 'Configuration' type parameter here because we need
// to apply the settings to the newly created process. I.e. every time new process is created we need to call
// 'GradleApiFacade.applySettings()'. So, we need to hold reference to the last returned 'GradleApiFacade' stub anyway.
private final RemoteProcessSupport<Object, GradleApiFacade, Object> mySupport;
private final GradleApiFacade myApiFacade;
private final RemoteProcessSupport<Object, GradleApiFacade, String> mySupport;
public GradleApiFacadeManager(@NotNull GradleLibraryManager gradleLibraryManager, @NotNull GradleProgressNotificationManager manager) {
myGradleLibraryManager = gradleLibraryManager;
myProgressManager = (GradleProgressNotificationManagerImpl)manager;
mySupport = new RemoteProcessSupport<Object, GradleApiFacade, Object>(GradleApiFacade.class) {
mySupport = new RemoteProcessSupport<Object, GradleApiFacade, String>(GradleApiFacade.class) {
@Override
protected void fireModificationCountChanged() {
}
@@ -95,13 +104,10 @@ public class GradleApiFacadeManager {
}
@Override
protected RunProfileState getRunProfileState(Object o, Object configuration, Executor executor) throws ExecutionException {
return createRunProfileState();
protected RunProfileState getRunProfileState(Object o, String configuration, Executor executor) throws ExecutionException {
return createRunProfileState(findProjectByName(configuration));
}
};
myApiFacade = (GradleApiFacade)Proxy.newProxyInstance(
GradleApiFacadeManager.class.getClassLoader(), new Class[]{GradleApiFacade.class}, new MyHandler()
);
ShutDownTracker.getInstance().registerShutdownTask(new Runnable() {
public void run() {
@@ -110,10 +116,21 @@ public class GradleApiFacadeManager {
});
}
private RunProfileState createRunProfileState() {
@NotNull
private static Project findProjectByName(@NotNull String name) {
final ProjectManager projectManager = ProjectManager.getInstance();
for (Project project : projectManager.getOpenProjects()) {
if (name.equals(project.getName())) {
return project;
}
}
return projectManager.getDefaultProject();
}
private RunProfileState createRunProfileState(@Nullable final Project project) {
return new CommandLineState(null) {
private SimpleJavaParameters createJavaParameters() throws ExecutionException {
Collection<File> gradleLibraries = myGradleLibraryManager.getAllLibraries();
Collection<File> gradleLibraries = myGradleLibraryManager.getAllLibraries(project);
GradleLog.LOG.assertTrue(gradleLibraries != null, GradleBundle.message("gradle.generic.text.error.sdk.undefined"));
if (gradleLibraries == null) {
throw new ExecutionException("Can't find gradle libraries");
@@ -193,19 +210,29 @@ public class GradleApiFacadeManager {
* @throws Exception in case of inability to return the facade
*/
@NotNull
public GradleApiFacade getFacade() throws Exception {
return myApiFacade;
public GradleApiFacade getFacade(@Nullable Project project) throws Exception {
if (project == null) {
project = ProjectManager.getInstance().getDefaultProject();
}
final GradleApiFacade facade = myFacadeWrappers.get(project.getName());
if (facade == null) {
final GradleApiFacade newFacade = (GradleApiFacade)Proxy.newProxyInstance(
GradleApiFacadeManager.class.getClassLoader(), new Class[]{GradleApiFacade.class}, new MyHandler(project)
);
myFacadeWrappers.putIfAbsent(project.getName(), newFacade);
}
return myFacadeWrappers.get(project.getName());
}
public Object doInvoke(Method method, Object[] args, int invocationNumber) throws Throwable {
GradleApiFacade facade = doGetFacade();
public Object doInvoke(@NotNull Project project, Method method, Object[] args, int invocationNumber) throws Throwable {
GradleApiFacade facade = doGetFacade(project);
try {
return method.invoke(facade, args);
}
catch (InvocationTargetException e) {
if (e.getTargetException() instanceof RemoteException && invocationNumber > 0) {
Thread.sleep(1000);
return doInvoke(method, args, invocationNumber - 1);
return doInvoke(project, method, args, invocationNumber - 1);
}
else {
throw e;
@@ -213,43 +240,57 @@ public class GradleApiFacadeManager {
}
}
@SuppressWarnings("ConstantConditions")
@NotNull
private GradleApiFacade doGetFacade() throws Exception {
if (!GradleUtil.isGradleAvailable()) {
private GradleApiFacade doGetFacade(@NotNull Project project) throws Exception {
if (project.isDisposed() || !GradleUtil.isGradleAvailable(project)) {
return GradleApiFacade.NULL_OBJECT;
}
Pair<GradleApiFacade, RemoteGradleProcessSettings> pair = myFacade.get();
Pair<GradleApiFacade, RemoteGradleProcessSettings> pair = myRemoteFacades.get(project.getName());
if (pair != null) {
if (isValid(pair)) {
if (isValid(pair, project)) {
return pair.first;
}
mySupport.stopAll(true);
myFacade.compareAndSet(pair, null);
myFacadeWrappers.clear();
myRemoteFacades.clear();
final Pair<GradleApiFacade, RemoteGradleProcessSettings> p = myRemoteFacades.putIfAbsent(project.getName(), NULL_VALUE);
if (p != null && p != NULL_VALUE) {
return p.first;
}
}
final GradleApiFacade facade = mySupport.acquire(this, "");
final GradleApiFacade facade = mySupport.acquire(this, project.getName());
if (facade == null) {
throw new IllegalStateException("Can't obtain facade to working with gradle api at the remote process");
throw new IllegalStateException("Can't obtain facade to working with gradle api at the remote process. Project: " + project);
}
Disposer.register(project, new Disposable() {
@Override
public void dispose() {
mySupport.stopAll(true);
myFacadeWrappers.clear();
myRemoteFacades.clear();
}
});
final GradleApiFacade result = new GradleApiFacadeWrapper(facade, myProgressManager);
Pair<GradleApiFacade, RemoteGradleProcessSettings> newPair
= new Pair<GradleApiFacade, RemoteGradleProcessSettings>(result, getRemoteSettings());
if (!myFacade.compareAndSet(null, newPair)) {
GradleLog.LOG.warn("Detected unexpected duplicate tooling api facade instance creation");
return myFacade.get().first;
= new Pair<GradleApiFacade, RemoteGradleProcessSettings>(result, getRemoteSettings(project));
if (myRemoteFacades.putIfAbsent(project.getName(), newPair) != null && !myRemoteFacades.replace(project.getName(), NULL_VALUE, newPair)) {
GradleLog.LOG.warn("Detected unexpected duplicate tooling api facade instance creation. Project: " + project);
return myRemoteFacades.get(project.getName()).first;
}
if (!StringUtil.isEmpty(newPair.second.getJavaHome())) {
GradleLog.LOG.info("Instructing gradle to use java from " + newPair.second.getJavaHome());
}
result.applySettings(newPair.second);
RemoteGradleProgressNotificationManager exported = myExportedProgressManager.get();
RemoteGradleProgressNotificationManager exported = myRemoteNotificationManagers.get(project.getName());
if (exported == null) {
try {
exported = (RemoteGradleProgressNotificationManager)UnicastRemoteObject.exportObject(myProgressManager, 0);
myExportedProgressManager.set(exported);
myRemoteNotificationManagers.putIfAbsent(project.getName(), exported);
}
catch (RemoteException e) {
exported = myExportedProgressManager.get();
exported = myRemoteNotificationManagers.get(project.getName());
}
}
if (exported == null) {
@@ -261,7 +302,11 @@ public class GradleApiFacadeManager {
return result;
}
private boolean isValid(@NotNull Pair<GradleApiFacade, RemoteGradleProcessSettings> pair) {
private boolean isValid(@NotNull Pair<GradleApiFacade, RemoteGradleProcessSettings> pair, @Nullable Project project) {
if (pair == NULL_VALUE) {
return false;
}
// Check remote process is alive.
try {
pair.first.getResolver();
@@ -272,8 +317,8 @@ public class GradleApiFacadeManager {
// Check that significant settings are not changed
RemoteGradleProcessSettings oldSettings = pair.second;
RemoteGradleProcessSettings currentSettings = getRemoteSettings();
RemoteGradleProcessSettings currentSettings = getRemoteSettings(project);
// We restart the slave process because there is a possible case that it was started with the incorrect classpath.
// For example, it could be started with gradle milestone-3 and that means that its classpath doesn't contain BasicIdeaProject.class.
// So, even if the user defines gradle milestone-7 to use, the slave process still is unable to operate because its classpath
@@ -285,8 +330,8 @@ public class GradleApiFacadeManager {
}
@NotNull
private RemoteGradleProcessSettings getRemoteSettings() {
File gradleHome = myGradleLibraryManager.getGradleHome();
private RemoteGradleProcessSettings getRemoteSettings(@Nullable Project project) {
File gradleHome = myGradleLibraryManager.getGradleHome(project);
RemoteGradleProcessSettings result = new RemoteGradleProcessSettings(gradleHome.getAbsolutePath());
String ttlAsString = System.getProperty(REMOTE_PROCESS_TTL_IN_MS_KEY);
if (ttlAsString != null) {
@@ -304,9 +349,16 @@ public class GradleApiFacadeManager {
}
private class MyHandler implements InvocationHandler {
@NotNull private final String myProjectName;
MyHandler(@NotNull Project project) {
myProjectName = project.getName();
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return doInvoke(method, args, REMOTE_FAIL_RECOVERY_ATTEMPTS_NUMBER);
return doInvoke(findProjectByName(myProjectName), method, args, REMOTE_FAIL_RECOVERY_ATTEMPTS_NUMBER);
}
}
}
@@ -3,7 +3,9 @@ package org.jetbrains.plugins.gradle.task;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.notification.GradleProgressNotificationManager;
import org.jetbrains.plugins.gradle.notification.GradleTaskNotificationEvent;
import org.jetbrains.plugins.gradle.notification.GradleTaskNotificationListener;
@@ -28,9 +30,11 @@ public abstract class AbstractGradleTask implements GradleTask {
private final AtomicReference<GradleTaskState> myState = new AtomicReference<GradleTaskState>(GradleTaskState.NOT_STARTED);
private final AtomicReference<Throwable> myError = new AtomicReference<Throwable>();
private final GradleTaskId myId;
@Nullable transient private final Project myIntellijProject;
@NotNull private final GradleTaskId myId;
protected AbstractGradleTask(@NotNull GradleTaskType type) {
protected AbstractGradleTask(Project project, @NotNull GradleTaskType type) {
myIntellijProject = project;
myId = GradleTaskId.create(type);
}
@@ -53,13 +57,18 @@ public abstract class AbstractGradleTask implements GradleTask {
return myError.get();
}
@Nullable
public Project getIntellijProject() {
return myIntellijProject;
}
public void refreshState() {
if (getState() != GradleTaskState.IN_PROGRESS) {
return;
}
final GradleApiFacadeManager manager = ServiceManager.getService(GradleApiFacadeManager.class);
try {
final GradleApiFacade facade = manager.getFacade();
final GradleApiFacade facade = manager.getFacade(myIntellijProject);
setState(facade.isTaskInProgress(getId()) ? GradleTaskState.IN_PROGRESS : GradleTaskState.FAILED);
}
catch (Throwable e) {
@@ -21,20 +21,19 @@ public class GradleResolveProjectTask extends AbstractGradleTask {
private final AtomicReference<GradleProject> myGradleProject = new AtomicReference<GradleProject>();
private final Project myIntellijProject;
private final String myProjectPath;
private final boolean myResolveLibraries;
public GradleResolveProjectTask(@Nullable Project project, @NotNull String projectPath, boolean resolveLibraries) {
super(GradleTaskType.RESOLVE_PROJECT);
myIntellijProject = project;
super(project, GradleTaskType.RESOLVE_PROJECT);
myProjectPath = projectPath;
myResolveLibraries = resolveLibraries;
}
protected void doExecute() throws Exception {
final GradleApiFacadeManager manager = ServiceManager.getService(GradleApiFacadeManager.class);
GradleProjectResolver resolver = manager.getFacade().getResolver();
GradleProjectResolver resolver = manager.getFacade(getIntellijProject()).getResolver();
setState(GradleTaskState.IN_PROGRESS);
final GradleProject project = resolver.resolveProjectInfo(getId(), myProjectPath, myResolveLibraries);
if (project == null) {
@@ -42,10 +41,11 @@ public class GradleResolveProjectTask extends AbstractGradleTask {
}
myGradleProject.set(project);
setState(GradleTaskState.FINISHED);
if (myIntellijProject == null || myIntellijProject.isDisposed()) {
final Project intellijProject = getIntellijProject();
if (intellijProject == null || intellijProject.isDisposed()) {
return;
}
final GradleProjectStructureChangesModel model = myIntellijProject.getComponent(GradleProjectStructureChangesModel.class);
final GradleProjectStructureChangesModel model = intellijProject.getComponent(GradleProjectStructureChangesModel.class);
if (model != null) {
// This task may be called during the 'import from gradle' processing, hence, no project-level IoC is up.
// Model update is necessary for the correct tool window project structure diff showing but we don't have
@@ -55,7 +55,7 @@ public class GradleResolveProjectTask extends AbstractGradleTask {
}
@Nullable
public GradleProject getProject() {
public GradleProject getGradleProject() {
return myGradleProject.get();
}
}
@@ -1,5 +1,8 @@
package org.jetbrains.plugins.gradle.task;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.project.Project;
import com.intellij.util.Alarm;
import com.intellij.util.containers.ConcurrentHashMap;
import org.jetbrains.annotations.NotNull;
@@ -23,7 +26,7 @@ import java.util.concurrent.TimeUnit;
* @author Denis Zhdanov
* @since 2/8/12 1:52 PM
*/
public class GradleTaskManager implements GradleTaskNotificationListener {
public class GradleTaskManager extends AbstractProjectComponent implements GradleTaskNotificationListener {
/**
* We receive information about the tasks being enqueued to the slave gradle projects here. However, there is a possible
@@ -45,9 +48,19 @@ public class GradleTaskManager implements GradleTaskNotificationListener {
@NotNull private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD);
@NotNull private final GradleApiFacadeManager myFacadeManager;
@NotNull private final GradleProgressNotificationManager myProgressNotificationManager;
public GradleTaskManager(@NotNull GradleApiFacadeManager facadeManager, @NotNull GradleProgressNotificationManager notificationManager) {
public GradleTaskManager(@NotNull Project project,
@NotNull GradleApiFacadeManager facadeManager,
@NotNull GradleProgressNotificationManager notificationManager)
{
super(project);
myFacadeManager = facadeManager;
myProgressNotificationManager = notificationManager;
if (ApplicationManager.getApplication().isUnitTestMode()) {
return;
}
notificationManager.addNotificationListener(this);
myAlarm.addRequest(new Runnable() {
@Override
@@ -67,7 +80,12 @@ public class GradleTaskManager implements GradleTaskNotificationListener {
}
}, DETECT_HANGED_TASKS_FREQUENCY_MILLIS);
}
@Override
public void disposeComponent() {
myProgressNotificationManager.removeNotificationListener(this);
}
/**
* Allows to check if any task of the given type is being executed at the moment.
*
@@ -106,7 +124,7 @@ public class GradleTaskManager implements GradleTaskNotificationListener {
public void update() {
try {
final Map<GradleTaskType, Set<GradleTaskId>> currentState = myFacadeManager.getFacade().getTasksInProgress();
final Map<GradleTaskType, Set<GradleTaskId>> currentState = myFacadeManager.getFacade(myProject).getTasksInProgress();
myTasksInProgress.clear();
for (Set<GradleTaskId> ids : currentState.values()) {
for (GradleTaskId id : ids) {

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