Merge remote-tracking branch 'origin/master'
@@ -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("<");
|
||||
|
||||
@@ -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(">");
|
||||
}
|
||||
|
||||
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("<");
|
||||
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("> ");
|
||||
}
|
||||
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 void <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> <a href="psi_element://Foo#Foo()">Foo()</a><br> <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> <a href="psi_element://Foo#Foo()">Foo()</a><br> <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 <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> <a href=\"psi_element://Time#Time()\">Time()</a><br> " +
|
||||
" <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));
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 281 B After Width: | Height: | Size: 311 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 286 B After Width: | Height: | Size: 347 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 398 B After Width: | Height: | Size: 453 B |