Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ekaterina Tuzova
2014-12-27 15:04:53 +03:00
351 changed files with 5709 additions and 2995 deletions
+1
View File
@@ -145,6 +145,7 @@ binding.setVariable("loadProject", {
def compilerOptions = JpsJavaExtensionService.instance.getOrCreateCompilerConfiguration(project).currentCompilerOptions
compilerOptions.GENERATE_NO_WARNINGS = true
compilerOptions.DEPRECATION = false
compilerOptions.ADDITIONAL_OPTIONS_STRING = compilerOptions.ADDITIONAL_OPTIONS_STRING.replace("-Xlint:unchecked", "")
})
boolean hasSourceRoots(JpsModule module) {
@@ -0,0 +1,30 @@
/*
* Copyright 2000-2014 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.ant;
import org.apache.tools.ant.types.RegularExpression;
/**
* A pattern which is used to skip NotNull assertion instrumentation on classes that have at least one annotation matching this pattern.
*
* Example usage:
*
* <javac2 ...>
* <skip pattern="com/acme/Instrumented"/>
* </javac2>
*/
public class ClassFilterAnnotationRegexp extends RegularExpression {
}
@@ -25,10 +25,8 @@ import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Javac;
import org.apache.tools.ant.types.Path;
import org.jetbrains.org.objectweb.asm.ClassReader;
import org.jetbrains.org.objectweb.asm.ClassVisitor;
import org.jetbrains.org.objectweb.asm.ClassWriter;
import org.jetbrains.org.objectweb.asm.Opcodes;
import org.apache.tools.ant.util.regexp.Regexp;
import org.jetbrains.org.objectweb.asm.*;
import java.io.*;
import java.net.MalformedURLException;
@@ -40,6 +38,7 @@ public class Javac2 extends Javac {
private ArrayList myFormFiles;
private List myNestedFormPathList;
private boolean instrumentNotNull = true;
private List<Regexp> myClassFilterAnnotationRegexpList = new ArrayList<Regexp>(0);
public Javac2() {
}
@@ -75,6 +74,16 @@ public class Javac2 extends Javac {
this.instrumentNotNull = instrumentNotNull;
}
/**
* Allows to specify patterns of annotation class names to skip NotNull instrumentation on classes which have at least one
* annotation matching at least one of the given patterns
*
* @param regexp the regular expression for JVM internal name (slash-separated) of annotations
*/
public void add(final ClassFilterAnnotationRegexp regexp) {
myClassFilterAnnotationRegexpList.add(regexp.getRegexp(getProject()));
}
/**
* The overridden setter method that warns about unsupported option.
*
@@ -425,8 +434,8 @@ public class Javac2 extends Javac {
ClassReader reader = new ClassReader(inputStream);
int version = getClassFileVersion(reader);
if (version >= Opcodes.V1_5) {
if (version >= Opcodes.V1_5 && !shouldBeSkippedByAnnotationPattern(reader)) {
ClassWriter writer = new InstrumenterClassWriter(getAsmClassWriterFlags(version), finder);
if (NotNullVerifyingInstrumenter.processClassFile(reader, writer)) {
@@ -471,6 +480,30 @@ public class Javac2 extends Javac {
return classfileVersion[0];
}
private boolean shouldBeSkippedByAnnotationPattern(ClassReader reader) {
if (myClassFilterAnnotationRegexpList.isEmpty()) {
return false;
}
final boolean[] result = new boolean[]{false};
reader.accept(new ClassVisitor(Opcodes.ASM5) {
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (!result[0]) {
String internalName = Type.getType(desc).getInternalName();
for (Regexp regexp : myClassFilterAnnotationRegexpList) {
if (regexp.matches(internalName)) {
result[0] = true;
break;
}
}
}
return null;
}
}, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
return result[0];
}
private void fireError(final String message) {
if (failOnError) {
throw new BuildException(message, getLocation());
@@ -241,7 +241,7 @@ public class FrameVariablesTree extends DebuggerTree {
}
final byte[] bytecodes = method.bytecodes();
if (bytecodes != null && bytecodes.length > 0) {
final int firstLocalVariableSlot = argumentCount + (method.isStatic()? 0 : 1);
final int firstLocalVariableSlot = ArgumentValueDescriptorImpl.getFirstLocalsSlot(method);
final long instructionIndex = location.codeIndex();
final TIntObjectHashMap<DecompiledLocalVariable> usedVars = new TIntObjectHashMap<DecompiledLocalVariable>();
new InstructionParser(bytecodes, instructionIndex) {
@@ -27,6 +27,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import com.sun.jdi.Method;
import com.sun.jdi.PrimitiveValue;
import com.sun.jdi.Value;
@@ -78,8 +79,7 @@ public class ArgumentValueDescriptorImpl extends ValueDescriptorImpl{
if (body != null) {
final StringBuilder nameBuilder = new StringBuilder();
try {
final int startSlot = params.getParametersCount() + (method.hasModifierProperty(PsiModifier.STATIC)? 0 : 1);
body.accept(new LocalVariableNameFinder(startSlot, nameBuilder));
body.accept(new LocalVariableNameFinder(getFirstLocalsSlot(method), nameBuilder));
}
finally {
myName = nameBuilder.length() > 0? myDefaultName + ": " + nameBuilder.toString() : myDefaultName;
@@ -93,6 +93,36 @@ public class ArgumentValueDescriptorImpl extends ValueDescriptorImpl{
return myValue;
}
private static int getFirstLocalsSlot(PsiMethod method) {
int startSlot = method.hasModifierProperty(PsiModifier.STATIC) ? 0 : 1;
for (PsiParameter parameter : method.getParameterList().getParameters()) {
startSlot += getTypeSlotSize(parameter.getType());
}
return startSlot;
}
private static int getTypeSlotSize(PsiType varType) {
if (varType == PsiType.DOUBLE || varType == PsiType.LONG) {
return 2;
}
return 1;
}
public static int getFirstLocalsSlot(Method method) {
int firstLocalVariableSlot = method.isStatic() ? 0 : 1;
for (String type : method.argumentTypeNames()) {
firstLocalVariableSlot += getTypeSlotSize(type);
}
return firstLocalVariableSlot;
}
private static int getTypeSlotSize(String name) {
if (PsiKeyword.DOUBLE.equals(name) || PsiKeyword.LONG.equals(name)) {
return 2;
}
return 1;
}
public String getName() {
return myName;
}
@@ -127,8 +157,7 @@ public class ArgumentValueDescriptorImpl extends ValueDescriptorImpl{
@Override
public void visitLocalVariable(PsiLocalVariable variable) {
appendName(variable.getName());
final PsiType varType = variable.getType();
myCurrentSlotIndex += (varType == PsiType.DOUBLE || varType == PsiType.LONG)? 2 : 1;
myCurrentSlotIndex += getTypeSlotSize(variable.getType());
}
public void visitSynchronizedStatement(PsiSynchronizedStatement statement) {
@@ -26,6 +26,7 @@ import com.intellij.execution.util.ExecutionErrorDialog;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.text.StringUtil;
@@ -168,7 +169,7 @@ public class JavaExecutionUtil {
@Nullable
public static PsiClass findMainClass(final Project project, final String mainClassName, final GlobalSearchScope scope) {
if (project.isDefault()) return null;
if (project.isDefault() || DumbService.isDumb(project)) return null;
final PsiManager psiManager = PsiManager.getInstance(project);
final String shortName = StringUtil.getShortName(mainClassName);
final String packageName = StringUtil.getPackageName(mainClassName);
@@ -26,14 +26,14 @@ import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
class IdeaProjectStoreImpl extends ProjectWithModulesStoreImpl {
public IdeaProjectStoreImpl(@NotNull ProjectImpl project) {
super(project);
public IdeaProjectStoreImpl(@NotNull ProjectImpl project, @NotNull PathMacroManager pathMacroManager) {
super(project, pathMacroManager);
}
@NotNull
@Override
protected StateStorageManager createStateStorageManager() {
return new ProjectStateStorageManager(PathMacroManager.getInstance(getComponentManager()).createTrackingSubstitutor(), myProject) {
return new ProjectStateStorageManager(myPathMacroManager.createTrackingSubstitutor(), myProject) {
@Override
public StorageData createIprStorageData(@NotNull String filePath) {
return new IdeaIprStorageData(ROOT_TAG_NAME, myProject, filePath);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -21,6 +21,7 @@ import com.intellij.ide.util.projectWizard.ProjectTemplateParameterFactory;
import com.intellij.ide.util.projectWizard.WizardInputField;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.openapi.util.io.StreamUtil;
import com.intellij.platform.ProjectTemplate;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
@@ -29,7 +30,6 @@ import com.intellij.util.xmlb.annotations.AbstractCollection;
import com.intellij.util.xmlb.annotations.Property;
import com.intellij.util.xmlb.annotations.Tag;
import org.jdom.Element;
import org.jdom.Namespace;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -45,7 +45,6 @@ import java.util.zip.ZipInputStream;
*/
@Tag("template")
public abstract class ArchivedProjectTemplate implements ProjectTemplate {
public static final String INPUT_FIELD = "input-field";
protected final String myDisplayName;
@@ -110,22 +109,26 @@ public abstract class ArchivedProjectTemplate implements ProjectTemplate {
return null;
}
public abstract ZipInputStream getStream() throws IOException;
public static abstract class StreamConsumer<T> {
public abstract T consume(@NotNull ZipInputStream stream) throws IOException;
}
public abstract <T> void getStream(@NotNull StreamConsumer<T> consumer) throws IOException;
@Nullable
public String getCategory() {
return myCategory;
}
public void populateFromElement(@NotNull Element element, final Namespace ns) {
public void populateFromElement(@NotNull Element element) {
XmlSerializer.deserializeInto(this, element);
myInputFields = getFields(element, ns);
myInputFields = getFields(element);
}
private static List<WizardInputField> getFields(Element templateElement, final Namespace ns) {
private static List<WizardInputField> getFields(Element templateElement) {
//noinspection unchecked
return ContainerUtil
.mapNotNull(templateElement.getChildren(INPUT_FIELD, ns), new Function<Element, WizardInputField>() {
.mapNotNull(templateElement.getChildren(INPUT_FIELD), new Function<Element, WizardInputField>() {
@Override
public WizardInputField fun(Element element) {
ProjectTemplateParameterFactory factory = WizardInputField.getFactoryById(element.getText());
@@ -134,4 +137,12 @@ public abstract class ArchivedProjectTemplate implements ProjectTemplate {
});
}
static <T> void consumeZipStream(@NotNull StreamConsumer<T> consumer, @NotNull ZipInputStream stream) throws IOException {
try {
consumer.consume(stream);
}
finally {
StreamUtil.closeStream(stream);
}
}
}
@@ -26,6 +26,7 @@ import com.intellij.platform.ProjectTemplate;
import com.intellij.platform.ProjectTemplatesFactory;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.MultiMap;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -33,13 +34,17 @@ import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author Dmitry Avdeev
* @since 10/1/12
*/
public class ArchivedTemplatesFactory extends ProjectTemplatesFactory {
private final static Logger LOG = Logger.getInstance(ArchivedTemplatesFactory.class);
static final String ZIP = ".zip";
@@ -47,8 +52,8 @@ public class ArchivedTemplatesFactory extends ProjectTemplatesFactory {
@NotNull
@Override
protected MultiMap<String, Pair<URL, ClassLoader>> compute() {
MultiMap<String, Pair<URL, ClassLoader>> map = new MultiMap<String, Pair<URL, ClassLoader>>();
Map<URL, ClassLoader> urls = new HashMap<URL, ClassLoader>();
MultiMap<String, Pair<URL, ClassLoader>> map = MultiMap.createSmartList();
Map<URL, ClassLoader> urls = new THashMap<URL, ClassLoader>();
//for (IdeaPluginDescriptor plugin : plugins) {
// if (!plugin.isEnabled()) continue;
// try {
@@ -65,9 +70,7 @@ public class ArchivedTemplatesFactory extends ProjectTemplatesFactory {
//}
URL configURL = getCustomTemplatesURL();
if (configURL != null) {
urls.put(configURL, ClassLoader.getSystemClassLoader());
}
urls.put(configURL, ClassLoader.getSystemClassLoader());
for (Map.Entry<URL, ClassLoader> url : urls.entrySet()) {
try {
@@ -94,23 +97,23 @@ public class ArchivedTemplatesFactory extends ProjectTemplatesFactory {
}
};
@NotNull
private static URL getCustomTemplatesURL() {
String path = getCustomTemplatesPath();
try {
return new File(path).toURI().toURL();
return new File(getCustomTemplatesPath()).toURI().toURL();
}
catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
@NotNull
static String getCustomTemplatesPath() {
return PathManager.getConfigPath() + "/projectTemplates";
}
public static File getTemplateFile(String name) {
String configURL = getCustomTemplatesPath();
return new File(configURL + "/" + name + ".zip");
return new File(getCustomTemplatesPath() + "/" + name + ".zip");
}
@NotNull
@@ -123,13 +126,11 @@ public class ArchivedTemplatesFactory extends ProjectTemplatesFactory {
@NotNull
@Override
public ProjectTemplate[] createTemplates(String group, WizardContext context) {
Collection<Pair<URL, ClassLoader>> urls = myGroups.getValue().get(group);
public ProjectTemplate[] createTemplates(@NotNull String group, WizardContext context) {
List<ProjectTemplate> templates = new ArrayList<ProjectTemplate>();
for (Pair<URL, ClassLoader> url : urls) {
for (Pair<URL, ClassLoader> url : myGroups.getValue().get(group)) {
try {
List<String> children = UrlUtil.getChildrenRelativePaths(url.first);
for (String child : children) {
for (String child : UrlUtil.getChildrenRelativePaths(url.first)) {
if (child.endsWith(ZIP)) {
URL templateUrl = new URL(url.first.toExternalForm() + "/" + child);
templates.add(new LocalArchivedTemplate(templateUrl, url.second));
@@ -152,6 +153,4 @@ public class ArchivedTemplatesFactory extends ProjectTemplatesFactory {
public Icon getGroupIcon(String group) {
return CUSTOM_GROUP.equals(group) ? AllIcons.Modules.Types.UserDefined : super.getGroupIcon(group);
}
private final static Logger LOG = Logger.getInstance(ArchivedTemplatesFactory.class);
}
@@ -19,14 +19,12 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.ModuleTypeManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.io.StreamUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Namespace;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -42,7 +40,6 @@ import java.util.zip.ZipInputStream;
* Date: 10/1/12
*/
public class LocalArchivedTemplate extends ArchivedProjectTemplate {
public static final String DESCRIPTION_PATH = Project.DIRECTORY_STORE_FOLDER + "/description.html";
static final String TEMPLATE_DESCRIPTOR = Project.DIRECTORY_STORE_FOLDER + "/project-template.xml";
@@ -56,16 +53,11 @@ public class LocalArchivedTemplate extends ArchivedProjectTemplate {
myArchivePath = archivePath;
myModuleType = computeModuleType(this);
String s = readEntry(new Condition<ZipEntry>() {
@Override
public boolean value(ZipEntry entry) {
return entry.getName().endsWith(TEMPLATE_DESCRIPTOR);
}
});
String s = readEntry(TEMPLATE_DESCRIPTOR);
if (s != null) {
try {
Element templateElement = JDOMUtil.loadDocument(s).getRootElement();
populateFromElement(templateElement, Namespace.NO_NAMESPACE);
populateFromElement(templateElement);
String iconPath = templateElement.getChildText("icon-path");
if (iconPath != null) {
myIcon = IconLoader.findIcon(iconPath, classLoader);
@@ -84,12 +76,7 @@ public class LocalArchivedTemplate extends ArchivedProjectTemplate {
@Override
public String getDescription() {
return readEntry(new Condition<ZipEntry>() {
@Override
public boolean value(ZipEntry entry) {
return entry.getName().endsWith(DESCRIPTION_PATH);
}
});
return readEntry(DESCRIPTION_PATH);
}
@Override
@@ -98,34 +85,29 @@ public class LocalArchivedTemplate extends ArchivedProjectTemplate {
}
@Nullable
String readEntry(Condition<ZipEntry> condition) {
ZipInputStream stream = null;
String readEntry(@NotNull final String endsWith) {
try {
stream = getStream();
ZipEntry entry;
while ((entry = stream.getNextEntry()) != null) {
if (condition.value(entry)) {
return StreamUtil.readText(stream, CharsetToolkit.UTF8_CHARSET);
getStream(new StreamConsumer<String>() {
@Override
public String consume(@NotNull ZipInputStream stream) throws IOException {
ZipEntry entry;
while ((entry = stream.getNextEntry()) != null) {
if (entry.getName().endsWith(endsWith)) {
return StreamUtil.readText(stream, CharsetToolkit.UTF8_CHARSET);
}
}
return null;
}
}
});
}
catch (IOException e) {
return null;
}
finally {
StreamUtil.closeStream(stream);
catch (IOException ignored) {
}
return null;
}
@NotNull
private static ModuleType computeModuleType(LocalArchivedTemplate template) {
String iml = template.readEntry(new Condition<ZipEntry>() {
@Override
public boolean value(ZipEntry entry) {
return entry.getName().endsWith(".iml");
}
});
String iml = template.readEntry(".iml");
if (iml == null) return ModuleType.EMPTY;
try {
Document document = JDOMUtil.loadDocument(iml);
@@ -143,8 +125,8 @@ public class LocalArchivedTemplate extends ArchivedProjectTemplate {
}
@Override
public ZipInputStream getStream() throws IOException {
return new ZipInputStream(myArchivePath.openStream());
public <T> void getStream(@NotNull StreamConsumer<T> consumer) throws IOException {
consumeZipStream(consumer, new ZipInputStream(myArchivePath.openStream()));
}
public URL getArchivePath() {
@@ -19,6 +19,7 @@ import com.intellij.CommonBundle;
import com.intellij.ide.util.projectWizard.WizardContext;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.platform.ProjectTemplate;
import com.intellij.platform.ProjectTemplatesFactory;
import com.intellij.ui.CollectionListModel;
@@ -35,7 +36,6 @@ import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.net.URL;
import java.util.Arrays;
/**
@@ -53,18 +53,16 @@ class ManageProjectTemplatesDialog extends DialogWrapper {
setTitle("Manage Project Templates");
final ProjectTemplate[] templates =
new ArchivedTemplatesFactory().createTemplates(ProjectTemplatesFactory.CUSTOM_GROUP, new WizardContext(null));
final CollectionListModel<ProjectTemplate> model = new CollectionListModel<ProjectTemplate>(Arrays.asList(templates)) {
myTemplatesList = new JBList(new CollectionListModel<ProjectTemplate>(Arrays.asList(templates)) {
@Override
public void remove(int index) {
ProjectTemplate template = getElementAt(index);
super.remove(index);
if (template instanceof LocalArchivedTemplate) {
URL path = ((LocalArchivedTemplate)template).getArchivePath();
new File(path.getPath()).delete();
FileUtil.delete(new File(((LocalArchivedTemplate)template).getArchivePath().getPath()));
}
}
};
myTemplatesList = new JBList(model);
});
myTemplatesList.setEmptyText("No user-defined project templates");
myTemplatesList.setPreferredSize(new Dimension(300, 100));
myTemplatesList.setCellRenderer(new ColoredListCellRenderer() {
@@ -24,25 +24,20 @@ import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.ModuleTypeManager;
import com.intellij.openapi.util.ClearableLazyValue;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.io.StreamUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.platform.ProjectTemplate;
import com.intellij.platform.ProjectTemplatesFactory;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.NullableFunction;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.net.HttpConfigurable;
import com.intellij.util.io.HttpRequests;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.util.Collection;
import java.util.List;
import java.util.zip.ZipInputStream;
@@ -52,23 +47,39 @@ import java.util.zip.ZipInputStream;
* Date: 11/14/12
*/
public class RemoteTemplatesFactory extends ProjectTemplatesFactory {
private final static Logger LOG = Logger.getInstance(RemoteTemplatesFactory.class);
private static final String URL = "http://download.jetbrains.com/idea/project_templates/";
private static final String URL = "https://download.jetbrains.com/idea/project_templates/";
public static final String TEMPLATE = "template";
public static final String INPUT_DEFAULT = "default";
public static final Function<Element, String> ELEMENT_STRING_FUNCTION = new Function<Element, String>() {
@Override
public String fun(Element element) {
return element.getText();
}
};
private final ClearableLazyValue<MultiMap<String, ArchivedProjectTemplate>> myTemplates = new ClearableLazyValue<MultiMap<String, ArchivedProjectTemplate>>() {
@NotNull
@Override
protected MultiMap<String, ArchivedProjectTemplate> compute() {
return getTemplates();
try {
return HttpRequests.request(URL + ApplicationInfo.getInstance().getBuild().getProductCode() + "_templates.xml")
.connect(new HttpRequests.RequestProcessor<MultiMap<String, ArchivedProjectTemplate>>() {
@Override
public MultiMap<String, ArchivedProjectTemplate> process(@NotNull HttpRequests.Request request) throws IOException {
try {
return create(JDOMUtil.load(request.getReader()));
}
catch (JDOMException e) {
LOG.error(e);
return MultiMap.emptyInstance();
}
}
});
}
catch (IOException e) { // timeouts, lost connection etc
LOG.info(e);
}
catch (Exception e) {
LOG.error(e);
}
return MultiMap.emptyInstance();
}
};
@@ -81,98 +92,56 @@ public class RemoteTemplatesFactory extends ProjectTemplatesFactory {
@NotNull
@Override
public ProjectTemplate[] createTemplates(String group, WizardContext context) {
public ProjectTemplate[] createTemplates(@NotNull String group, WizardContext context) {
Collection<ArchivedProjectTemplate> templates = myTemplates.getValue().get(group);
return templates.toArray(new ProjectTemplate[templates.size()]);
}
private static MultiMap<String, ArchivedProjectTemplate> getTemplates() {
InputStream stream = null;
HttpURLConnection connection = null;
String code = ApplicationInfo.getInstance().getBuild().getProductCode();
try {
connection = getConnection(code + "_templates.xml");
stream = connection.getInputStream();
String text = StreamUtil.readText(stream, CharsetToolkit.UTF8_CHARSET);
return createFromText(text);
}
catch (IOException ex) { // timeouts, lost connection etc
LOG.info(ex);
return MultiMap.emptyInstance();
}
catch (Exception e) {
LOG.error(e);
return MultiMap.emptyInstance();
}
finally {
StreamUtil.closeStream(stream);
if (connection != null) {
connection.disconnect();
}
}
@NotNull
@TestOnly
public static MultiMap<String, ArchivedProjectTemplate> createFromText(@NotNull String value) throws IOException, JDOMException {
return create(JDOMUtil.loadDocument(value).getRootElement());
}
@SuppressWarnings("unchecked")
public static MultiMap<String, ArchivedProjectTemplate> createFromText(String text) throws IOException, JDOMException {
MultiMap<String, ArchivedProjectTemplate> map = new MultiMap<String, ArchivedProjectTemplate>();
Element rootElement = JDOMUtil.loadDocument(text).getRootElement();
List<ArchivedProjectTemplate> templates = createGroupTemplates(rootElement, Namespace.NO_NAMESPACE);
for (ArchivedProjectTemplate template : templates) {
@NotNull
private static MultiMap<String, ArchivedProjectTemplate> create(@NotNull Element element) throws IOException, JDOMException {
MultiMap<String, ArchivedProjectTemplate> map = MultiMap.createSmartList();
for (ArchivedProjectTemplate template : createGroupTemplates(element)) {
map.putValue(template.getCategory(), template);
}
return map;
}
@SuppressWarnings("unchecked")
private static List<ArchivedProjectTemplate> createGroupTemplates(Element groupElement, final Namespace ns) {
List<Element> elements = groupElement.getChildren(TEMPLATE, ns);
private static List<ArchivedProjectTemplate> createGroupTemplates(Element groupElement) {
List<Element> elements = groupElement.getChildren(TEMPLATE);
return ContainerUtil.mapNotNull(elements, new NullableFunction<Element, ArchivedProjectTemplate>() {
@Override
public ArchivedProjectTemplate fun(final Element element) {
if (!checkRequiredPlugins(element, ns)) return null;
if (!checkRequiredPlugins(element)) return null;
String type = element.getChildText("moduleType");
final ModuleType moduleType = ModuleTypeManager.getInstance().findByID(type);
final String path = element.getChildText("path", ns);
final String description = element.getChildTextTrim("description", ns);
String name = element.getChildTextTrim("name", ns);
final String path = element.getChildText("path");
final String description = element.getChildTextTrim("description");
String name = element.getChildTextTrim("name");
RemoteProjectTemplate template = new RemoteProjectTemplate(name, element, moduleType, path, description);
template.populateFromElement(element, ns);
template.populateFromElement(element);
return template;
}
});
}
public static List<String> getFrameworks(Element element) {
List<Element> frameworks = element.getChildren("framework");
return ContainerUtil.map(frameworks, ELEMENT_STRING_FUNCTION);
}
private static boolean checkRequiredPlugins(Element element, Namespace ns) {
@SuppressWarnings("unchecked") List<Element> plugins = element.getChildren("requiredPlugin", ns);
for (Element plugin : plugins) {
String id = plugin.getTextTrim();
if (!PluginManager.isPluginInstalled(PluginId.getId(id))) {
private static boolean checkRequiredPlugins(Element element) {
for (Element plugin : element.getChildren("requiredPlugin")) {
if (!PluginManager.isPluginInstalled(PluginId.getId(plugin.getTextTrim()))) {
return false;
}
}
return true;
}
private static HttpURLConnection getConnection(String path) throws IOException {
HttpURLConnection connection = HttpConfigurable.getInstance().openHttpConnection(URL + path);
connection.setConnectTimeout(2000);
connection.setReadTimeout(2000);
connection.connect();
return connection;
}
private final static Logger LOG = Logger.getInstance(RemoteTemplatesFactory.class);
private static class RemoteProjectTemplate extends ArchivedProjectTemplate {
private final ModuleType myModuleType;
private final String myPath;
@@ -194,15 +163,14 @@ public class RemoteTemplatesFactory extends ProjectTemplatesFactory {
}
@Override
public ZipInputStream getStream() throws IOException {
final HttpURLConnection connection = getConnection(myPath);
return new ZipInputStream(connection.getInputStream()) {
public <T> void getStream(@NotNull final StreamConsumer<T> consumer) throws IOException {
HttpRequests.request(URL + myPath).connect(new HttpRequests.RequestProcessor<Void>() {
@Override
public void close() throws IOException {
super.close();
connection.disconnect();
public Void process(@NotNull HttpRequests.Request request) throws IOException {
consumeZipStream(consumer, new ZipInputStream(request.getInputStream()));
return null;
}
};
});
}
@Nullable
@@ -40,7 +40,6 @@ import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.NullableComputable;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.io.StreamUtil;
import com.intellij.openapi.util.text.StringUtilRt;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.LocalFileSystem;
@@ -200,12 +199,9 @@ public class TemplateModuleBuilder extends ModuleBuilder {
}
private void unzip(final @Nullable String projectName, String path, final boolean moduleMode) {
File dir = new File(path);
ZipInputStream zipInputStream = null;
final WizardInputField basePackage = getBasePackageField();
try {
zipInputStream = myTemplate.getStream();
NullableFunction<String, String> pathConvertor = new NullableFunction<String, String>() {
final NullableFunction<String, String> pathConvertor = new NullableFunction<String, String>() {
@Nullable
@Override
public String fun(String path) {
@@ -216,13 +212,22 @@ public class TemplateModuleBuilder extends ModuleBuilder {
return path;
}
};
ZipUtil.unzip(ProgressManager.getInstance().getProgressIndicator(), dir, zipInputStream, pathConvertor, new ZipUtil.ContentProcessor() {
final File dir = new File(path);
myTemplate.getStream(new ArchivedProjectTemplate.StreamConsumer<Void>() {
@Override
public byte[] processContent(byte[] content, File file) throws IOException {
FileType fileType = FileTypeManager.getInstance().getFileTypeByExtension(FileUtilRt.getExtension(file.getName()));
return fileType.isBinary() ? content : processTemplates(projectName, new String(content, CharsetToolkit.UTF8_CHARSET), file);
public Void consume(@NotNull ZipInputStream stream) throws IOException {
ZipUtil.unzip(ProgressManager.getInstance().getProgressIndicator(), dir, stream, pathConvertor, new ZipUtil.ContentProcessor() {
@Override
public byte[] processContent(byte[] content, File file) throws IOException {
FileType fileType = FileTypeManager.getInstance().getFileTypeByExtension(FileUtilRt.getExtension(file.getName()));
return fileType.isBinary() ? content : processTemplates(projectName, new String(content, CharsetToolkit.UTF8_CHARSET), file);
}
}, true);
return null;
}
}, true);
});
String iml = ContainerUtil.find(dir.list(), new Condition<String>() {
@Override
public boolean value(String s) {
@@ -245,9 +250,6 @@ public class TemplateModuleBuilder extends ModuleBuilder {
catch (IOException e) {
throw new RuntimeException(e);
}
finally {
StreamUtil.closeStream(zipInputStream);
}
}
private static String getPathFragment(String value) {
@@ -22,6 +22,7 @@ import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PropertyUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -37,7 +38,8 @@ public class PurityInference {
if (!InferenceFromSourceUtil.shouldInferFromSource(method) ||
method.getReturnType() == PsiType.VOID ||
method.getBody() == null ||
method.isConstructor()) {
method.isConstructor() ||
PropertyUtil.isSimpleGetter(method)) {
return false;
}
@@ -24,6 +24,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.ui.Messages;
@@ -150,7 +151,9 @@ class AddModuleDependencyFix extends OrderEntryFix {
targetClasses.add(psiClass);
}
}
new AddImportAction(project, myReference, editor, targetClasses.toArray(new PsiClass[targetClasses.size()])).execute();
if (!DumbService.isDumb(project)) {
new AddImportAction(project, myReference, editor, targetClasses.toArray(new PsiClass[targetClasses.size()])).execute();
}
}
}
};
@@ -18,9 +18,9 @@ package com.intellij.codeInsight.generation;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.JavaVersionService;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.*;
import com.intellij.psi.search.GlobalSearchScope;
@@ -234,6 +234,9 @@ public class GenerateEqualsHelper implements Runnable {
@NonNls private static final MessageFormat ARRAY_COMPARER_MF =
new MessageFormat("if(!java.util.Arrays.equals({1}, {0}.{1})) return false;\n");
@NonNls private static final MessageFormat ARRAY_DEEP_COMPARER_MF =
new MessageFormat("if(!java.util.Arrays.deepEquals({1}, {0}.{1})) return false;\n");
@NonNls private static final MessageFormat FIELD_COMPARER_MF =
new MessageFormat("if({1}!=null ? !{1}.equals({0}.{1}) : {0}.{1}!= null)return false;\n");
@NonNls private static final MessageFormat NON_NULL_FIELD_COMPARER_MF = new MessageFormat("if(!{1}.equals({0}.{1}))return false;\n");
@@ -244,9 +247,14 @@ public class GenerateEqualsHelper implements Runnable {
private void addArrayEquals(StringBuffer buffer, PsiField field) {
final PsiType fieldType = field.getType();
if (isNestedArray(fieldType)) {
buffer.append(" ");
buffer.append(CodeInsightBundle.message("generate.equals.compare.nested.arrays.comment", field.getName()));
buffer.append("\n");
if (JavaVersionService.getInstance().isAtLeast(field, JavaSdkVersion.JDK_1_5)) {
ARRAY_DEEP_COMPARER_MF.format(getComparerFormatParameters(field), buffer, null);
}
else {
buffer.append(" ");
buffer.append(CodeInsightBundle.message("generate.equals.compare.nested.arrays.comment", field.getName()));
buffer.append("\n");
}
return;
}
if (isArrayOfObjects(fieldType)) {
@@ -474,7 +482,14 @@ public class GenerateEqualsHelper implements Runnable {
}
private static void adjustHashCodeToArrays(@NonNls StringBuilder buffer, final PsiField field, final String name) {
if (field.getType() instanceof PsiArrayType && hasArraysHashCode(field)) {
final PsiType fieldType = field.getType();
if (fieldType instanceof PsiArrayType &&
JavaVersionService.getInstance().isAtLeast(field, JavaSdkVersion.JDK_1_5)) {
if (isNestedArray(fieldType)) {
buffer.append(" ");
buffer.append("// Probably incorrect - hashCode for high dimension arrays with Arrays.hashCode");
buffer.append("\n");
}
buffer.append("java.util.Arrays.hashCode(");
buffer.append(name);
buffer.append(")");
@@ -485,16 +500,6 @@ public class GenerateEqualsHelper implements Runnable {
}
}
private static boolean hasArraysHashCode(final PsiField field) {
// the method was added in JDK 1.5 - check for actual method presence rather than language level
Module module = ModuleUtilCore.findModuleForPsiElement(field);
if (module == null) return false;
PsiClass arraysClass = JavaPsiFacade.getInstance(field.getProject()).findClass("java.util.Arrays", module.getModuleWithLibrariesScope());
if (arraysClass == null) return false;
final PsiMethod[] methods = arraysClass.findMethodsByName("hashCode", false);
return methods.length > 0;
}
@SuppressWarnings("HardCodedStringLiteral")
private void addSuperHashCode(StringBuilder buffer) {
if (mySuperHasHashCode) {
@@ -22,8 +22,11 @@ import com.intellij.codeInsight.generation.GenerateEqualsHelper;
import com.intellij.ide.wizard.StepAdapter;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.JavaVersionService;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.classMembers.AbstractMemberInfoModel;
import com.intellij.refactoring.classMembers.MemberInfoBase;
import com.intellij.refactoring.classMembers.MemberInfoTooltipManager;
@@ -263,12 +266,15 @@ public class GenerateEqualsWizard extends AbstractGenerateEqualsWizard<PsiClass,
public String getTooltip(MemberInfo memberInfo) {
if (checkForProblems(memberInfo) == OK) return null;
if (!(memberInfo.getMember() instanceof PsiField)) return CodeInsightBundle.message("generate.equals.hashcode.internal.error");
final PsiType type = ((PsiField)memberInfo.getMember()).getType();
if (GenerateEqualsHelper.isNestedArray(type)) {
return CodeInsightBundle .message("generate.equals.warning.equals.for.nested.arrays.not.supported");
}
if (GenerateEqualsHelper.isArrayOfObjects(type)) {
return CodeInsightBundle.message("generate.equals.warning.generated.equals.could.be.incorrect");
final PsiField field = (PsiField)memberInfo.getMember();
if (!JavaVersionService.getInstance().isAtLeast(field, JavaSdkVersion.JDK_1_5)) {
final PsiType type = field.getType();
if (GenerateEqualsHelper.isNestedArray(type)) {
return CodeInsightBundle .message("generate.equals.warning.equals.for.nested.arrays.not.supported");
}
if (GenerateEqualsHelper.isArrayOfObjects(type)) {
return CodeInsightBundle.message("generate.equals.warning.generated.equals.could.be.incorrect");
}
}
return null;
}
@@ -277,16 +283,20 @@ public class GenerateEqualsWizard extends AbstractGenerateEqualsWizard<PsiClass,
@Override
public boolean isMemberEnabled(MemberInfo member) {
if (!(member.getMember() instanceof PsiField)) return false;
final PsiType type = ((PsiField)member.getMember()).getType();
return !GenerateEqualsHelper.isNestedArray(type);
final PsiField field = (PsiField)member.getMember();
final PsiType type = field.getType();
return JavaVersionService.getInstance().isAtLeast(field, JavaSdkVersion.JDK_1_5) || !GenerateEqualsHelper.isNestedArray(type);
}
@Override
public int checkForProblems(@NotNull MemberInfo member) {
if (!(member.getMember() instanceof PsiField)) return ERROR;
final PsiType type = ((PsiField)member.getMember()).getType();
if (GenerateEqualsHelper.isNestedArray(type)) return ERROR;
if (GenerateEqualsHelper.isArrayOfObjects(type)) return WARNING;
final PsiField field = (PsiField)member.getMember();
final PsiType type = field.getType();
if (!JavaVersionService.getInstance().isAtLeast(field, JavaSdkVersion.JDK_1_5)) {
if (GenerateEqualsHelper.isNestedArray(type)) return ERROR;
if (GenerateEqualsHelper.isArrayOfObjects(type)) return WARNING;
}
return OK;
}
@@ -302,8 +312,9 @@ public class GenerateEqualsWizard extends AbstractGenerateEqualsWizard<PsiClass,
public String getTooltip(MemberInfo memberInfo) {
if (isMemberEnabled(memberInfo)) return null;
if (!(memberInfo.getMember() instanceof PsiField)) return CodeInsightBundle.message("generate.equals.hashcode.internal.error");
final PsiType type = ((PsiField)memberInfo.getMember()).getType();
if (!(type instanceof PsiArrayType)) return null;
final PsiField field = (PsiField)memberInfo.getMember();
final PsiType type = field.getType();
if (!(type instanceof PsiArrayType) || JavaVersionService.getInstance().isAtLeast(field, JavaSdkVersion.JDK_1_5)) return null;
return CodeInsightBundle.message("generate.equals.hashcode.warning.hashcode.for.arrays.is.not.supported");
}
});
@@ -292,17 +292,18 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
}
private static PsiCall getCall(PsiExpressionList list) {
if (list.getParent() instanceof PsiMethodCallExpression) {
return (PsiCall)list.getParent();
PsiElement listParent = list.getParent();
if (listParent instanceof PsiMethodCallExpression) {
return (PsiCall)listParent;
}
if (list.getParent() instanceof PsiNewExpression) {
return (PsiCall)list.getParent();
if (listParent instanceof PsiNewExpression) {
return (PsiCall)listParent;
}
if (list.getParent() instanceof PsiAnonymousClass) {
return (PsiCall)list.getParent().getParent();
if (listParent instanceof PsiAnonymousClass) {
return (PsiCall)listParent.getParent();
}
if (list.getParent() instanceof PsiEnumConstant) {
return (PsiCall)list.getParent();
if (listParent instanceof PsiEnumConstant) {
return (PsiCall)listParent;
}
return null;
}
@@ -62,7 +62,7 @@ public final class PackageElement implements Queryable, RootsProvider {
@Override
public Collection<VirtualFile> getRoots() {
Set<VirtualFile> roots= new HashSet<VirtualFile>();
final PsiDirectory[] dirs = PackageUtil.getDirectories(getPackage(), myElement.getProject(), myModule, isLibraryElement());
final PsiDirectory[] dirs = PackageUtil.getDirectories(getPackage(), myModule, isLibraryElement());
for (PsiDirectory each : dirs) {
roots.add(each.getVirtualFile());
}
@@ -28,7 +28,9 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiPackage;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.PlatformIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -87,15 +89,18 @@ public class PackageElementNode extends ProjectViewNode<PackageElement> {
if (!getSettings().isFlattenPackages()) {
final PsiPackage[] subpackages = PackageUtil.getSubpackages(aPackage, module, myProject, isLibraryElement());
final PsiPackage[] subpackages = PackageUtil.getSubpackages(aPackage, module, isLibraryElement());
for (PsiPackage subpackage : subpackages) {
PackageUtil.addPackageAsChild(children, subpackage, module, getSettings(), isLibraryElement());
}
}
// process only files in package's directories
final PsiDirectory[] dirs = PackageUtil.getDirectories(aPackage, myProject, module, isLibraryElement());
for (final PsiDirectory dir : dirs) {
children.addAll(ProjectViewDirectoryHelper.getInstance(myProject).getDirectoryChildren(dir, getSettings(), false));
final GlobalSearchScope scopeToShow = PackageUtil.getScopeToShow(aPackage.getProject(), module, isLibraryElement());
PsiFile[] packageChildren = aPackage.getFiles(scopeToShow);
for (PsiFile file : packageChildren) {
if (file.getVirtualFile() != null) {
children.add(new PsiFileNode(getProject(), file, getSettings()));
}
}
return children;
}
@@ -163,7 +168,7 @@ public class PackageElementNode extends ProjectViewNode<PackageElement> {
if (value == null) {
return VirtualFile.EMPTY_ARRAY;
}
final PsiDirectory[] directories = PackageUtil.getDirectories(value.getPackage(), getProject(), value.getModule(), isLibraryElement());
final PsiDirectory[] directories = PackageUtil.getDirectories(value.getPackage(), value.getModule(), isLibraryElement());
final VirtualFile[] result = new VirtualFile[directories.length];
for (int i = 0; i < directories.length; i++) {
PsiDirectory directory = directories[i];
@@ -23,12 +23,8 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.JavaDirectoryService;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiPackage;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,25 +34,18 @@ public class PackageUtil {
@NotNull
public static PsiPackage[] getSubpackages(@NotNull PsiPackage aPackage,
@Nullable Module module,
@NotNull Project project,
final boolean searchInLibraries) {
final PsiDirectory[] dirs = getDirectories(aPackage, project, module, searchInLibraries);
final Set<PsiPackage> subpackages = new HashSet<PsiPackage>();
for (PsiDirectory dir : dirs) {
final PsiDirectory[] subdirectories = dir.getSubdirectories();
for (PsiDirectory subdirectory : subdirectories) {
final PsiPackage psiPackage = JavaDirectoryService.getInstance().getPackage(subdirectory);
if (psiPackage != null) {
final String name = psiPackage.getName();
// skip "default" subpackages as they should be attributed to other modules
// this is the case when contents of one module is nested into contents of another
if (name != null && !name.isEmpty()) {
subpackages.add(psiPackage);
}
}
final GlobalSearchScope scopeToShow = getScopeToShow(aPackage.getProject(), module, searchInLibraries);
List<PsiPackage> result = new ArrayList<PsiPackage>();
for (PsiPackage psiPackage : aPackage.getSubPackages(scopeToShow)) {
// skip "default" subpackages as they should be attributed to other modules
// this is the case when contents of one module is nested into contents of another
final String name = psiPackage.getName();
if (name != null && !name.isEmpty()) {
result.add(psiPackage);
}
}
return subpackages.toArray(new PsiPackage[subpackages.size()]);
return result.toArray(new PsiPackage[result.size()]);
}
public static void addPackageAsChild(@NotNull Collection<AbstractTreeNode> children,
@@ -70,7 +59,7 @@ public class PackageUtil {
children.add(new PackageElementNode(project, new PackageElement(module, aPackage, inLibrary), settings));
}
if (settings.isFlattenPackages() || shouldSkipPackage) {
final PsiPackage[] subpackages = getSubpackages(aPackage, module, project, inLibrary);
final PsiPackage[] subpackages = getSubpackages(aPackage, module, inLibrary);
for (PsiPackage subpackage : subpackages) {
addPackageAsChild(children, subpackage, module, settings, inLibrary);
}
@@ -82,26 +71,28 @@ public class PackageUtil {
boolean strictlyEmpty,
final boolean inLibrary) {
final Project project = aPackage.getProject();
final PsiDirectory[] dirs = getDirectories(aPackage, project, module, inLibrary);
for (final PsiDirectory dir : dirs) {
if (!TreeViewUtil.isEmptyMiddlePackage(dir, strictlyEmpty)) {
return false;
}
final GlobalSearchScope scopeToShow = getScopeToShow(project, module, inLibrary);
PsiElement[] children = aPackage.getFiles(scopeToShow);
if (children.length > 0) {
return false;
}
return true;
PsiPackage[] subPackages = aPackage.getSubPackages(scopeToShow);
if (strictlyEmpty) {
return subPackages.length == 1;
}
return subPackages.length > 0;
}
@NotNull
public static PsiDirectory[] getDirectories(@NotNull PsiPackage aPackage,
@NotNull Project project,
@Nullable Module module,
boolean inLibrary) {
final GlobalSearchScope scopeToShow = getScopeToShow(project, module, inLibrary);
final GlobalSearchScope scopeToShow = getScopeToShow(aPackage.getProject(), module, inLibrary);
return aPackage.getDirectories(scopeToShow);
}
@NotNull
private static GlobalSearchScope getScopeToShow(@NotNull Project project, @Nullable Module module, boolean forLibraries) {
public static GlobalSearchScope getScopeToShow(@NotNull Project project, @Nullable Module module, boolean forLibraries) {
if (module == null) {
if (forLibraries) {
return new ProjectLibrariesSearchScope(project);
@@ -242,7 +233,7 @@ public class PackageUtil {
@Override
public int compare(@NotNull VirtualFile file1, @NotNull VirtualFile file2) {
throw new IncorrectOperationException("not implemented");
return 0;
}
@Override
@@ -39,7 +39,7 @@ public class PackageViewModuleGroupNode extends ModuleGroupNode {
@Override
protected AbstractTreeNode createModuleNode(Module module)
throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
return createTreeNode(PackageViewModuleNode.class, module.getProject(), module, getSettings());
return new PackageViewModuleNode(module.getProject(), module, getSettings());
}
@Override
@@ -101,13 +101,13 @@ public class PackageViewProjectNode extends AbstractProjectNode {
protected AbstractTreeNode createModuleGroup(final Module module) throws
InvocationTargetException,
NoSuchMethodException, InstantiationException, IllegalAccessException {
return createTreeNode(PackageViewModuleNode.class, getProject(), module, getSettings());
return new PackageViewModuleNode(getProject(), module, getSettings());
}
@Override
protected AbstractTreeNode createModuleGroupNode(final ModuleGroup moduleGroup)
throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
return createTreeNode(PackageViewModuleGroupNode.class, getProject(), moduleGroup, getSettings());
return new PackageViewModuleGroupNode(getProject(), moduleGroup, getSettings());
}
@Override
@@ -48,6 +48,7 @@ import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTag;
import com.intellij.psi.util.PsiFormatUtil;
import com.intellij.psi.util.PsiFormatUtilBase;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
@@ -186,8 +187,51 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
buffer.append(JavaDocUtil.getShortestClassName(aClass, aClass));
if (aClass.hasTypeParameters()) {
PsiTypeParameter[] parms = aClass.getTypeParameters();
generateTypeParameters(aClass, buffer);
if (!aClass.isEnum() && !aClass.isAnnotationType()) {
PsiReferenceList extendsList = aClass.getExtendsList();
writeExtends(aClass, buffer, extendsList == null ? PsiClassType.EMPTY_ARRAY : extendsList.getReferencedTypes());
}
writeImplements(aClass, buffer, aClass.getImplementsListTypes());
return buffer.toString();
}
public static void writeImplements(PsiClass aClass, StringBuilder buffer, PsiClassType[] refs) {
if (refs.length > 0) {
newLine(buffer);
buffer.append("implements ");
writeTypeRefs(aClass, buffer, refs);
}
}
public static void writeExtends(PsiClass aClass, StringBuilder buffer, PsiClassType[] refs) {
if (refs.length > 0 || !aClass.isInterface() && !CommonClassNames.JAVA_LANG_OBJECT.equals(aClass.getQualifiedName())) {
buffer.append(" extends ");
if (refs.length == 0) {
buffer.append("Object");
}
else {
writeTypeRefs(aClass, buffer, refs);
}
}
}
private static void writeTypeRefs(PsiClass aClass, StringBuilder buffer, PsiClassType[] refs) {
for (int i = 0; i < refs.length; i++) {
JavaDocInfoGenerator.generateType(buffer, refs[i], aClass, false);
if (i < refs.length - 1) {
buffer.append(", ");
}
}
}
public static void generateTypeParameters(PsiTypeParameterListOwner typeParameterOwner, StringBuilder buffer) {
if (typeParameterOwner.hasTypeParameters()) {
PsiTypeParameter[] parms = typeParameterOwner.getTypeParameters();
buffer.append("&lt;");
@@ -195,14 +239,13 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
PsiTypeParameter p = parms[i];
buffer.append(p.getName());
PsiClassType[] refs = p.getExtendsList().getReferencedTypes();
if (refs.length > 0) {
buffer.append(" extends ");
for (int j = 0; j < refs.length; j++) {
JavaDocInfoGenerator.generateType(buffer, refs[j], aClass, false);
JavaDocInfoGenerator.generateType(buffer, refs[j], typeParameterOwner, false);
if (j < refs.length - 1) {
buffer.append(" & ");
@@ -217,42 +260,6 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
buffer.append("&gt;");
}
PsiClassType[] refs;
if (!aClass.isEnum() && !aClass.isAnnotationType()) {
PsiReferenceList extendsList = aClass.getExtendsList();
refs = extendsList == null ? PsiClassType.EMPTY_ARRAY : extendsList.getReferencedTypes();
if (refs.length > 0 || !aClass.isInterface() && !CommonClassNames.JAVA_LANG_OBJECT.equals(aClass.getQualifiedName())) {
buffer.append(" extends ");
if (refs.length == 0) {
buffer.append("Object");
}
else {
for (int i = 0; i < refs.length; i++) {
JavaDocInfoGenerator.generateType(buffer, refs[i], aClass, false);
if (i < refs.length - 1) {
buffer.append(", ");
}
}
}
}
}
refs = aClass.getImplementsListTypes();
if (refs.length > 0) {
newLine(buffer);
buffer.append("implements ");
for (int i = 0; i < refs.length; i++) {
JavaDocInfoGenerator.generateType(buffer, refs[i], aClass, false);
if (i < refs.length - 1) {
buffer.append(", ");
}
}
}
return buffer.toString();
}
@SuppressWarnings({"HardCodedStringLiteral"})
@@ -272,35 +279,7 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
generateModifiers(buffer, method);
PsiTypeParameter[] params = method.getTypeParameters();
if (params.length > 0) {
buffer.append("&lt;");
for (int i = 0; i < params.length; i++) {
PsiTypeParameter param = params[i];
buffer.append(param.getName());
PsiClassType[] extendees = param.getExtendsList().getReferencedTypes();
if (extendees.length > 0) {
buffer.append(" extends ");
for (int j = 0; j < extendees.length; j++) {
JavaDocInfoGenerator.generateType(buffer, extendees[j], method, false);
if (j < extendees.length - 1) {
buffer.append(" & ");
}
}
}
if (i < params.length - 1) {
buffer.append(", ");
}
}
buffer.append("&gt; ");
}
generateTypeParameters(method, buffer);
if (method.getReturnType() != null) {
JavaDocInfoGenerator.generateType(buffer, substitutor.substitute(method.getReturnType()), method, false);
@@ -415,43 +394,7 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
.forLanguage(commentOwner.getLanguage());
if (commentOwner instanceof PsiMethod) {
PsiMethod psiMethod = (PsiMethod)commentOwner;
final PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
final Map<String, String> param2Description = new HashMap<String, String>();
final PsiMethod[] superMethods = psiMethod.findSuperMethods();
for (PsiMethod superMethod : superMethods) {
final PsiDocComment comment = superMethod.getDocComment();
if (comment != null) {
final PsiDocTag[] params = comment.findTagsByName("param");
for (PsiDocTag param : params) {
final PsiElement[] dataElements = param.getDataElements();
if (dataElements != null) {
String paramName = null;
for (PsiElement dataElement : dataElements) {
if (dataElement instanceof PsiDocParamRef) {
paramName = dataElement.getReference().getCanonicalText();
break;
}
}
if (paramName != null) {
param2Description.put(paramName, param.getText());
}
}
}
}
}
for (PsiParameter parameter : parameters) {
String description = param2Description.get(parameter.getName());
if (description != null) {
builder.append(CodeDocumentationUtil.createDocCommentLine("", project, commenter));
if (description.indexOf('\n') > -1) description = description.substring(0, description.lastIndexOf('\n'));
builder.append(description);
}
else {
builder.append(CodeDocumentationUtil.createDocCommentLine(PARAM_TAG, project, commenter));
builder.append(parameter.getName());
}
builder.append(LINE_SEPARATOR);
}
generateParametersTakingDocFromSuperMethods(project, builder, commenter, psiMethod);
final PsiTypeParameterList typeParameterList = psiMethod.getTypeParameterList();
if (typeParameterList != null) {
@@ -478,7 +421,51 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
return builder.length() > 0 ? builder.toString() : null;
}
private static void createTypeParamsListComment(final StringBuilder buffer,
public static void generateParametersTakingDocFromSuperMethods(Project project,
StringBuilder builder,
CodeDocumentationAwareCommenter commenter, PsiMethod psiMethod) {
final PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
final Map<String, String> param2Description = new HashMap<String, String>();
final PsiMethod[] superMethods = psiMethod.findSuperMethods();
for (PsiMethod superMethod : superMethods) {
final PsiDocComment comment = superMethod.getDocComment();
if (comment != null) {
final PsiDocTag[] params = comment.findTagsByName("param");
for (PsiDocTag param : params) {
final PsiElement[] dataElements = param.getDataElements();
if (dataElements != null) {
String paramName = null;
for (PsiElement dataElement : dataElements) {
if (dataElement instanceof PsiDocParamRef) {
paramName = dataElement.getReference().getCanonicalText();
break;
}
}
if (paramName != null) {
param2Description.put(paramName, param.getText());
}
}
}
}
}
for (PsiParameter parameter : parameters) {
String description = param2Description.get(parameter.getName());
if (description != null) {
builder.append(CodeDocumentationUtil.createDocCommentLine("", project, commenter));
if (description.indexOf('\n') > -1) description = description.substring(0, description.lastIndexOf('\n'));
builder.append(description);
}
else {
builder.append(CodeDocumentationUtil.createDocCommentLine(PARAM_TAG, project, commenter));
builder.append(parameter.getName());
}
builder.append(LINE_SEPARATOR);
}
}
public static void createTypeParamsListComment(final StringBuilder buffer,
final Project project,
final CodeDocumentationAwareCommenter commenter,
final PsiTypeParameterList typeParameterList) {
@@ -491,11 +478,56 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
}
@Override
public String generateDoc(final PsiElement element, final PsiElement originalElement) {
public String generateDoc(PsiElement element, PsiElement originalElement) {
if (element instanceof PsiExpressionList) {
element = element.getParent(); // for new Class(<caret>) or methodCall(<caret>) proceed from method call or new expression
originalElement = null;
}
if (element instanceof PsiMethodCallExpression) {
return getMethodCandidateInfo((PsiMethodCallExpression)element);
}
// Try hard for documentation of incomplete new Class instantiation
PsiElement elt = originalElement != null ? PsiTreeUtil.prevLeaf(originalElement): element;
if (elt instanceof PsiErrorElement) elt = elt.getPrevSibling();
else if (elt != null && !(elt instanceof PsiNewExpression)) {
elt = elt.getParent();
}
if (elt instanceof PsiNewExpression) {
PsiClass targetClass = null;
if (element instanceof PsiJavaCodeReferenceElement) { // new Class<caret>
PsiElement resolve = ((PsiJavaCodeReferenceElement)element).resolve();
if (resolve instanceof PsiClass) targetClass = (PsiClass)resolve;
} else if (element instanceof PsiClass) { //Class in completion
targetClass = (PsiClass)element;
} else if (element instanceof PsiNewExpression) { // new Class(<caret>)
PsiJavaCodeReferenceElement reference = ((PsiNewExpression)element).getClassReference();
if (reference != null) {
PsiElement resolve = reference.resolve();
if (resolve instanceof PsiClass) targetClass = (PsiClass)resolve;
}
}
if (targetClass != null) {
PsiMethod[] constructors = targetClass.getConstructors();
if (constructors.length > 0) {
if (constructors.length == 1) return generateDoc(constructors[0], originalElement);
@NonNls final StringBuilder sb = new StringBuilder();
for(PsiMethod constructor:constructors) {
final String str = PsiFormatUtil.formatMethod(constructor, PsiSubstitutor.EMPTY,
PsiFormatUtilBase.SHOW_NAME |
PsiFormatUtilBase.SHOW_TYPE |
PsiFormatUtilBase.SHOW_PARAMETERS,
PsiFormatUtilBase.SHOW_TYPE | PsiFormatUtilBase.SHOW_NAME);
createElementLink(sb, constructor, StringUtil.escapeXml(str));
}
return CodeInsightBundle.message("javadoc.constructor.candidates", targetClass.getName(), sb);
}
}
}
//external documentation finder
return generateExternalJavadoc(element);
@@ -528,11 +560,15 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
return null;
}
private static String getMethodCandidateInfo(PsiMethodCallExpression expr) {
private String getMethodCandidateInfo(PsiMethodCallExpression expr) {
final PsiResolveHelper rh = JavaPsiFacade.getInstance(expr.getProject()).getResolveHelper();
final CandidateInfo[] candidates = rh.getReferencedMethodCandidates(expr, true);
final String text = expr.getText();
if (candidates.length > 0) {
if (candidates.length == 1) {
PsiElement element = candidates[0].getElement();
if (element instanceof PsiMethod) return generateDoc(element, null);
}
@NonNls final StringBuilder sb = new StringBuilder();
for (final CandidateInfo candidate : candidates) {
@@ -26,6 +26,7 @@ import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.module.EffectiveLanguageLevelUtil;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.impl.DirectoryIndex;
@@ -69,6 +70,8 @@ public class JavaPsiImplementationHelperImpl extends JavaPsiImplementationHelper
public PsiClass getOriginalClass(PsiClass psiClass) {
PsiCompiledElement cls = psiClass.getUserData(ClsElementImpl.COMPILED_ELEMENT);
if (cls != null && cls.isValid()) return (PsiClass)cls;
if (DumbService.isDumb(myProject)) return psiClass;
VirtualFile vFile = psiClass.getContainingFile().getVirtualFile();
final ProjectFileIndex idx = ProjectRootManager.getInstance(myProject).getFileIndex();
@@ -44,10 +44,10 @@ public class ParameterData {
myType = type;
}
public static void createFromConstructor(final PsiMethod constructor, final Map<String, ParameterData> result) {
public static void createFromConstructor(final PsiMethod constructor, String setterPrefix, final Map<String, ParameterData> result) {
for (PsiParameter parameter : constructor.getParameterList().getParameters()) {
initParameterData(parameter, result);
initParameterData(parameter, setterPrefix, result);
}
final PsiMethod chainedConstructor = RefactoringUtil.getChainedConstructor(constructor);
@@ -61,7 +61,7 @@ public class ParameterData {
for (final PsiParameter parameter : chainedConstructor.getParameterList().getParameters()) {
if (!parameter.isVarArgs()) {
final PsiExpression arg = args[i];
final ParameterData parameterData = initParameterData(parameter, result);
final ParameterData parameterData = initParameterData(parameter, setterPrefix, result);
if (!(arg instanceof PsiReferenceExpression && ((PsiReferenceExpression)arg).resolve() instanceof PsiParameter)) {
parameterData.setDefaultValue(arg.getText());
}
@@ -71,7 +71,7 @@ public class ParameterData {
}
}
private static ParameterData initParameterData(PsiParameter parameter, Map<String, ParameterData> result) {
private static ParameterData initParameterData(PsiParameter parameter, String setterPrefix, Map<String, ParameterData> result) {
JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(parameter.getProject());
final String paramName = parameter.getName();
final String pureParamName = styleManager.variableNameToPropertyName(paramName, VariableKind.PARAMETER);
@@ -91,7 +91,7 @@ public class ParameterData {
parameterData = new ParameterData(paramName, parameter.getType());
parameterData.setFieldName(styleManager.suggestVariableName(VariableKind.FIELD, uniqueParamName, null, parameter.getType()).names[0]);
parameterData.setSetterName(PropertyUtil.suggestSetterName(uniqueParamName));
parameterData.setSetterName(PropertyUtil.suggestSetterName(uniqueParamName, setterPrefix));
result.put(uniqueParamName, parameterData);
}
@@ -20,16 +20,24 @@
*/
package com.intellij.refactoring.replaceConstructorWithBuilder;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.ide.util.TreeClassChooser;
import com.intellij.ide.util.TreeClassChooserFactory;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.InputValidatorEx;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PropertyUtil;
import com.intellij.refactoring.PackageWrapper;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.move.moveClassesOrPackages.DestinationFolderComboBox;
@@ -37,9 +45,10 @@ import com.intellij.refactoring.ui.PackageNameReferenceEditorCombo;
import com.intellij.refactoring.ui.RefactoringDialog;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.ui.*;
import com.intellij.util.ui.Table;
import com.intellij.ui.table.JBTable;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
@@ -68,16 +77,20 @@ public class ReplaceConstructorWithBuilderDialog extends RefactoringDialog {
private static final Logger LOG = Logger.getInstance("#" + ReplaceConstructorWithBuilderDialog.class.getName());
private final LinkedHashMap<String, ParameterData> myParametersMap;
private MyTableModel myTableModel;
private Table myTable;
private JBTable myTable;
private String mySetterPrefix;
private static final String RECENT_KEYS = "ReplaceConstructorWithBuilder.RECENT_KEYS";
private static final String SETTER_PREFIX_KEY = "ConstructorWithBuilder.SetterPrefix";
protected ReplaceConstructorWithBuilderDialog(@NotNull Project project, PsiMethod[] constructors) {
super(project, false);
myConstructors = constructors;
myParametersMap = new LinkedHashMap<String, ParameterData>();
mySetterPrefix = PropertiesComponent.getInstance(project).getValue(SETTER_PREFIX_KEY, "set");
for (PsiMethod constructor : constructors) {
ParameterData.createFromConstructor(constructor, myParametersMap);
ParameterData.createFromConstructor(constructor, mySetterPrefix, myParametersMap);
}
init();
setTitle(ReplaceConstructorWithBuilderProcessor.REFACTORING_NAME);
@@ -109,6 +122,44 @@ public class ReplaceConstructorWithBuilderDialog extends RefactoringDialog {
}
@Nullable
@Override
protected JComponent createNorthPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.add(new JLabel("Parameters to Pass to the Builder"), BorderLayout.CENTER);
final DefaultActionGroup actionGroup = new DefaultActionGroup(null, false);
actionGroup.addAction(new AnAction("Rename Setters Prefix") {
@Override
public void actionPerformed(AnActionEvent e) {
applyNewSetterPrefix();
}
}).setAsSecondary(true);
panel.add(ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, actionGroup, true).getComponent(), BorderLayout.EAST);
final Box box = Box.createHorizontalBox();
box.add(panel);
box.add(Box.createHorizontalGlue());
return box;
}
private void applyNewSetterPrefix() {
final String setterPrefix = Messages.showInputDialog(myTable, "New setter prefix:", "Rename Setters Prefix", null,
mySetterPrefix, new MySetterPrefixInputValidator());
if (setterPrefix != null) {
mySetterPrefix = setterPrefix;
PropertiesComponent.getInstance(myProject).setValue(SETTER_PREFIX_KEY, setterPrefix);
final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(myProject);
for (String paramName : myParametersMap.keySet()) {
final ParameterData data = myParametersMap.get(paramName);
paramName = data.getParamName();
final String propertyName = javaCodeStyleManager.variableNameToPropertyName(paramName, VariableKind.PARAMETER);
data.setSetterName(PropertyUtil.suggestSetterName(propertyName, setterPrefix));
}
myTable.revalidate();
myTable.repaint();
}
}
protected JComponent createCenterPanel() {
final Splitter splitter = new Splitter(true);
@@ -171,7 +222,7 @@ public class ReplaceConstructorWithBuilderDialog extends RefactoringDialog {
private JScrollPane createTablePanel() {
myTableModel = new MyTableModel();
myTable = new Table(myTableModel);
myTable = new JBTable(myTableModel);
myTable.setSurrendersFocusOnKeystroke(true);
myTable.getTableHeader().setReorderingAllowed(false);
@@ -198,13 +249,7 @@ public class ReplaceConstructorWithBuilderDialog extends RefactoringDialog {
myTable.setPreferredScrollableViewportSize(new Dimension(550, myTable.getRowHeight() * 12));
myTable.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTable);
//final Border titledBorder = IdeBorderFactory.createBoldTitledBorder("Parameters to Pass to the Builder");
//final Border emptyBorder = BorderFactory.createEmptyBorder(0, 5, 5, 5);
//final Border border = BorderFactory.createCompoundBorder(titledBorder, emptyBorder);
//scrollPane.setBorder(border);
return scrollPane;
return ScrollPaneFactory.createScrollPane(myTable);
}
private static final int PARAM = 0;
@@ -338,4 +383,26 @@ public class ReplaceConstructorWithBuilderDialog extends RefactoringDialog {
return null;
}
}
private class MySetterPrefixInputValidator implements InputValidatorEx {
@Override
public boolean checkInput(String inputString) {
return getErrorText(inputString) == null;
}
@Override
public boolean canClose(String inputString) {
return checkInput(inputString);
}
@Nullable
@Override
public String getErrorText(String inputString) {
if (StringUtil.isEmpty(inputString)) {
return null;
}
return !PsiNameHelper.getInstance(myProject).isIdentifier(inputString)
? "Identifier \'" + inputString + "\' is invalid" : null;
}
}
}
@@ -37,13 +37,16 @@ public class VariableInIncompleteCodeSearcher extends QueryExecutorBase<PsiRefer
@Override
public void processQuery(@NotNull final ReferencesSearch.SearchParameters p, @NotNull final Processor<PsiReference> consumer) {
final PsiElement refElement = p.getElementToSearch();
if (!refElement.isValid() || !(refElement instanceof PsiLocalVariable || refElement instanceof PsiParameter)) return;
if (!refElement.isValid() || !(refElement instanceof PsiVariable)) return;
final String name = ((PsiVariable)refElement).getName();
if (name == null) return;
final SearchScope scope = p.getEffectiveSearchScope();
if (!(scope instanceof LocalSearchScope)) return;
SearchScope scope = p.getEffectiveSearchScope();
if (!(scope instanceof LocalSearchScope)) {
//process incomplete references to the 'field' in the same file only
scope = new LocalSearchScope(refElement.getContainingFile());
}
PsiElement[] elements = ((LocalSearchScope)scope).getScope();
if (elements.length == 0) return;
@@ -101,33 +101,31 @@ public abstract class PsiElementFinder {
}
/**
* Returns a list of children (classes, subpackages and possibly other elements) belonging to the specified package.
* Returns a list of files belonging to the specified package which are not located in any of the package directories.
*
* @param psiPackage the package to return the list of children for.
* @param scope the scope in which children are searched.
* @return the list of children.
* @param psiPackage the package to return the list of files for.
* @param scope the scope in which files are searched.
* @return the list of files.
* @since 14.1
*/
@NotNull
public PsiNamedElement[] getChildren(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
Set<PsiNamedElement> children = new HashSet<PsiNamedElement>();
Collections.addAll(children, getSubPackages(psiPackage, scope));
Collections.addAll(children, getClasses(psiPackage, scope));
return children.toArray(new PsiNamedElement[children.size()]);
public PsiFile[] getPackageFiles(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
return PsiFile.EMPTY_ARRAY;
}
/**
* Returns the filter to use for filtering the list of children for a given package produced by other PsiElementFinder
* implementations. (For example, the list of children for a Kotlin package includes files directly, rather than classes,
* so the classes located by the standard Java package children finder need to be excluded.)
* Returns the filter to use for filtering the list of files in the directories belonging to a package to exclude files
* that actually belong to a different package. (For example, in Kotlin the package of a file is determined by its
* package statement and not by its location in the directory structure, so the files which have a differring package
* statement need to be excluded.)
*
* @param psiPackage the package to return the list of children for.
* @param scope the scope in which children are searched.
* @param psiPackage the package for which the list of files is requested.
* @param scope the scope in which children are requested.
* @return the filter to use, or null if no additional filtering is necessary.
* @since 14.1
*/
@Nullable
public Predicate<PsiNamedElement> getPackageChildrenFilter(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
public Predicate<PsiFile> getPackageFilesFilter(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
return null;
}
@@ -84,12 +84,13 @@ public interface PsiPackage extends PsiCheckedRenameElement, NavigationItem, Psi
PsiClass[] getClasses(@NotNull GlobalSearchScope scope);
/**
* Returns the list of all elements (classes, subpackages and potentially other elements) belonging to this package
* (non-recursively), restricted by the specified scope.
* Returns the list of all files in the package, restricted by the specified scope. (This is
* normally the list of all files in all directories corresponding to the package, but it can
* be modified by custom language plugins which have a different notion of packages.)
*
* @since 14.1
*/
PsiElement[] getChildren(@NotNull GlobalSearchScope scope);
PsiFile[] getFiles(@NotNull GlobalSearchScope scope);
/**
* Returns the list of package-level annotations for the package.
@@ -345,9 +345,16 @@ public class PropertyUtil {
}
public static String suggestSetterName(@NonNls String propertyName) {
@NonNls StringBuilder name =
new StringBuilder(StringUtil.capitalizeWithJavaBeanConvention(StringUtil.sanitizeJavaIdentifier(propertyName)));
name.insert(0, "set");
return suggestSetterName(propertyName, "set");
}
public static String suggestSetterName(@NonNls String propertyName, String setterPrefix) {
final String sanitizeJavaIdentifier = StringUtil.sanitizeJavaIdentifier(propertyName);
if (StringUtil.isEmpty(setterPrefix)) {
return sanitizeJavaIdentifier;
}
@NonNls StringBuilder name = new StringBuilder(StringUtil.capitalizeWithJavaBeanConvention(sanitizeJavaIdentifier));
name.insert(0, setterPrefix);
return name.toString();
}
@@ -585,11 +585,26 @@ public class JavaDocInfoGenerator {
public void generateCommonSection(StringBuilder buffer, PsiDocComment docComment) {
generateDescription(buffer, docComment);
generateApiSection(buffer, docComment);
generateDeprecatedSection(buffer, docComment);
generateSinceSection(buffer, docComment);
generateSeeAlsoSection(buffer, docComment);
}
private void generateApiSection(StringBuilder buffer, PsiDocComment comment) {
final String[] tagNames = {"apiNote", "implSpec", "implNote"};
for (String tagName : tagNames) {
PsiDocTag tag = comment.findTagByName(tagName);
if (tag != null) {
buffer.append("<DD><DL>");
buffer.append("<DT><b>").append(tagName).append("</b>");
buffer.append("<DD>");
generateValue(buffer, tag.getDataElements(), ourEmptyElementsProvider);
buffer.append("</DD></DL></DD>");
}
}
}
private void generatePackageHtmlJavaDoc(final StringBuilder buffer, final PsiFile packageHtmlFile, boolean generatePrologueAndEpilogue) {
String htmlText = packageHtmlFile.getText();
@@ -912,6 +927,7 @@ public class JavaDocInfoGenerator {
generateThrowsSection(buffer, method, comment);
if (comment != null) {
generateApiSection(buffer, comment);
generateSinceSection(buffer, comment);
generateSeeAlsoSection(buffer, comment);
}
@@ -243,17 +243,17 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
return result == null ? PsiClass.EMPTY_ARRAY : result.toArray(new PsiClass[result.size()]);
}
private static class AndPredicate implements Predicate<PsiNamedElement> {
private final List<Predicate<PsiNamedElement>> myComponents = new SmartList<Predicate<PsiNamedElement>>();
private static class AndPredicate<T> implements Predicate<T> {
private final List<Predicate<T>> myComponents = new SmartList<Predicate<T>>();
public AndPredicate(Predicate<PsiNamedElement> filter1, Predicate<PsiNamedElement> filter2) {
public AndPredicate(Predicate<T> filter1, Predicate<T> filter2) {
myComponents.add(filter1);
myComponents.add(filter2);
}
@Override
public boolean apply(@Nullable PsiNamedElement input) {
for (Predicate<PsiNamedElement> component : myComponents) {
public boolean apply(@Nullable T input) {
for (Predicate<T> component : myComponents) {
if (!component.apply(input)) {
return false;
}
@@ -263,34 +263,38 @@ public class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
}
@NotNull
public PsiElement[] getPackageChildren(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
Map<String, PsiNamedElement> result = new HashMap<String, PsiNamedElement>();
Predicate<PsiNamedElement> filter = null;
public PsiFile[] getPackageFiles(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
Predicate<PsiFile> filter = null;
for (PsiElementFinder finder : filteredFinders()) {
Predicate<PsiNamedElement> finderFilter = finder.getPackageChildrenFilter(psiPackage, scope);
Predicate<PsiFile> finderFilter = finder.getPackageFilesFilter(psiPackage, scope);
if (finderFilter != null) {
if (filter == null) {
filter = finderFilter;
}
else if (filter instanceof AndPredicate) {
((AndPredicate) filter).myComponents.add(finderFilter);
((AndPredicate<PsiFile>) filter).myComponents.add(finderFilter);
}
else {
filter = new AndPredicate(filter, finderFilter);
filter = new AndPredicate<PsiFile>(filter, finderFilter);
}
}
}
Set<PsiFile> result = new HashSet<PsiFile>();
PsiDirectory[] directories = psiPackage.getDirectories(scope);
for (PsiDirectory directory : directories) {
for (PsiFile file : directory.getFiles()) {
if (filter == null || filter.apply(file)) {
result.add(file);
}
}
}
for (PsiElementFinder finder : filteredFinders()) {
PsiNamedElement[] children = finder.getChildren(psiPackage, scope);
for (PsiNamedElement child : children) {
if (!result.containsKey(child.getName()) && (filter == null || filter.apply(child))) {
result.put(child.getName(), child);
}
}
Collections.addAll(result, finder.getPackageFiles(psiPackage, scope));
}
return result.values().toArray(new PsiElement[result.size()]);
return result.toArray(new PsiFile[result.size()]);
}
public boolean processPackageDirectories(@NotNull PsiPackage psiPackage,
@@ -23,7 +23,6 @@ import com.intellij.openapi.util.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.filters.OrFilter;
import com.intellij.psi.impl.source.ClassInnerStuffCache;
import com.intellij.psi.impl.source.PsiImmediateClassType;
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
@@ -45,6 +44,7 @@ import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.NullableFunction;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ConcurrentFactoryMap;
import com.intellij.util.containers.HashSet;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
@@ -214,54 +214,6 @@ public class PsiClassImplUtil {
public enum MemberType {CLASS, FIELD, METHOD}
@NotNull
private static MembersMap buildAllMaps(@NotNull PsiClass psiClass) {
final List<Pair<PsiMember, PsiSubstitutor>> classes = new ArrayList<Pair<PsiMember, PsiSubstitutor>>();
final List<Pair<PsiMember, PsiSubstitutor>> fields = new ArrayList<Pair<PsiMember, PsiSubstitutor>>();
final List<Pair<PsiMember, PsiSubstitutor>> methods = new ArrayList<Pair<PsiMember, PsiSubstitutor>>();
FilterScopeProcessor<MethodCandidateInfo> processor = new FilterScopeProcessor<MethodCandidateInfo>(
new OrFilter(ElementClassFilter.METHOD, ElementClassFilter.FIELD, ElementClassFilter.CLASS)) {
@Override
protected void add(@NotNull PsiElement element, @NotNull PsiSubstitutor substitutor) {
if (element instanceof PsiMethod) {
methods.add(Pair.create((PsiMember)element, substitutor));
}
else if (element instanceof PsiField) {
fields.add(Pair.create((PsiMember)element, substitutor));
}
else if (element instanceof PsiClass) {
classes.add(Pair.create((PsiMember)element, substitutor));
}
}
};
processDeclarationsInClassNotCached(psiClass, processor, ResolveState.initial(), null, null, psiClass, false,
PsiUtil.getLanguageLevel(psiClass));
MembersMap result = new MembersMap(MemberType.class);
result.put(MemberType.CLASS, generateMapByList(classes));
result.put(MemberType.METHOD, generateMapByList(methods));
result.put(MemberType.FIELD, generateMapByList(fields));
return result;
}
@NotNull
private static Map<String, List<Pair<PsiMember, PsiSubstitutor>>> generateMapByList(@NotNull final List<Pair<PsiMember, PsiSubstitutor>> list) {
Map<String, List<Pair<PsiMember, PsiSubstitutor>>> map = new THashMap<String, List<Pair<PsiMember, PsiSubstitutor>>>();
map.put(ALL, list);
for (final Pair<PsiMember, PsiSubstitutor> info : list) {
PsiMember element = info.getFirst();
String currentName = element.getName();
List<Pair<PsiMember, PsiSubstitutor>> listByName = map.get(currentName);
if (listByName == null) {
listByName = new ArrayList<Pair<PsiMember, PsiSubstitutor>>(1);
map.put(currentName, listByName);
}
listByName.add(info);
}
return map;
}
private static Map<String, List<Pair<PsiMember, PsiSubstitutor>>> getMap(@NotNull PsiClass aClass, @NotNull MemberType type) {
ParameterizedCachedValue<MembersMap, PsiClass> value = getValues(aClass);
return value.getValue(aClass).get(type);
@@ -407,9 +359,46 @@ public class PsiClassImplUtil {
return factory.createMethodFromText(text, null).getSignature(PsiSubstitutor.EMPTY);
}
private static class MembersMap extends EnumMap<MemberType, Map<String, List<Pair<PsiMember, PsiSubstitutor>>>> {
public MembersMap(@NotNull Class<MemberType> keyType) {
super(keyType);
private static class MembersMap extends ConcurrentFactoryMap<MemberType, Map<String, List<Pair<PsiMember, PsiSubstitutor>>>> {
private final PsiClass myPsiClass;
public MembersMap(PsiClass psiClass) {
myPsiClass = psiClass;
}
@Nullable
@Override
protected Map<String, List<Pair<PsiMember, PsiSubstitutor>>> create(final MemberType key) {
final Map<String, List<Pair<PsiMember, PsiSubstitutor>>> map = new THashMap<String, List<Pair<PsiMember, PsiSubstitutor>>>();
final List<Pair<PsiMember, PsiSubstitutor>> allMembers = new ArrayList<Pair<PsiMember, PsiSubstitutor>>();
map.put(ALL, allMembers);
ElementClassFilter filter = key == MemberType.CLASS ? ElementClassFilter.CLASS :
key == MemberType.METHOD ? ElementClassFilter.METHOD :
ElementClassFilter.FIELD;
FilterScopeProcessor<MethodCandidateInfo> processor = new FilterScopeProcessor<MethodCandidateInfo>(filter) {
@Override
protected void add(@NotNull PsiElement element, @NotNull PsiSubstitutor substitutor) {
if (key == MemberType.CLASS && element instanceof PsiClass ||
key == MemberType.METHOD && element instanceof PsiMethod ||
key == MemberType.FIELD && element instanceof PsiField) {
Pair<PsiMember, PsiSubstitutor> info = Pair.create((PsiMember)element, substitutor);
allMembers.add(info);
String currentName = ((PsiMember)element).getName();
List<Pair<PsiMember, PsiSubstitutor>> listByName = map.get(currentName);
if (listByName == null) {
listByName = new ArrayList<Pair<PsiMember, PsiSubstitutor>>(1);
map.put(currentName, listByName);
}
listByName.add(info);
}
}
};
processDeclarationsInClassNotCached(myPsiClass, processor, ResolveState.initial(), null, null, myPsiClass, false,
PsiUtil.getLanguageLevel(myPsiClass));
return map;
}
}
@@ -418,8 +407,7 @@ public class PsiClassImplUtil {
@Override
public CachedValueProvider.Result<MembersMap> compute(@NotNull PsiClass myClass) {
MembersMap map = buildAllMaps(myClass);
return new CachedValueProvider.Result<MembersMap>(map, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
return new CachedValueProvider.Result<MembersMap>(new MembersMap(myClass), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
}
}
@@ -20,6 +20,8 @@ import com.intellij.lang.Language;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.navigation.ItemPresentation;
import com.intellij.navigation.ItemPresentationProviders;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.ui.Queryable;
import com.intellij.openapi.util.Condition;
@@ -46,6 +48,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
public class PsiPackageImpl extends PsiPackageBase implements PsiPackage, Queryable {
private static final Logger LOG = Logger.getInstance(PsiPackageImpl.class);
private volatile CachedValue<PsiModifierList> myAnnotationList;
private volatile CachedValue<Collection<PsiDirectory>> myDirectories;
private volatile CachedValue<Collection<PsiDirectory>> myDirectoriesWithLibSources;
@@ -153,15 +157,9 @@ public class PsiPackageImpl extends PsiPackageBase implements PsiPackage, Querya
return getFacade().getClasses(this, scope);
}
@NotNull
@Override
public PsiElement[] getChildren() {
return getChildren(allScope());
}
@Override
public PsiElement[] getChildren(@NotNull GlobalSearchScope scope) {
return getFacade().getPackageChildren(this, scope);
public PsiFile[] getFiles(@NotNull GlobalSearchScope scope) {
return getFacade().getPackageFiles(this, scope);
}
@Override
@@ -321,7 +319,17 @@ public class PsiPackageImpl extends PsiPackageBase implements PsiPackage, Querya
@NotNull Condition<String> nameCondition) {
for (PsiClass aClass : classes) {
String name = aClass.getName();
if (name != null && nameCondition.value(name) && !processor.execute(aClass, state)) return false;
if (name != null && nameCondition.value(name)) {
try {
if (!processor.execute(aClass, state)) return false;
}
catch (ProcessCanceledException e) {
throw e;
}
catch (Exception e) {
LOG.error(e);
}
}
}
return true;
}
@@ -44,6 +44,9 @@ public class JavadocManagerImpl implements JavadocManager {
myInfos.add(new SimpleDocTagInfo("serialField", PsiField.class, false, LanguageLevel.JDK_1_3));
myInfos.add(new SimpleDocTagInfo("since", PsiElement.class, PsiPackage.class, LanguageLevel.JDK_1_3));
myInfos.add(new SimpleDocTagInfo("version", PsiClass.class, PsiPackage.class, LanguageLevel.JDK_1_3));
myInfos.add(new SimpleDocTagInfo("apiNote", PsiElement.class, false, LanguageLevel.JDK_1_8));
myInfos.add(new SimpleDocTagInfo("implNote", PsiElement.class, false, LanguageLevel.JDK_1_8));
myInfos.add(new SimpleDocTagInfo("implSpec", PsiElement.class, false, LanguageLevel.JDK_1_8));
myInfos.add(new SimpleDocTagInfo("docRoot", PsiElement.class, true, LanguageLevel.JDK_1_3));
myInfos.add(new SimpleDocTagInfo("inheritDoc", PsiElement.class, true, LanguageLevel.JDK_1_4));
@@ -0,0 +1,10 @@
public class Main {
public int a = 3;
protected Object obj = null;
private long e = 4;
public static void main(String[] args) {
}
}
@@ -0,0 +1,17 @@
import java.lang.Object;
import java.util.LinkedHashSet;
import java.util.Set;
public class Main {
public int a = 3;
private long e = 4;
protected Object obj = null;
public static void main(String[] args) {
}
}
@@ -0,0 +1,10 @@
import java.util.LinkedHashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
}
}
@@ -0,0 +1,15 @@
import java.util.List;
public class Test {
public long newRun;
public int ab;
public int awe;
private int c;
public void run() {
List<String> strings = null;
}
}
@@ -0,0 +1,21 @@
import java.util.HashMap;
import java.util.Set;
import java.util.List;
public class Test {
public long newRun;
public void run() {
List<String> strings = null;
}
public int ab;
private int c;
public int awe;
}
@@ -0,0 +1,23 @@
import java.util.LinkedHashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
Set<String> test = new LinkedHashSet<String>();
if (test.contains("AA")) {
if (test.contains("AS")) {
System.out.println("AAAA!");
}
}
}
};
runnable.run();
}
}
@@ -0,0 +1,27 @@
import java.lang.Override;
import java.lang.Runnable;
import java.lang.String;
import java.util.Set;
import java.util.HashSet;
import java.util.LinkedHashSet;
public class Main {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
Set<String> test = new LinkedHashSet<String>();
if (test.contains("AA")) {
if (test.contains("AS")) {
System.out.println("AAAA!");
}
}
}
};
runnable.run();
}
}
@@ -0,0 +1,23 @@
import com.intellij.util.containers.HashSet;
import java.util.Set;
import java.util.HashSet;
public class Main {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
Set<String> test = new HashSet<String>();
if (test.contains("AA")) {
System.out.println("AAAA!");
}
}
};
runnable.run();
}
}
@@ -0,0 +1,10 @@
import java.util.List;
public class Test {
public void run() {
List<String> strings = null;
}
}
@@ -0,0 +1,12 @@
import java.util.HashMap;
import java.util.Set;
import java.util.List;
public class Test {
public void run() {
List<String> strings = null;
}
}
@@ -0,0 +1,9 @@
class Test {
public int a = 3;
private int b = 3;
public void run () {}
int aero = 12;
}
@@ -0,0 +1,9 @@
class Test {
<selection> private int b = 3;
public int a = 3;</selection>
public void run () {}
int aero = 12;
}
@@ -0,0 +1,15 @@
public class Test {
int a = 3;
int c = 12;
public void run() {
int arr = 12;
long test = 1;
}
}
@@ -0,0 +1,15 @@
public class Test {
int a = 3;
int c = 12;
public void run() {
<selection> int arr = 12;
long test =1;</selection>
}
}
@@ -0,0 +1,13 @@
public class Test {
public void run() {
int a = 3;
int b = 12;
}
public void test() {
}
}
@@ -0,0 +1,13 @@
public class Test {
public void run() {
int a = 3;
int b = 12;
}
public void test() {
}
}
@@ -0,0 +1,10 @@
public class Test {
public void run() {
int a = 3;
}
}
@@ -0,0 +1,8 @@
public class Test {
int a = 3;
void run() {
}
}
@@ -0,0 +1,9 @@
public class Test {
int a = 3;
void run()
{
}
}
@@ -0,0 +1,5 @@
public class Test1 {
public void foo() {
new Tim<caret>
}
}
@@ -0,0 +1,8 @@
class Test {
/**
* @apiNote note1
* @implNote implNote
* @implSpec implSpec
*/
public void i() {}
}
@@ -11,7 +11,7 @@ class Test {
final Test test = (Test) o;
// Compare nested arrays - values of myIIs here
if (!Arrays.deepEquals(myIIs, test.myIIs)) return false;
if (!Arrays.equals(myIs, test.myIs)) return false;
// Probably incorrect - comparing Object[] arrays with Arrays.equals
if (!Arrays.equals(myOs, test.myOs)) return false;
@@ -21,7 +21,8 @@ class Test {
public int hashCode() {
int result = myOs != null ? Arrays.hashCode(myOs) : 0;
result = 31 * result + (myIIs != null ? Arrays.hashCode(myIIs) : 0);
result = 31 * result + (myIIs != null ? // Probably incorrect - hashCode for high dimension arrays with Arrays.hashCode
Arrays.hashCode(myIIs) : 0);
result = 31 * result + (myIs != null ? Arrays.hashCode(myIs) : 0);
return result;
}
@@ -0,0 +1 @@
<html><head> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } p { margin: 5px 0; } </style></head><body><small><b><a href="psi_element://Test"><code>Test</code></a></b></small><PRE>public&nbsp;void&nbsp;<b>foo</b>()</PRE><DD><DL><DT><b>apiNote</b><DD> my api note </DD></DL></DD><DD><DL><DT><b>implSpec</b><DD> my impl spec </DD></DL></DD><DD><DL><DT><b>implNote</b><DD> my impl note</DD></DL></DD></body></html>
@@ -0,0 +1,13 @@
class Test {
/**
* @apiNote
* my api note
*
* @implSpec
* my impl spec
*
* @implNote
* my impl note
*/
public void foo(){}
}
@@ -0,0 +1,5 @@
class A {
public static void main() {
template.with.desc<caret>
}
}
@@ -0,0 +1,5 @@
class A {
public static void main() {
template with description<caret>
}
}
@@ -0,0 +1,11 @@
class MyTest {
String foo;
{
I i;
foo<caret>
i = MyTest::foo;
}
}
@@ -0,0 +1,11 @@
class MyTest {
String bar;
{
I i;
bar
i = MyTest::foo;
}
}
@@ -14,15 +14,70 @@
* limitations under the License.
*/
package com.intellij.codeInsight
import com.intellij.codeInsight.documentation.DocumentationManager
import com.intellij.codeInsight.navigation.CtrlMouseHandler
import com.intellij.lang.java.JavaDocumentationProvider
import com.intellij.psi.PsiExpressionList
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
/**
* @author peter
*/
class JavaDocumentationTest extends LightCodeInsightFixtureTestCase {
public void testConstructorDoc() {
myFixture.configureByText 'a.java', '''
class Foo { Foo() {} Foo(int param) {} }
class Foo2 {{
new Foo<caret>
}}
'''
def originalElement = myFixture.file.findElementAt(myFixture.editor.caretModel.offset)
def doc = new JavaDocumentationProvider().generateDoc(
DocumentationManager.getInstance(project).findTargetElement(myFixture.editor, myFixture.file),
originalElement
)
assert doc == """<html>Candidates for new <b>Foo</b>() are:<br>&nbsp;&nbsp;<a href="psi_element://Foo#Foo()">Foo()</a><br>&nbsp;&nbsp;<a href="psi_element://Foo#Foo(int)">Foo(int param)</a><br></html>"""
}
public void testConstructorDoc2() {
myFixture.configureByText 'a.java', '''
class Foo { Foo() {} Foo(int param) {} }
class Foo2 {{
new Foo(<caret>)
}}
'''
def elementAt = myFixture.file.findElementAt(myFixture.editor.caretModel.offset)
def exprList = PsiTreeUtil.getParentOfType(elementAt, PsiExpressionList.class)
def doc = new JavaDocumentationProvider().generateDoc(
exprList,
elementAt
)
assert doc == """<html>Candidates for new <b>Foo</b>() are:<br>&nbsp;&nbsp;<a href="psi_element://Foo#Foo()">Foo()</a><br>&nbsp;&nbsp;<a href="psi_element://Foo#Foo(int)">Foo(int param)</a><br></html>"""
}
public void testMethodDocWhenInArgList() {
myFixture.configureByText 'a.java', '''
class Foo { void doFoo() {} }
class Foo2 {{
new Foo().doFoo(<caret>)
}}
'''
def exprList = PsiTreeUtil.getParentOfType(myFixture.file.findElementAt(myFixture.editor.caretModel.offset), PsiExpressionList.class)
def doc = new JavaDocumentationProvider().generateDoc(
exprList,
null
)
assert doc == """<html><head> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } p { margin: 5px 0; } </style></head><body><small><b><a href="psi_element://Foo"><code>Foo</code></a></b></small><PRE>void&nbsp;<b>doFoo</b>()</PRE></body></html>"""
}
public void testGenericMethod() {
myFixture.configureByText 'a.java', '''
class Bar<T> { java.util.List<T> foo(T param); }
@@ -28,7 +28,6 @@ import com.intellij.testFramework.LightCodeInsightTestCase;
import com.intellij.testFramework.utils.parameterInfo.MockCreateParameterInfoContext;
import com.intellij.testFramework.utils.parameterInfo.MockParameterInfoUIContext;
import com.intellij.testFramework.utils.parameterInfo.MockUpdateParameterInfoContext;
import com.intellij.util.ArrayUtilRt;
import com.intellij.util.Function;
import junit.framework.Assert;
@@ -104,21 +103,10 @@ public class ParameterInfoTest extends LightCodeInsightTestCase {
assertEquals(2, itemsToShow.length);
assertTrue(itemsToShow[0] instanceof MethodCandidateInfo);
final ParameterInfoUIContextEx parameterContext = ParameterInfoComponent.createContext(itemsToShow, myEditor, handler, -1);
final Boolean [] enabled = new Boolean[itemsToShow.length];
final MockUpdateParameterInfoContext updateParameterInfoContext = new MockUpdateParameterInfoContext(myEditor, myFile){
@Override
public Object[] getObjectsToView() {
return itemsToShow;
}
@Override
public void setUIComponentEnabled(int index, boolean b) {
enabled[index] = b;
}
};
final MockUpdateParameterInfoContext updateParameterInfoContext = new MockUpdateParameterInfoContext(myEditor, myFile, itemsToShow);
updateParameterInfoContext.setParameterOwner(list);
handler.updateParameterInfo(list, updateParameterInfoContext);
assertTrue(ArrayUtilRt.find(enabled, Boolean.TRUE) > -1);
assertTrue(updateParameterInfoContext.isUIComponentEnabled(0) || updateParameterInfoContext.isUIComponentEnabled(1));
}
public void testAfterGenericsInsideCall() throws Exception {
@@ -0,0 +1,121 @@
/*
* Copyright 2000-2014 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.actions;
import com.intellij.JavaTestUtil;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ContentRevision;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.psi.PsiFile;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ReformatCodeActionInEditorTest extends LightCodeInsightFixtureTestCase {
@Override
protected String getTestDataPath() {
return JavaTestUtil.getJavaTestDataPath() + "/actions/reformatFileInEditor/";
}
public void doTest(@NotNull ReformatFilesOptions options) {
setOptions(options);
String before = null;
if (options.isProcessOnlyChangedText()) {
myFixture.configureByFile(getTestName(true) + "_revision.java");
PsiFile file = myFixture.getFile();
Document document = myFixture.getDocument(file);
before = document.getText();
}
myFixture.configureByFile(getTestName(true) + "_before.java");
if (before != null) {
myFixture.getFile().putUserData(FormatChangedTextUtil.TEST_REVISION_CONTENT, before);
}
final String actionId = IdeActions.ACTION_EDITOR_REFORMAT;
AnAction action = ActionManager.getInstance().getAction(actionId);
AnActionEvent event = createEventFor(action, getProject(), myFixture.getEditor());
action.actionPerformed(event);
myFixture.checkResultByFile(getTestName(true) + "_after.java");
}
@Override
public void tearDown() throws Exception {
myFixture.getFile().putUserData(FormatChangedTextUtil.TEST_REVISION_CONTENT, null);
super.tearDown();
}
protected AnActionEvent createEventFor(@NotNull AnAction action, @NotNull final Project project, @NotNull final Editor editor) {
return new AnActionEvent(null, new DataContext() {
@Nullable
@Override
public Object getData(@NonNls String dataId) {
if (CommonDataKeys.PROJECT.is(dataId)) return project;
if (CommonDataKeys.EDITOR.is(dataId)) return editor;
return null;
}
}, "", action.getTemplatePresentation(), ActionManager.getInstance(), 0);
}
protected void setOptions(ReformatFilesOptions options) {
ReformatCodeAction.setTestOptions(options);
}
public void testFormatWholeFile() {
doTest(new MockReformatFileSettings().setProcessWholeFile(true));
}
public void testFormatOptimizeWholeFile() {
doTest(new MockReformatFileSettings().setProcessWholeFile(true).setOptimizeImports(true));
}
public void testFormatOptimizeRearrangeWholeFile() {
doTest(new MockReformatFileSettings().setProcessWholeFile(true).setOptimizeImports(true).setRearrange(true));
}
public void testFormatSelection() {
doTest(new MockReformatFileSettings().setProcessWholeFile(false));
}
public void testFormatRearrangeSelection() {
doTest(new MockReformatFileSettings().setProcessWholeFile(false).setRearrange(true));
}
public void testFormatVcsChanges() {
doTest(new MockReformatFileSettings().setProcessOnlyChangedText(true));
}
public void testFormatOptimizeVcsChanges() {
doTest(new MockReformatFileSettings().setProcessOnlyChangedText(true).setOptimizeImports(true));
}
public void testFormatOptimizeRearrangeVcsChanges() {
doTest(new MockReformatFileSettings().setProcessOnlyChangedText(true).setOptimizeImports(true).setRearrange(true));
}
}
@@ -19,11 +19,13 @@ import com.intellij.JavaTestUtil;
import com.intellij.codeInsight.lookup.LookupManager;
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
import com.intellij.codeInsight.template.impl.TemplateState;
import com.intellij.lang.java.JavaDocumentationProvider;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.PsiClass;
import com.intellij.testFramework.TestDataPath;
import java.io.IOException;
@@ -58,6 +60,23 @@ public class ClassNameCompletionTest extends LightFixtureCompletionTestCase {
checkResultByFile(path + "/after2.java");
}
public void testDocAfterNew() throws Exception {
createClass("public class Time { Time() {} Time(long time) {} }");
String path = "/docAfterNew";
configureByFile(path + "/before1.java");
assertTrue(myItems != null && myItems.length >= 1);
String doc = new JavaDocumentationProvider().generateDoc(
(PsiClass)myItems[0].getObject(),
myFixture.getFile().findElementAt(myFixture.getEditor().getCaretModel().getOffset())
);
assertEquals(doc,
"<html>Candidates for new <b>Time</b>() are:<br>&nbsp;&nbsp;<a href=\"psi_element://Time#Time()\">Time()</a><br>&nbsp;" +
"&nbsp;<a href=\"psi_element://Time#Time(long)\">Time(long time)</a><br></html>");
}
public void testTypeParametersTemplate() throws Exception {
createClass("package pack; public interface Foo<T> {void foo(T t};");
@@ -95,6 +95,7 @@ public class JavadocHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testValueNotOnField() throws Exception { doTestWithLangLevel(LanguageLevel.HIGHEST); }
public void testValueNotOnStaticField() throws Exception { doTestWithLangLevel(LanguageLevel.HIGHEST); }
public void testValueOnNotInitializedField() throws Exception { doTestWithLangLevel(LanguageLevel.HIGHEST); }
public void testJava18Tags() throws Exception { doTestWithLangLevel(LanguageLevel.JDK_1_8); }
public void testUnknownInlineTag() throws Exception { doTest(); }
public void testUnknownTags() throws Exception { doTest(); }
@@ -113,6 +113,10 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase {
doTestMethod();
}
public void testApiNotes() throws Exception {
doTestMethod();
}
public void testLiteral() throws Exception {
doTestField();
}
@@ -33,6 +33,7 @@ public class ListTemplateActionTest extends LightCodeInsightFixtureTestCase {
TemplateManagerImpl.setTemplateTesting(getProject(), getTestRootDisposable());
addTemplate("simple", "simple template text", "description");
addTemplate("complex key", "complex template text", "");
addTemplate("template.with.desc", "template with description", "desc");
}
private void addTemplate(String key, String text, String description) {
@@ -92,6 +93,10 @@ public class ListTemplateActionTest extends LightCodeInsightFixtureTestCase {
public void testComplexKeyWithNotMatchedPrefixAfterNonJavaCharacter() {
doTest("complex key");
}
public void testTemplateShouldNotBeReplacedByOtherTemplateMatchedByDescription() {
doTest("template.with.desc");
}
private void doTest(@NotNull String lookupText) {
myFixture.configureByFile(getTestName(false) + ".java");
@@ -115,7 +115,7 @@ public class NavigateFromSourceTest extends BaseProjectViewTestCase {
pane.select(psiClass, psiClass.getContainingFile().getVirtualFile(), true);
assertEquals(9, tree.getSelectionCount());
assertEquals(8, tree.getSelectionCount());
}
private static void changeClassTextAndTryToNavigate(final String newClassString,
@@ -0,0 +1,221 @@
/*
* Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* -Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduct the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the distribution.
*
* Neither the name of JetBrains or IntelliJ IDEA
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT
* BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT
* OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN
* IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
*/
package com.intellij.projectView;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.ide.projectView.impl.AbstractProjectTreeStructure;
import com.intellij.ide.projectView.impl.PackageViewPane;
import com.intellij.ide.projectView.impl.ProjectViewImpl;
import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.impl.ModuleManagerImpl;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.TestSourceBasedTestCase;
import com.intellij.util.ui.tree.TreeUtil;
import com.intellij.lang.properties.projectView.ResourceBundleGrouper;
import org.jetbrains.annotations.NonNls;
import javax.swing.*;
import java.io.IOException;
public class PackagesTreeStructureTest extends TestSourceBasedTestCase {
public void testPackageView() throws IOException {
ModuleManagerImpl.getInstanceImpl(myProject).setModuleGroupPath(myModule, new String[]{"Group"});
final VirtualFile srcFile = getSrcDirectory().getVirtualFile();
if (srcFile.findChild("empty") == null){
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
try {
srcFile.createChildDirectory(this, "empty");
}
catch (IOException e) {
fail(e.getLocalizedMessage());
}
}
});
}
doTest(true, true, "-Project\n" +
" -Group: Group\n" +
" -Module\n" +
" -PsiPackage: com.package1\n" +
" Class1.java\n" +
" Class2.java\n" +
" Class4.java\n" +
" Form1.form\n" +
" Form1.java\n" +
" Form2.form\n" +
" PsiPackage: empty\n" +
" -PsiPackage: java\n" +
" Class1.java\n" +
" -PsiPackage: javax.servlet\n" +
" Class1.java\n" +
" -Libraries\n" +
" -PsiPackage: java\n" +
" +PsiPackage: awt\n" +
" +PsiPackage: beans.beancontext\n" +
" +PsiPackage: io\n" +
" +PsiPackage: lang\n" +
" +PsiPackage: net\n" +
" +PsiPackage: rmi\n" +
" +PsiPackage: security\n" +
" +PsiPackage: sql\n" +
" +PsiPackage: util\n" +
" -PsiPackage: javax.swing\n" +
" +PsiPackage: table\n" +
" AbstractButton.class\n" +
" Icon.class\n" +
" JButton.class\n" +
" JComponent.class\n" +
" JDialog.class\n" +
" JFrame.class\n" +
" JLabel.class\n" +
" JPanel.class\n" +
" JScrollPane.class\n" +
" JTable.class\n" +
" SwingConstants.class\n" +
" SwingUtilities.class\n" +
" -PsiPackage: META-INF\n" +
" MANIFEST.MF\n" +
" MANIFEST.MF\n" +
" -PsiPackage: org\n" +
" +PsiPackage: intellij.lang.annotations\n" +
" +PsiPackage: jetbrains.annotations\n" +
""
, 5);
doTest(false, true, "-Project\n" +
" -PsiPackage: com.package1\n" +
" Class1.java\n" +
" Class2.java\n" +
" Class4.java\n" +
" Form1.form\n" +
" Form1.java\n" +
" Form2.form\n" +
" PsiPackage: empty\n" +
" -PsiPackage: java\n" +
" Class1.java\n" +
" -PsiPackage: javax.servlet\n" +
" Class1.java\n" +
" -Libraries\n" +
" -PsiPackage: java\n" +
" +PsiPackage: awt\n" +
" +PsiPackage: beans.beancontext\n" +
" +PsiPackage: io\n" +
" +PsiPackage: lang\n" +
" +PsiPackage: net\n" +
" +PsiPackage: rmi\n" +
" +PsiPackage: security\n" +
" +PsiPackage: sql\n" +
" +PsiPackage: util\n" +
" -PsiPackage: javax.swing\n" +
" +PsiPackage: table\n" +
" AbstractButton.class\n" +
" Icon.class\n" +
" JButton.class\n" +
" JComponent.class\n" +
" JDialog.class\n" +
" JFrame.class\n" +
" JLabel.class\n" +
" JPanel.class\n" +
" JScrollPane.class\n" +
" JTable.class\n" +
" SwingConstants.class\n" +
" SwingUtilities.class\n" +
" -PsiPackage: META-INF\n" +
" MANIFEST.MF\n" +
" MANIFEST.MF\n" +
" -PsiPackage: org\n" +
" +PsiPackage: intellij.lang.annotations\n" +
" +PsiPackage: jetbrains.annotations\n"
, 3);
doTest(true, false, "-Project\n" +
" -Group: Group\n" +
" -Module\n" +
" -PsiPackage: com.package1\n" +
" Class1.java\n" +
" Class2.java\n" +
" Class4.java\n" +
" Form1.form\n" +
" Form1.java\n" +
" Form2.form\n" +
" PsiPackage: empty\n" +
" -PsiPackage: java\n" +
" Class1.java\n" +
" -PsiPackage: javax.servlet\n" +
" Class1.java\n", 4);
doTest(false, false, "-Project\n" +
" -PsiPackage: com.package1\n" +
" Class1.java\n" +
" Class2.java\n" +
" Class4.java\n" +
" Form1.form\n" +
" Form1.java\n" +
" Form2.form\n" +
" PsiPackage: empty\n" +
" -PsiPackage: java\n" +
" Class1.java\n" +
" -PsiPackage: javax.servlet\n" +
" Class1.java\n", 3);
}
private void doTest(final boolean showModules, final boolean showLibraryContents, @NonNls final String expected, final int levels) {
final ProjectViewImpl projectView = (ProjectViewImpl)ProjectView.getInstance(myProject);
projectView.setShowModules(showModules, PackageViewPane.ID);
projectView.setShowLibraryContents(showLibraryContents, PackageViewPane.ID);
projectView.setFlattenPackages(false, PackageViewPane.ID);
projectView.setHideEmptyPackages(true, PackageViewPane.ID);
PackageViewPane packageViewPane = new PackageViewPane(myProject);
packageViewPane.createComponent();
((AbstractProjectTreeStructure) packageViewPane.getTreeStructure()).setProviders(new ResourceBundleGrouper(myProject));
packageViewPane.updateFromRoot(true);
JTree tree = packageViewPane.getTree();
TreeUtil.expand(tree, levels);
IdeaTestUtil.assertTreeEqual(tree, expected);
BaseProjectViewTestCase.checkContainsMethod(packageViewPane.getTreeStructure().getRootElement(), packageViewPane.getTreeStructure());
Disposer.dispose(packageViewPane);
}
@Override
protected String getTestPath() {
return "projectView";
}
}
@@ -80,6 +80,10 @@ public class RenameMembersInplaceTest extends LightCodeInsightTestCase {
doTestInplaceRename("bar");
}
public void testRenameFieldInIncompleteStatement() throws Exception {
doTestInplaceRename("bar");
}
public void testNameSuggestion() throws Exception {
configureByFile(BASE_PATH + "/" + getTestName(false) + ".java");
@@ -111,7 +111,7 @@ public class ReplaceConstructorWithBuilderTest extends MultiFileTestCase {
final LinkedHashMap<String, ParameterData> map = new LinkedHashMap<String, ParameterData>();
final PsiMethod[] constructors = aClass.getConstructors();
for (PsiMethod constructor : constructors) {
ParameterData.createFromConstructor(constructor, map);
ParameterData.createFromConstructor(constructor, "set", map);
}
if (expectedDefaults != null) {
for (Map.Entry<String, String> entry : expectedDefaults.entrySet()) {
@@ -15,6 +15,7 @@
*/
package com.intellij.execution.filters;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.JavaPsiFacade;
@@ -58,6 +59,10 @@ public class ExceptionInfoCache {
return cached;
}
if (DumbService.isDumb(myProject)) {
return Pair.create(PsiClass.EMPTY_ARRAY, PsiFile.EMPTY_ARRAY);
}
PsiClass[] classes = findClassesPreferringMyScope(className);
if (classes.length == 0) {
final int dollarIndex = className.indexOf('$');
@@ -33,6 +33,7 @@ class JavaPredefinedConfigurations {
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.string.literals"),"\"'_String\"",EXPRESSION_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.all.expressions.of.some.type"),"'_Expression:[exprtype( SomeType )]",EXPRESSION_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.sample.method.invokation.with.constant.argument"),"Integer.parseInt('_a:[script( \"com.intellij.psi.util.PsiUtil.isConstantExpression(__context__)\" )])",EXPRESSION_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.method.references"), "'_Qualifier::'methodName", EXPRESSION_TYPE),
// Operators
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.block.dcls"),"{\n '_Type+ 'Var+ = '_Init*;\n '_BlockStatements*;\n}",OPERATOR_TYPE),
@@ -90,7 +91,7 @@ class JavaPredefinedConfigurations {
),
createSearchTemplateInfo(
SSRBundle.message("predefined.configuration.implementors.of.interface.within.hierarchy"),
"class 'Class implements 'Interface:* {}",
"class 'Class implements '_Interface:* {}",
CLASS_TYPE
),
createSearchTemplateInfo(
@@ -165,6 +166,7 @@ class JavaPredefinedConfigurations {
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.generic.casts"),"( '_Type <'_GenericArgument+> ) '_Expr", GENERICS_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.type.var.substitutions.in.intanceof.with.generic.types"),"'_Expr instanceof '_Type <'Substitutions+> ", GENERICS_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.variables.of.generic.types"),"'_Type <'_GenericArgument+> 'Var = 'Init?;", GENERICS_TYPE),
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.diamond.operators"), "new 'ClassName<>('_Argument*)", GENERICS_TYPE),
// Add comments and metadata
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.comments"),"/* 'CommentContent */", METADATA_TYPE),
@@ -1,6 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2014 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,49 +16,75 @@
package com.intellij.testFramework;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiReference;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
public abstract class ResolveTestCase extends PsiTestCase {
@NonNls protected static final String MARKER = "<ref>";
protected static final String MARKER = "<ref>";
protected PsiReference configureByFile(@NonNls String filePath) throws Exception{
private Document myDocument;
@Override
protected void tearDown() throws Exception {
if (myDocument != null) {
FileDocumentManager.getInstance().reloadFromDisk(myDocument);
}
super.tearDown();
}
protected PsiReference configureByFile(@NotNull String filePath) throws Exception {
return configureByFile(filePath, null);
}
protected PsiReference configureByFile(@TestDataFile @NonNls String filePath, @Nullable VirtualFile parentDir) throws Exception{
protected PsiReference configureByFile(@TestDataFile @NotNull String filePath, @Nullable VirtualFile parentDir) throws Exception {
final String fullPath = getTestDataPath() + filePath;
final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/'));
assertNotNull("file " + filePath + " not found", vFile);
String fileText = StringUtil.convertLineSeparators(VfsUtil.loadText(vFile));
final String fileName = vFile.getName();
return configureByFileText(fileText, fileName, parentDir);
String fileText = StringUtil.convertLineSeparators(VfsUtilCore.loadText(vFile));
return configureByFileText(fileText, vFile.getName(), parentDir);
}
protected PsiReference configureByFileText(String fileText, String fileName) throws Exception {
return configureByFileText(fileText, fileName, null);
}
protected PsiReference configureByFileText(String fileText, String fileName, @Nullable final VirtualFile parentDir) throws Exception {
protected PsiReference configureByFileText(String fileText, String fileName, @Nullable VirtualFile parentDir) throws Exception {
int offset = fileText.indexOf(MARKER);
assertTrue(offset >= 0);
fileText = fileText.substring(0, offset) + fileText.substring(offset + MARKER.length());
myFile = parentDir == null? createFile(myModule, fileName, fileText) : createFile(myModule, parentDir, fileName, fileText);
if (parentDir == null) {
myFile = createFile(myModule, fileName, fileText);
}
else {
VirtualFile existing = parentDir.findChild(fileName);
if (existing != null) {
myDocument = FileDocumentManager.getInstance().getDocument(existing);
assertNotNull(myDocument);
myDocument.setText(fileText);
myFile = PsiManager.getInstance(getProject()).findFile(existing);
assertNotNull(myFile);
assertEquals(fileText, myFile.getText());
}
else {
myFile = createFile(myModule, parentDir, fileName, fileText);
}
}
PsiReference ref = myFile.findReferenceAt(offset);
assertNotNull(ref);
return ref;
}
@@ -15,7 +15,6 @@
*/
package com.intellij.testFramework;
import com.intellij.ide.highlighter.ProjectFileType;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
@@ -101,7 +100,6 @@ import java.io.File;
}
protected String getRootFiles() {
return " " + myModule.getModuleFile().getName() + "\n" +
" " + myProject.getName() + ProjectFileType.DOT_DEFAULT_EXTENSION + "\n";
return " " + myModule.getModuleFile().getName() + "\n";
}
}
@@ -602,8 +602,10 @@ public class JavaBuilder extends ModuleLevelBuilder {
if (baseDirectory != null) {
//this is a temporary workaround to allow passing per-module compiler options for Eclipse compiler in form
// -properties $MODULE_DIR$/.settings/org.eclipse.jdt.core.prefs
String stringToReplace = "$" + PathMacroUtil.MODULE_DIR_MACRO_NAME + "$";
String moduleDirPath = FileUtil.toCanonicalPath(baseDirectory.getAbsolutePath());
for (String s : cached) {
options.add(StringUtil.replace(s, "$" + PathMacroUtil.MODULE_DIR_MACRO_NAME + "$", baseDirectory.getAbsolutePath()));
options.add(StringUtil.replace(s, stringToReplace, moduleDirPath));
}
}
else {
@@ -21,6 +21,8 @@ import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.util.Comparing;
import com.intellij.ui.JBColor;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.HashMap;
import com.intellij.util.ui.ColorIcon;
import com.intellij.util.ui.JBUI;
@@ -118,11 +120,11 @@ public class HighlightDisplayLevel {
@NotNull
public static Icon createIconByMask(final Color renderColor) {
return new TheColorIcon(getEmptyIconDim(), renderColor);
return new MyColorIcon(getEmptyIconDim(), renderColor);
}
public static class TheColorIcon extends ColorIcon implements ColoredIcon {
public TheColorIcon(int size, @NotNull Color color) {
private static class MyColorIcon extends ColorIcon implements ColoredIcon {
public MyColorIcon(int size, @NotNull Color color) {
super(size, color);
}
@@ -130,12 +132,12 @@ public class HighlightDisplayLevel {
public Color getColor() {
return getIconColor();
}
}
}
public interface ColoredIcon {
Color getColor();
}
public static class SingleColorIcon implements Icon, ColoredIcon {
private final TextAttributesKey myKey;
@@ -143,7 +145,13 @@ public class HighlightDisplayLevel {
myKey = key;
}
@NotNull
public Color getColor() {
return ObjectUtils.notNull(getColorInner(), JBColor.GRAY);
}
@Nullable
public Color getColorInner() {
final EditorColorsManager manager = EditorColorsManager.getInstance();
if (manager != null) {
TextAttributes attributes = manager.getGlobalScheme().getAttributes(myKey);
@@ -94,16 +94,7 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
myRendererColors.put(severity.getName(), renderColor);
}
myOrderMap = null;
final TextAttributes attributes = info.getAttributes();
Color color = attributes.getErrorStripeColor();
if (color == null) {
color = attributes.getEffectColor();
}
if (color == null) {
color = JBColor.GRAY;
}
new HighlightDisplayLevel(severity, new HighlightDisplayLevel.TheColorIcon(HighlightDisplayLevel.getEmptyIconDim(), color));
HighlightDisplayLevel.registerSeverity(severity, getHighlightInfoTypeBySeverity(severity).getAttributesKey());
severitiesChanged();
}
@@ -59,6 +59,7 @@ public interface Project extends ComponentManager, AreaInstance {
*
* @return a path to a project base directory, or <code>null</code> for default project
*/
@Nullable
@NonNls
String getBasePath();
@@ -332,7 +332,7 @@ public abstract class VirtualFile extends UserDataHolderBase implements Modifica
return null;
}
@Nullable
@NotNull
public VirtualFile findOrCreateChildData(Object requestor, @NotNull @NonNls String name) throws IOException {
final VirtualFile child = findChild(name);
if (child != null) return child;
@@ -23,7 +23,7 @@ import org.jetbrains.annotations.Nullable;
/**
* @author peter
* @see com.intellij.psi.LanguageSubstitutors
* @see LanguageSubstitutors
*/
public abstract class LanguageSubstitutor {
@@ -25,6 +25,7 @@ import com.intellij.psi.StubBuilder;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.IFileElementType;
import com.intellij.psi.tree.ILightStubFileElementType;
import com.intellij.psi.tree.IStubFileElementType;
import com.intellij.util.containers.Stack;
import gnu.trove.TIntStack;
import org.jetbrains.annotations.NotNull;
@@ -46,11 +47,18 @@ public class LightStubBuilder implements StubBuilder {
}
Language language = ((LanguageFileType)fileType).getLanguage();
final IFileElementType contentType = LanguageParserDefinitions.INSTANCE.forLanguage(language).getFileNodeType();
if (!(contentType instanceof ILightStubFileElementType)) {
LOG.error("File is not of ILightStubFileElementType: " + contentType + ", " + file);
if (!(contentType instanceof IStubFileElementType)) {
LOG.error("File is not of IStubFileElementType: " + contentType + ", " + file);
return null;
}
tree = file.getNode().getLighterAST();
final FileASTNode node = file.getNode();
if (contentType instanceof ILightStubFileElementType) {
tree = node.getLighterAST();
}
else {
tree = new TreeBackedLighterAST(node);
}
} else {
FORCED_AST.set(null);
}
@@ -120,6 +120,7 @@ public class MockProject extends MockComponentManager implements Project {
return myBaseDir;
}
@Nullable
@Override
public String getBasePath() {
return null;
@@ -150,7 +150,7 @@ public class PsiDirectoryImpl extends PsiElementBase implements PsiDirectory, Qu
CheckUtil.checkWritable(this);
VirtualFile parentFile = myFile.getParent();
if (parentFile == null) {
throw new IncorrectOperationException(VfsBundle.message("cannot.rename.root.directory"));
throw new IncorrectOperationException(VfsBundle.message("cannot.rename.root.directory", myFile.getPath()));
}
VirtualFile child = parentFile.findChild(name);
if (child != null && !child.equals(myFile)) {
@@ -126,10 +126,24 @@ public class FileManagerImpl implements FileManager {
}
}
removeInvalidFilesAndDirs(false);
checkLanguageChange();
}
});
}
private void checkLanguageChange() {
Map<VirtualFile, FileViewProvider> fileToPsiFileMap = new THashMap<VirtualFile, FileViewProvider>(myVFileToViewProviderMap);
myVFileToViewProviderMap.clear();
for (Iterator<VirtualFile> iterator = fileToPsiFileMap.keySet().iterator(); iterator.hasNext();) {
VirtualFile vFile = iterator.next();
Language language = getLanguage(vFile);
if (language != null && language != fileToPsiFileMap.get(vFile).getBaseLanguage()) {
iterator.remove();
}
}
myVFileToViewProviderMap.putAll(fileToPsiFileMap);
}
public void forceReload(@NotNull VirtualFile vFile) {
if (findCachedViewProvider(vFile) == null) {
return;
@@ -231,6 +245,11 @@ public class FileManagerImpl implements FileManager {
@NotNull
public FileViewProvider createFileViewProvider(@NotNull final VirtualFile file, boolean eventSystemEnabled) {
Language language = getLanguage(file);
return createFileViewProvider(file, eventSystemEnabled, language);
}
@NotNull
private FileViewProvider createFileViewProvider(@NotNull VirtualFile file, boolean eventSystemEnabled, Language language) {
final FileViewProviderFactory factory = language == null
? FileTypeFileViewProviders.INSTANCE.forFileType(file.getFileType())
: LanguageFileViewProviders.INSTANCE.forLanguage(language);
@@ -18,10 +18,7 @@ package com.intellij.psi.impl.source;
import com.intellij.extapi.psi.StubBasedPsiElementBase;
import com.intellij.ide.util.PsiNavigationSupport;
import com.intellij.lang.ASTFactory;
import com.intellij.lang.ASTNode;
import com.intellij.lang.FileASTNode;
import com.intellij.lang.Language;
import com.intellij.lang.*;
import com.intellij.navigation.ItemPresentation;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
@@ -48,10 +45,7 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.stubs.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.ILazyParseableElementType;
import com.intellij.psi.tree.IStubFileElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.tree.*;
import com.intellij.reference.SoftReference;
import com.intellij.util.FileContentUtilCore;
import com.intellij.util.IncorrectOperationException;
@@ -256,7 +250,9 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
final Iterator<StubElement<?>> stubs = stubTree.getPlainList().iterator();
stubs.next(); // Skip file stub;
final List<Pair<StubBasedPsiElementBase, CompositeElement>> result = ContainerUtil.newArrayList();
final StubBuilder builder = ((IStubFileElementType)getContentElementType()).getBuilder();
final IStubFileElementType elementType = getElementTypeForStubBuilder();
assert elementType != null;
final StubBuilder builder = elementType.getBuilder();
LazyParseableElement.setSuppressEagerPsiCreation(true);
try {
@@ -299,6 +295,12 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
return result;
}
@Nullable
public IStubFileElementType getElementTypeForStubBuilder() {
final IFileElementType type = LanguageParserDefinitions.INSTANCE.forLanguage(getLanguage()).getFileNodeType();
return type instanceof IStubFileElementType ? (IStubFileElementType)type : null;
}
protected void reportStubAstMismatch(String message, StubTree stubTree, Document cachedDocument) {
rebuildStub();
clearStub(STUB_PSI_MISMATCH);
@@ -982,10 +984,10 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
if (tree == null) {
ApplicationManager.getApplication().assertReadAccessAllowed();
IElementType contentElementType = getContentElementType();
if (!(contentElementType instanceof IStubFileElementType)) {
IStubFileElementType contentElementType = getElementTypeForStubBuilder();
if (contentElementType == null) {
VirtualFile vFile = getVirtualFile();
String message = "ContentElementType: " + contentElementType + "; file: " + this +
String message = "ContentElementType: " + getContentElementType() + "; file: " + this +
"\n\t" + "Boolean.TRUE.equals(getUserData(BUILDING_STUB)) = " + Boolean.TRUE.equals(getUserData(BUILDING_STUB)) +
"\n\t" + "getTreeElement() = " + getTreeElement() +
"\n\t" + "vFile instanceof VirtualFileWithId = " + (vFile instanceof VirtualFileWithId) +
@@ -994,7 +996,7 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
throw new AssertionError(message);
}
StubElement currentStubTree = ((IStubFileElementType)contentElementType).getBuilder().buildStubTree(this);
StubElement currentStubTree = contentElementType.getBuilder().buildStubTree(this);
if (currentStubTree == null) {
throw new AssertionError("Stub tree wasn't built for " + contentElementType + "; file: " + this);
}
@@ -16,7 +16,6 @@
package com.intellij.psi.impl.source.codeStyle;
import com.intellij.lang.*;
import com.intellij.openapi.command.AbnormalCommandTerminationException;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.Key;
import com.intellij.psi.*;
@@ -125,7 +124,7 @@ public class CodeEditUtil {
public static void checkForOuters(ASTNode element) {
if (element instanceof OuterLanguageElement && element.getCopyableUserData(OUTER_OK) == null) {
throw new AbnormalCommandTerminationException();
throw new IllegalArgumentException("Outer element " + element + " is not allowed here");
}
ASTNode child = element.getFirstChildNode();
@@ -449,7 +449,9 @@ public class TreeUtil {
FileElement tree = file.getTreeElement();
assert tree != null : file;
final StubBuilder builder = ((IStubFileElementType)file.getContentElementType()).getBuilder();
final IStubFileElementType type = file.getElementTypeForStubBuilder();
assert type != null;
final StubBuilder builder = type.getBuilder();
tree.acceptTree(new RecursiveTreeElementWalkingVisitor() {
@Override
protected void visitNode(TreeElement node) {
@@ -25,7 +25,7 @@ import com.intellij.psi.tree.IFileElementType;
import com.intellij.psi.tree.IStubFileElementType;
public class CumulativeStubVersion {
private static final int VERSION = 28;
private static final int VERSION = 29;
public static int getCumulativeVersion() {
int version = VERSION;
@@ -17,6 +17,7 @@ package com.intellij.psi.stubs;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageParserDefinitions;
import com.intellij.lang.TreeBackedLighterAST;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.util.Key;
@@ -67,8 +68,6 @@ public class StubTreeBuilder {
}
else {
final LanguageFileType languageFileType = (LanguageFileType)fileType;
Language l = languageFileType.getLanguage();
final IFileElementType type = LanguageParserDefinitions.INSTANCE.forLanguage(l).getFileNodeType();
CharSequence contentAsText = inputData.getContentAsText();
FileContentImpl fileContent = (FileContentImpl)inputData;
@@ -76,14 +75,15 @@ public class StubTreeBuilder {
final FileViewProvider viewProvider = psi.getViewProvider();
psi = viewProvider.getStubBindingRoot();
psi.putUserData(IndexingDataKeys.FILE_TEXT_CONTENT_KEY, contentAsText);
final IStubFileElementType type = ((PsiFileImpl)psi).getElementTypeForStubBuilder();
// if we load AST, it should be easily gc-able. See PsiFileImpl.createTreeElementPointer()
psi.getManager().startBatchFilesProcessingMode();
try {
IStubFileElementType stubFileElementType;
if (type instanceof IStubFileElementType) {
stubFileElementType = (IStubFileElementType)type;
if (type != null) {
stubFileElementType = type;
}
else if (languageFileType instanceof SubstitutedFileType) {
SubstitutedFileType substituted = (SubstitutedFileType)languageFileType;
@@ -108,7 +108,11 @@ public class StubTreeBuilder {
for (Pair<IStubFileElementType, PsiFile> stubbedRoot : stubbedRoots) {
if (psi == stubbedRoot.second) continue;
final StubElement element = stubbedRoot.first.getBuilder().buildStubTree(stubbedRoot.second);
final StubBuilder stubbedRootBuilder = stubbedRoot.first.getBuilder();
if (stubbedRootBuilder instanceof LightStubBuilder) {
LightStubBuilder.FORCED_AST.set(new TreeBackedLighterAST(psi.getNode()));
}
final StubElement element = stubbedRootBuilder.buildStubTree(stubbedRoot.second);
if (element instanceof PsiFileStub) {
stubs.add((PsiFileStub)element);
}
@@ -142,9 +146,9 @@ public class StubTreeBuilder {
for (Language language : viewProvider.getLanguages()) {
final PsiFile file = viewProvider.getPsi(language);
if (file instanceof PsiFileImpl) {
final IElementType contentType = ((PsiFileImpl)file).getContentElementType();
if (contentType instanceof IStubFileElementType) {
roots.add(Trinity.create(language, (IStubFileElementType)contentType, file));
final IElementType type = ((PsiFileImpl)file).getElementTypeForStubBuilder();
if (type != null) {
roots.add(Trinity.create(language, (IStubFileElementType)type, file));
}
}
}
@@ -296,7 +296,7 @@ public class DvcsUtil {
}
public static void addMappingIfSubRoot(@NotNull Project project, @NotNull String newRepositoryPath, @NotNull String vcsName) {
if (FileUtil.isAncestor(project.getBasePath(), newRepositoryPath, true)) {
if (project.getBasePath() != null && FileUtil.isAncestor(project.getBasePath(), newRepositoryPath, true)) {
ProjectLevelVcsManager manager = ProjectLevelVcsManager.getInstance(project);
manager.setDirectoryMappings(VcsUtil.addMapping(manager.getDirectoryMappings(), newRepositoryPath, vcsName));
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 281 B

After

Width:  |  Height:  |  Size: 311 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 286 B

After

Width:  |  Height:  |  Size: 347 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 398 B

After

Width:  |  Height:  |  Size: 453 B

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