merge with master

This commit is contained in:
Evgeny Pasynkov
2012-06-25 12:00:18 +02:00
parent 77f8edbcf2
commit 33278f0c84
448 changed files with 9101 additions and 13350 deletions
@@ -831,13 +831,13 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
}
private SourceFileInfo(@NotNull DataInput in) throws IOException {
final int projCount = in.readInt();
final int projCount = DataInputOutputUtil.readINT(in);
for (int idx = 0; idx < projCount; idx++) {
final int projectId = in.readInt();
final long stamp = in.readLong();
final int projectId = DataInputOutputUtil.readINT(in);
final long stamp = DataInputOutputUtil.readTIME(in);
updateTimestamp(projectId, stamp);
final int pathsCount = in.readInt();
final int pathsCount = DataInputOutputUtil.readINT(in);
for (int i = 0; i < pathsCount; i++) {
final int path = in.readInt();
addOutputPath(projectId, path);
@@ -847,18 +847,18 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
public void save(@NotNull final DataOutput out) throws IOException {
final int[] projects = getProjectIds().toArray();
out.writeInt(projects.length);
DataInputOutputUtil.writeINT(out, projects.length);
for (int projectId : projects) {
out.writeInt(projectId);
out.writeLong(getTimestamp(projectId));
DataInputOutputUtil.writeINT(out, projectId);
DataInputOutputUtil.writeTIME(out, getTimestamp(projectId));
final Object value = myProjectToOutputPathMap != null? myProjectToOutputPathMap.get(projectId) : null;
if (value instanceof Integer) {
out.writeInt(1);
DataInputOutputUtil.writeINT(out, 1);
out.writeInt(((Integer)value).intValue());
}
else if (value instanceof TIntHashSet) {
final TIntHashSet set = (TIntHashSet)value;
out.writeInt(set.size());
DataInputOutputUtil.writeINT(out, set.size());
final IOException[] ex = new IOException[] {null};
set.forEach(new TIntProcedure() {
public boolean execute(final int value) {
@@ -877,7 +877,7 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
}
}
else {
out.writeInt(0);
DataInputOutputUtil.writeINT(out, 0);
}
}
}
@@ -29,8 +29,6 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.compiler.*;
import com.intellij.openapi.compiler.ex.CompileContextEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
@@ -51,7 +49,6 @@ public class ResourceCompiler implements TranslatingCompiler {
private final Project myProject;
private final CompilerConfiguration myConfiguration;
private final ResourceCompilerExtension[] myResourceCompilerExtensions = ResourceCompilerExtension.EP_NAME.getExtensions();
private static final FileTypeManager FILE_TYPE_MANAGER = FileTypeManager.getInstance();
public ResourceCompiler(Project project, CompilerConfiguration compilerConfiguration) {
myProject = project;
@@ -73,8 +70,7 @@ public class ResourceCompiler implements TranslatingCompiler {
if (module != null && skipStandardResourceCompiler(module)) {
return false;
}
return !StdFileTypes.JAVA.equals(file.getFileType()) && myConfiguration.isResourceFile(file);
return myConfiguration.isResourceFile(file);
}
public void compile(final CompileContext context, Chunk<Module> moduleChunk, final VirtualFile[] files, OutputSink sink) {
@@ -133,7 +133,7 @@ public class ChangedConstantsDependencyProcessor {
final Ref<CacheCorruptedException> exRef = new Ref<CacheCorruptedException>(null);
processIdentifiers(psiSearchHelper, new PsiElementProcessor<PsiIdentifier>() {
@Override
public boolean execute(@NotNull PsiIdentifier identifier) {
public synchronized boolean execute(@NotNull PsiIdentifier identifier) {
try {
final PsiElement parent = identifier.getParent();
if (parent instanceof PsiReferenceExpression) {
@@ -23,6 +23,7 @@ import com.intellij.openapi.roots.OrderEnumerator;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
@@ -30,6 +31,8 @@ import com.intellij.packaging.artifacts.ArtifactTemplate;
import com.intellij.packaging.elements.*;
import com.intellij.packaging.impl.elements.LibraryPackagingElement;
import com.intellij.packaging.impl.elements.ManifestFileUtil;
import com.intellij.packaging.impl.elements.ProductionModuleOutputElementType;
import com.intellij.packaging.impl.elements.TestModuleOutputElementType;
import com.intellij.util.CommonProcessors;
import com.intellij.util.PathUtil;
import com.intellij.util.Processor;
@@ -101,13 +104,16 @@ public class JarFromModulesTemplate extends ArtifactTemplate {
if (!includeTests) {
orderEnumerator = orderEnumerator.productionOnly();
}
final OrderEnumerator enumerator = orderEnumerator.using(myContext.getModulesProvider()).withoutSdk().runtimeOnly().recursively();
final ModulesProvider modulesProvider = myContext.getModulesProvider();
final OrderEnumerator enumerator = orderEnumerator.using(modulesProvider).withoutSdk().runtimeOnly().recursively();
enumerator.forEachLibrary(new CommonProcessors.CollectProcessor<Library>(libraries));
enumerator.forEachModule(new Processor<Module>() {
@Override
public boolean process(Module module) {
archive.addOrFindChild(factory.createModuleOutput(module));
if (includeTests) {
if (ProductionModuleOutputElementType.ELEMENT_TYPE.isSuitableModule(modulesProvider, module)) {
archive.addOrFindChild(factory.createModuleOutput(module));
}
if (includeTests && TestModuleOutputElementType.ELEMENT_TYPE.isSuitableModule(modulesProvider, module)) {
archive.addOrFindChild(factory.createTestModuleOutput(module));
}
return true;
@@ -20,6 +20,7 @@ import com.intellij.openapi.module.ModulePointer;
import com.intellij.openapi.module.ModulePointerManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.packaging.elements.CompositePackagingElement;
import com.intellij.packaging.elements.PackagingElement;
@@ -59,5 +60,16 @@ public abstract class ModuleOutputElementTypeBase<E extends ModuleOutputPackagin
protected abstract ModuleOutputPackagingElementBase createElement(@NotNull Project project, @NotNull ModulePointer pointer);
protected abstract List<Module> getSuitableModules(ArtifactEditorContext context);
private List<Module> getSuitableModules(ArtifactEditorContext context) {
ModulesProvider modulesProvider = context.getModulesProvider();
ArrayList<Module> modules = new ArrayList<Module>();
for (Module module : modulesProvider.getModules()) {
if (isSuitableModule(modulesProvider, module)) {
modules.add(module);
}
}
return modules;
}
public abstract boolean isSuitableModule(ModulesProvider modulesProvider, Module module);
}
@@ -21,12 +21,9 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModulePointer;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.packaging.ui.ArtifactEditorContext;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author nik
@@ -52,14 +49,8 @@ public class ProductionModuleOutputElementType extends ModuleOutputElementTypeBa
return AllIcons.Nodes.ModuleOpen;
}
protected List<Module> getSuitableModules(ArtifactEditorContext context) {
ArrayList<Module> modules = new ArrayList<Module>();
ModulesProvider modulesProvider = context.getModulesProvider();
for (Module module : modulesProvider.getModules()) {
if (modulesProvider.getRootModel(module).getSourceRootUrls(false).length > 0) {
modules.add(module);
}
}
return modules;
@Override
public boolean isSuitableModule(ModulesProvider modulesProvider, Module module) {
return modulesProvider.getRootModel(module).getSourceRootUrls(false).length > 0;
}
}
@@ -20,16 +20,12 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModulePointer;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModuleRootModel;
import com.intellij.openapi.roots.SourceFolder;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.packaging.ui.ArtifactEditorContext;
import com.intellij.util.PlatformIcons;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author nik
@@ -56,19 +52,8 @@ public class TestModuleOutputElementType extends ModuleOutputElementTypeBase<Tes
return PlatformIcons.TEST_SOURCE_FOLDER;
}
protected List<Module> getSuitableModules(ArtifactEditorContext context) {
ModulesProvider modulesProvider = context.getModulesProvider();
ArrayList<Module> modules = new ArrayList<Module>();
for (Module module : modulesProvider.getModules()) {
if (hasTestSourceRoots(modulesProvider.getRootModel(module))) {
modules.add(module);
}
}
return modules;
}
private static boolean hasTestSourceRoots(final ModuleRootModel rootModel) {
for (ContentEntry entry : rootModel.getContentEntries()) {
public boolean isSuitableModule(ModulesProvider modulesProvider, Module module) {
for (ContentEntry entry : modulesProvider.getRootModel(module).getContentEntries()) {
for (SourceFolder folder : entry.getSourceFolders()) {
if (folder.isTestSource()) return true;
}
@@ -50,26 +50,16 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
myClassName = name;
}
public MethodVisitor visitMethod(
final int access,
final String name,
final String desc,
final String signature,
final String[] exceptions) {
public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) {
final Type[] args = Type.getArgumentTypes(desc);
final Type returnType = Type.getReturnType(desc);
MethodVisitor v = cv.visitMethod(access,
name,
desc,
signature,
exceptions);
MethodVisitor v = cv.visitMethod(access, name, desc, signature, exceptions);
return new MethodVisitor(Opcodes.ASM4, v) {
private final ArrayList myNotNullParams = new ArrayList();
private int mySyntheticCount = 0;
private boolean myIsNotNull = false;
//private boolean myIsUnmodifiable = false;
public Label myThrowLabel;
//public Label myWrapLabel;
private Label myStartGeneratedCodeLabel;
@@ -78,9 +68,7 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
final String anno,
final boolean visible) {
AnnotationVisitor av;
av = mv.visitParameterAnnotation(parameter,
anno,
visible);
av = mv.visitParameterAnnotation(parameter, anno, visible);
if (isReferenceType(args[parameter]) && anno.equals(NOT_NULL_ANNO)) {
myNotNullParams.add(new Integer(parameter));
}
@@ -92,8 +80,7 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
return av;
}
public AnnotationVisitor visitAnnotation(String anno,
boolean isRuntime) {
public AnnotationVisitor visitAnnotation(String anno, boolean isRuntime) {
final AnnotationVisitor av = mv.visitAnnotation(anno, isRuntime);
if (isReferenceType(returnType) &&
anno.equals(NOT_NULL_ANNO)) {
@@ -119,8 +106,7 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
Label end = new Label();
mv.visitJumpInsn(IFNONNULL, end);
generateThrow(IAE_CLASS_NAME,
"Argument " + (param - mySyntheticCount) + " for @NotNull parameter of " + myClassName + "." + name + " must not be null", end);
generateThrow(IAE_CLASS_NAME, "Argument " + (param - mySyntheticCount) + " for @NotNull parameter of " + myClassName + "." + name + " must not be null", end);
}
}
@@ -137,17 +123,9 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
mv.visitInsn(DUP);
/*generateConditionalThrow("@NotNull method " + myClassName + "." + name + " must not return null",
"java/lang/IllegalStateException");*/
if (myThrowLabel == null) {
Label skipLabel = new Label();
mv.visitJumpInsn(IFNONNULL, skipLabel);
myThrowLabel = new Label();
mv.visitLabel(myThrowLabel);
generateThrow(ISE_CLASS_NAME, "@NotNull method " + myClassName + "." + name + " must not return null",
skipLabel);
}
else {
mv.visitJumpInsn(IFNULL, myThrowLabel);
}
final Label skipLabel = new Label();
mv.visitJumpInsn(IFNONNULL, skipLabel);
generateThrow(ISE_CLASS_NAME, "@NotNull method " + myClassName + "." + name + " must not return null", skipLabel);
}
}
@@ -159,10 +137,7 @@ public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcode
mv.visitTypeInsn(NEW, exceptionClass);
mv.visitInsn(DUP);
mv.visitLdcInsn(descr);
mv.visitMethodInsn(INVOKESPECIAL,
exceptionClass,
CONSTRUCTOR_NAME,
exceptionParamClass);
mv.visitMethodInsn(INVOKESPECIAL, exceptionClass, CONSTRUCTOR_NAME, exceptionParamClass);
mv.visitInsn(ATHROW);
mv.visitLabel(end);
@@ -237,7 +237,14 @@ public class ThreadDumpAction extends AnAction implements AnAction.TransparentUp
}
public static String renderObject(ObjectReference monitor) {
return DebuggerBundle.message("threads.export.attribute.label.object-id", Long.toHexString(monitor.uniqueID()), monitor.referenceType().name());
String monitorTypeName;
try {
monitorTypeName = monitor.referenceType().name();
}
catch (Throwable e) {
monitorTypeName = "Error getting object type: '" + e.getMessage() + "'";
}
return DebuggerBundle.message("threads.export.attribute.label.object-id", Long.toHexString(monitor.uniqueID()), monitorTypeName);
}
private static String threadStatusToJavaThreadState(int status) {
@@ -287,7 +294,7 @@ public class ThreadDumpAction extends AnAction implements AnAction.TransparentUp
try {
sourceName = location.sourceName();
}
catch (AbsentInformationException e) {
catch (Throwable e) {
sourceName = "Unknown Source";
}
return DebuggerBundle.message(
@@ -107,6 +107,8 @@ public class DebuggerSession implements AbstractDebuggerSession {
private final Set<ThreadReferenceProxyImpl> mySteppingThroughThreads = new HashSet<ThreadReferenceProxyImpl>();
protected final Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
private boolean myModifiedClassesScanRequired = false;
public boolean isSteppingThrough(ThreadReferenceProxyImpl threadProxy) {
return mySteppingThroughThreads.contains(threadProxy);
}
@@ -117,6 +119,14 @@ public class DebuggerSession implements AbstractDebuggerSession {
return mySearchScope;
}
public boolean isModifiedClassesScanRequired() {
return myModifiedClassesScanRequired;
}
public void setModifiedClassesScanRequired(boolean modifiedClassesScanRequired) {
myModifiedClassesScanRequired = modifiedClassesScanRequired;
}
private class MyDebuggerStateManager extends DebuggerStateManager {
private DebuggerContextImpl myDebuggerContext;
@@ -32,7 +32,10 @@ import com.sun.jdi.ReferenceType;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.util.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author lex
@@ -149,13 +149,42 @@ public class HotSwapUIImpl extends HotSwapUI implements ProjectComponent{
final boolean isOutOfProcessMode = CompilerWorkspaceConfiguration.getInstance(myProject).useOutOfProcessBuild();
final boolean shouldPerformScan = !isOutOfProcessMode || generatedPaths == null;
final HotSwapProgressImpl findClassesProgress = shouldPerformScan ? new HotSwapProgressImpl(myProject) : null;
final HotSwapProgressImpl findClassesProgress;
if (shouldPerformScan) {
findClassesProgress = new HotSwapProgressImpl(myProject);
}
else {
boolean createProgress = false;
for (DebuggerSession session : sessions) {
if (session.isModifiedClassesScanRequired()) {
createProgress = true;
break;
}
}
findClassesProgress = createProgress? new HotSwapProgressImpl(myProject) : null;
}
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
public void run() {
final Map<DebuggerSession, Map<String, HotSwapFile>> modifiedClasses = shouldPerformScan?
scanForModifiedClassesWithProgress(sessions, findClassesProgress, !isOutOfProcessMode) :
HotSwapManager.findModifiedClasses(sessions, generatedPaths);
final Map<DebuggerSession, Map<String, HotSwapFile>> modifiedClasses;
if (shouldPerformScan) {
modifiedClasses = scanForModifiedClassesWithProgress(sessions, findClassesProgress, !isOutOfProcessMode);
}
else {
final List<DebuggerSession> toScan = new ArrayList<DebuggerSession>();
final List<DebuggerSession> toUseGenerated = new ArrayList<DebuggerSession>();
for (DebuggerSession session : sessions) {
(session.isModifiedClassesScanRequired()? toScan : toUseGenerated).add(session);
session.setModifiedClassesScanRequired(false);
}
modifiedClasses = new HashMap<DebuggerSession, Map<String, HotSwapFile>>();
if (!toUseGenerated.isEmpty()) {
modifiedClasses.putAll(HotSwapManager.findModifiedClasses(toUseGenerated, generatedPaths));
}
if (!toScan.isEmpty()) {
modifiedClasses.putAll(scanForModifiedClassesWithProgress(toScan, findClassesProgress, !isOutOfProcessMode));
}
}
final Application application = ApplicationManager.getApplication();
if (modifiedClasses.isEmpty()) {
@@ -170,9 +199,18 @@ public class HotSwapUIImpl extends HotSwapUI implements ProjectComponent{
final RunHotswapDialog dialog = new RunHotswapDialog(myProject, sessions, shouldDisplayHangWarning);
dialog.show();
if (!dialog.isOK()) {
for (DebuggerSession session : modifiedClasses.keySet()) {
session.setModifiedClassesScanRequired(true);
}
return;
}
modifiedClasses.keySet().retainAll(dialog.getSessionsToReload());
final Set<DebuggerSession> toReload = new HashSet<DebuggerSession>(dialog.getSessionsToReload());
for (DebuggerSession session : modifiedClasses.keySet()) {
if (!toReload.contains(session)) {
session.setModifiedClassesScanRequired(true);
}
}
modifiedClasses.keySet().retainAll(toReload);
}
else {
if (shouldDisplayHangWarning) {
@@ -191,6 +229,9 @@ public class HotSwapUIImpl extends HotSwapUI implements ProjectComponent{
}
);
if (answer == DialogWrapper.CANCEL_EXIT_CODE) {
for (DebuggerSession session : modifiedClasses.keySet()) {
session.setModifiedClassesScanRequired(true);
}
return;
}
}
@@ -199,11 +199,11 @@ public class DebuggerTreeRenderer extends ColoredTreeCellRenderer {
final String errorMessage = exception.getMessage();
if(valueLabel.endsWith(errorMessage)) {
descriptorText.append(valueLabel.substring(0, valueLabel.length() - errorMessage.length()), DEFAULT_ATTRIBUTES);
appendValueTextWithEscapesRendering(descriptorText, valueLabel.substring(0, valueLabel.length() - errorMessage.length()), DEFAULT_ATTRIBUTES);
descriptorText.append(errorMessage, XDebuggerUIConstants.EXCEPTION_ATTRIBUTES);
}
else {
descriptorText.append(valueLabel, valueDescriptor.isDirty() ? XDebuggerUIConstants.CHANGED_VALUE_ATTRIBUTES : DEFAULT_ATTRIBUTES);
appendValueTextWithEscapesRendering(descriptorText, valueLabel, valueDescriptor.isDirty() ? XDebuggerUIConstants.CHANGED_VALUE_ATTRIBUTES : DEFAULT_ATTRIBUTES);
descriptorText.append(errorMessage, XDebuggerUIConstants.EXCEPTION_ATTRIBUTES);
}
}
@@ -212,7 +212,7 @@ public class DebuggerTreeRenderer extends ColoredTreeCellRenderer {
descriptorText.append(XDebuggerUIConstants.COLLECTING_DATA_MESSAGE, XDebuggerUIConstants.COLLECTING_DATA_HIGHLIGHT_ATTRIBUTES);
}
else {
descriptorText.append(valueLabel, valueDescriptor.isDirty() ? XDebuggerUIConstants.CHANGED_VALUE_ATTRIBUTES : DEFAULT_ATTRIBUTES);
appendValueTextWithEscapesRendering(descriptorText, valueLabel, valueDescriptor.isDirty() ? XDebuggerUIConstants.CHANGED_VALUE_ATTRIBUTES : DEFAULT_ATTRIBUTES);
}
}
}
@@ -225,6 +225,42 @@ public class DebuggerTreeRenderer extends ColoredTreeCellRenderer {
return descriptorText;
}
private static void appendValueTextWithEscapesRendering(SimpleColoredText descriptorText, String valueText, final SimpleTextAttributes attribs) {
final SimpleTextAttributes boldAttribs = attribs.derive(SimpleTextAttributes.STYLE_BOLD, null, Color.lightGray, null);
final StringBuilder buf = new StringBuilder();
boolean slashFound = false;
for (int idx= 0; idx < valueText.length(); idx++) {
final char ch = valueText.charAt(idx);
if (slashFound) {
slashFound = false;
if (ch == '\\' || ch == '\"' || ch == 'b'|| ch == 't'|| ch == 'n'|| ch == 'f'|| ch == 'r' ) {
if (buf.length() > 0) {
descriptorText.append(buf.toString(), attribs);
buf.setLength(0);
}
if (ch != '\\' && ch != '\"') {
descriptorText.append("\\", boldAttribs);
}
descriptorText.append(String.valueOf(ch), boldAttribs);
}
else {
buf.append('\\').append(ch);
}
}
else {
if (ch == '\\') {
slashFound = true;
}
else {
buf.append(ch);
}
}
}
if (buf.length() > 0) {
descriptorText.append(buf.toString(), attribs);
}
}
private static String[] breakString(String source, String substr) {
if (substr != null && substr.length() > 0) {
int index = Math.max(source.indexOf(substr), 0);
@@ -12,9 +12,7 @@
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<haveBorder value="false"/>
</properties>
<properties/>
<border type="none"/>
<children>
<grid id="452da" layout-manager="GridLayoutManager" row-count="6" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
@@ -176,7 +174,7 @@
<clientProperties>
<BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithoutIndent"/>
</clientProperties>
<border type="etched" title-resource-bundle="messages/ApplicationBundle" title-key="title.order.of.members"/>
<border type="none" title-resource-bundle="messages/ApplicationBundle" title-key="title.order.of.members"/>
<children/>
</grid>
<vspacer id="91133">
@@ -13,7 +13,6 @@
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<haveBorder value="false"/>
</properties>
<border type="none"/>
<children>
@@ -158,9 +158,11 @@ public class AllClassesGetter {
}).forEach(new Processor<PsiClass>() {
public boolean process(PsiClass psiClass) {
assert psiClass != null;
if (isSuitable(context, packagePrefix, qnames, psiClass, filterByScope, pkgContext)) {
qnames.add(psiClass.getQualifiedName());
consumer.consume(psiClass);
if (isAcceptableInContext(context, psiClass, filterByScope, pkgContext)) {
String qName = psiClass.getQualifiedName();
if (qName != null && qName.startsWith(packagePrefix) && qnames.add(qName)) {
consumer.consume(psiClass);
}
}
return true;
}
@@ -181,9 +183,9 @@ public class AllClassesGetter {
return j > 0 ? prefix.substring(0, j) : "";
}
private static boolean isSuitable(@NotNull final PsiElement context, final String packagePrefix, final Set<String> qnames,
@NotNull final PsiClass psiClass,
final boolean filterByScope, final boolean pkgContext) {
public static boolean isAcceptableInContext(@NotNull final PsiElement context,
@NotNull final PsiClass psiClass,
final boolean filterByScope, final boolean pkgContext) {
ProgressManager.checkCanceled();
if (!context.isValid() || !psiClass.isValid()) return false;
@@ -191,9 +193,7 @@ public class AllClassesGetter {
if (JavaCompletionUtil.isInExcludedPackage(psiClass, false)) return false;
final String qualifiedName = psiClass.getQualifiedName();
if (qualifiedName == null || !qualifiedName.startsWith(packagePrefix)) return false;
if (qnames.contains(qualifiedName)) return false;
if (qualifiedName == null) return false;
if (!filterByScope && !(psiClass instanceof PsiCompiledElement)) return true;
@@ -44,9 +44,7 @@ public class InheritorsHolder implements Consumer<LookupElement> {
public void consume(LookupElement lookupElement) {
final Object object = lookupElement.getObject();
if (object instanceof PsiClass) {
final PsiClass psiClass = (PsiClass)object;
if (JavaCompletionUtil.hasAccessibleInnerClass(psiClass, myPosition)) return;
registerClass(psiClass);
registerClass((PsiClass)object);
}
myResult.addElement(AutoCompletionPolicy.NEVER_AUTOCOMPLETE.applyPolicy(lookupElement));
}
@@ -19,12 +19,12 @@ import com.intellij.codeInsight.ExpectedTypeInfo;
import com.intellij.codeInsight.ExpectedTypesProvider;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.lang.LangBundle;
import com.intellij.lang.StdLanguages;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.patterns.PsiJavaElementPattern;
import com.intellij.patterns.PsiJavaPatterns;
import com.intellij.psi.*;
import com.intellij.psi.filters.ClassFilter;
import com.intellij.psi.filters.ElementFilter;
@@ -35,15 +35,18 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.Consumer;
import com.intellij.util.ProcessingContext;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import static com.intellij.patterns.PsiJavaPatterns.psiElement;
/**
* @author peter
*/
public class JavaClassNameCompletionContributor extends CompletionContributor {
private static final PsiJavaElementPattern.Capture<PsiElement> AFTER_NEW = psiElement().afterLeaf(PsiKeyword.NEW);
public static final PsiJavaElementPattern.Capture<PsiElement> AFTER_NEW = psiElement().afterLeaf(PsiKeyword.NEW);
private static final PsiJavaElementPattern.Capture<PsiElement> IN_TYPE_PARAMETER =
psiElement().afterLeaf(PsiKeyword.EXTENDS, PsiKeyword.SUPER, "&").withParent(
psiElement(PsiReferenceList.class).withParent(PsiTypeParameter.class));
@@ -92,7 +95,8 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
}
final boolean inJavaContext = parameters.getPosition() instanceof PsiIdentifier;
if (AFTER_NEW.accepts(insertedElement)) {
final boolean afterNew = AFTER_NEW.accepts(insertedElement);
if (afterNew) {
final PsiExpression expr = PsiTreeUtil.getContextOfType(insertedElement, PsiExpression.class, true);
for (final ExpectedTypeInfo info : ExpectedTypesProvider.getExpectedTypes(expr, true)) {
final PsiType type = info.getType();
@@ -104,20 +108,34 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
if (!defaultType.equals(type)) {
final PsiClass defClass = PsiUtil.resolveClassInType(defaultType);
if (defClass != null) {
consumer.consume(createClassLookupItem(defClass, inJavaContext));
consumer.consume(createClassLookupItem(defClass, true));
}
}
}
}
final boolean lookingForAnnotations = PsiJavaPatterns.psiElement().afterLeaf("@").accepts(insertedElement);
final boolean lookingForAnnotations = psiElement().afterLeaf("@").accepts(insertedElement);
final boolean pkgContext = JavaCompletionUtil.inSomePackage(insertedElement);
AllClassesGetter.processJavaClasses(parameters, matcher, filterByScope, new Consumer<PsiClass>() {
@Override
public void consume(PsiClass psiClass) {
if (lookingForAnnotations && !psiClass.isAnnotationType()) return;
if (filter.isAcceptable(psiClass, insertedElement)) {
consumer.consume(createClassLookupItem(psiClass, inJavaContext));
if (!inJavaContext) {
consumer.consume(AllClassesGetter.createLookupItem(psiClass, AllClassesGetter.TRY_SHORTENING));
} else {
for (JavaPsiClassReferenceElement element : createClassLookupItems(psiClass, afterNew,
JavaClassNameInsertHandler.JAVA_CLASS_INSERT_HANDLER, new Condition<PsiClass>() {
@Override
public boolean value(PsiClass psiClass) {
return filter.isAcceptable(psiClass, insertedElement) &&
AllClassesGetter.isAcceptableInContext(insertedElement, psiClass, filterByScope, pkgContext);
}
})) {
consumer.consume(element);
}
}
}
}
});
@@ -128,6 +146,31 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
: AllClassesGetter.TRY_SHORTENING);
}
public static List<JavaPsiClassReferenceElement> createClassLookupItems(final PsiClass psiClass,
boolean withInners,
InsertHandler<JavaPsiClassReferenceElement> insertHandler,
Condition<PsiClass> condition) {
List<JavaPsiClassReferenceElement> result = new SmartList<JavaPsiClassReferenceElement>();
if (condition.value(psiClass)) {
result.add(AllClassesGetter.createLookupItem(psiClass, insertHandler));
}
String name = psiClass.getName();
if (withInners && name != null) {
for (PsiClass inner : psiClass.getInnerClasses()) {
if (inner.hasModifierProperty(PsiModifier.STATIC)) {
for (JavaPsiClassReferenceElement lookupInner : createClassLookupItems(inner, withInners, insertHandler, condition)) {
String forced = lookupInner.getForcedPresentableName();
lookupInner.setForcedPresentableName(name + "." + (forced != null ? forced : inner.getName()));
result.add(lookupInner);
}
}
}
}
return result;
}
@Override
public String handleEmptyLookup(@NotNull final CompletionParameters parameters, final Editor editor) {
if (!(parameters.getOriginalFile() instanceof PsiJavaFile)) return null;
@@ -145,6 +188,6 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
private static boolean shouldShowSecondSmartCompletionHint(final CompletionParameters parameters) {
return parameters.getCompletionType() == CompletionType.CLASS_NAME &&
parameters.getInvocationCount() == 1 &&
parameters.getOriginalFile().getLanguage() == StdLanguages.JAVA;
parameters.getOriginalFile().getLanguage().isKindOf(JavaLanguage.INSTANCE);
}
}
@@ -32,9 +32,6 @@ import com.intellij.psi.filters.FilterPositionUtil;
import com.intellij.psi.javadoc.PsiDocTag;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.containers.hash.HashSet;
import java.util.Set;
/**
* @author peter
@@ -91,8 +88,9 @@ class JavaClassNameInsertHandler implements InsertHandler<JavaPsiClassReferenceE
}
PsiTypeLookupItem.addImportForItem(context, psiClass);
context.setTailOffset(context.getOffset(refEnd));
if (shouldInsertParentheses(psiClass, file.findElementAt(context.getTailOffset() - 1))) {
if (shouldInsertParentheses(file.findElementAt(context.getTailOffset() - 1))) {
if (ConstructorInsertHandler.insertParentheses(context, item, psiClass, false)) {
fillTypeArgs |= psiClass.hasTypeParameters() && PsiUtil.getLanguageLevel(file).isAtLeast(LanguageLevel.JDK_1_5);
}
@@ -122,7 +120,7 @@ class JavaClassNameInsertHandler implements InsertHandler<JavaPsiClassReferenceE
}
}
private static boolean shouldInsertParentheses(PsiClass psiClass, PsiElement position) {
private static boolean shouldInsertParentheses(PsiElement position) {
final PsiJavaCodeReferenceElement ref = PsiTreeUtil.getParentOfType(position, PsiJavaCodeReferenceElement.class);
if (ref == null) {
return false;
@@ -135,13 +133,13 @@ class JavaClassNameInsertHandler implements InsertHandler<JavaPsiClassReferenceE
final PsiElement prevElement = FilterPositionUtil.searchNonSpaceNonCommentBack(ref);
if (prevElement != null && prevElement.getParent() instanceof PsiNewExpression) {
Set<PsiType> expectedTypes = new HashSet<PsiType>();
for (ExpectedTypeInfo info : ExpectedTypesProvider.getExpectedTypes((PsiExpression)prevElement.getParent(), true)) {
expectedTypes.add(info.getType());
if (info.getType() instanceof PsiArrayType) {
return false;
}
}
return JavaCompletionUtil.isDefinitelyExpected(psiClass, expectedTypes, position);
return true;
}
return false;
@@ -31,6 +31,7 @@ import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.patterns.ElementPattern;
@@ -282,12 +283,14 @@ public class JavaCompletionContributor extends CompletionContributor {
final Set<String> usedWords = new HashSet<String>();
final PsiElement position = parameters.getPosition();
final boolean checkAccess = parameters.getInvocationCount() <= 1;
final boolean isSwitchLabel = SWITCH_LABEL.accepts(position);
final boolean isAfterNew = JavaClassNameCompletionContributor.AFTER_NEW.accepts(position);
final boolean pkgContext = JavaCompletionUtil.inSomePackage(position);
LegacyCompletionContributor.processReferences(parameters, result, new PairConsumer<PsiReference, CompletionResultSet>() {
public void consume(final PsiReference reference, final CompletionResultSet result) {
if (reference instanceof PsiJavaReference) {
final ElementFilter filter = getReferenceFilter(position);
if (filter != null) {
final boolean isSwitchLabel = SWITCH_LABEL.accepts(position);
final PsiFile originalFile = parameters.getOriginalFile();
for (LookupElement element : JavaCompletionUtil.processJavaReference(position,
(PsiJavaReference)reference,
@@ -332,11 +335,17 @@ public class JavaCompletionContributor extends CompletionContributor {
result.addElement((LookupElement)completion);
}
else if (completion instanceof PsiClass) {
if (!inheritors.alreadyProcessed((PsiClass)completion)) {
JavaPsiClassReferenceElement item = JavaClassNameCompletionContributor.createClassLookupItem((PsiClass)completion, true);
for (JavaPsiClassReferenceElement item : JavaClassNameCompletionContributor.createClassLookupItems((PsiClass)completion, isAfterNew,
JavaClassNameInsertHandler.JAVA_CLASS_INSERT_HANDLER, new Condition<PsiClass>() {
@Override
public boolean value(PsiClass psiClass) {
return !inheritors.alreadyProcessed(psiClass) && JavaCompletionUtil.isSourceLevelAccessible(position, psiClass, pkgContext);
}
})) {
usedWords.add(item.getLookupString());
result.addElement(item);
}
}
else {
LookupElement element = LookupItemUtil.objectToLookupItem(completion);
@@ -69,10 +69,7 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import static com.intellij.patterns.PlatformPatterns.psiElement;
@@ -419,9 +416,9 @@ public class JavaCompletionUtil {
}
public static Set<LookupElement> processJavaReference(PsiElement element, PsiJavaReference javaReference, ElementFilter elementFilter,
final boolean checkAccess, boolean filterStaticAfterInstance, @Nullable final PrefixMatcher matcher, CompletionParameters parameters) {
final boolean checkAccess, boolean filterStaticAfterInstance, final PrefixMatcher matcher, CompletionParameters parameters) {
final THashSet<LookupElement> set = new THashSet<LookupElement>();
final Condition<String> nameCondition = matcher == null ? null : new Condition<String>() {
final Condition<String> nameCondition = new Condition<String>() {
public boolean value(String s) {
return matcher.prefixMatches(s);
}
@@ -450,8 +447,7 @@ public class JavaCompletionUtil {
final Set<PsiMember> mentioned = new THashSet<PsiMember>();
for (CompletionElement completionElement : processor.getResults()) {
LookupElement item = createLookupElement(completionElement, javaReference);
if (item != null) {
for (LookupElement item : createLookupElements(completionElement, javaReference)) {
item.putUserData(QUALIFIER_TYPE_ATTR, qualifierType);
final Object o = item.getObject();
if (o instanceof PsiClass && !isSourceLevelAccessible(element, (PsiClass)o, pkgContext)) {
@@ -604,25 +600,33 @@ public class JavaCompletionUtil {
}), 1);
}
private static LookupElement createLookupElement(CompletionElement completionElement, PsiJavaReference reference) {
private static List<? extends LookupElement> createLookupElements(CompletionElement completionElement, PsiJavaReference reference) {
Object completion = completionElement.getElement();
assert !(completion instanceof LookupElement);
if (completion instanceof PsiMethod &&
reference instanceof PsiJavaCodeReferenceElement &&
((PsiJavaCodeReferenceElement)reference).getParent() instanceof PsiImportStaticStatement) {
return JavaLookupElementBuilder.forMethod((PsiMethod)completion, PsiSubstitutor.EMPTY);
if (reference instanceof PsiJavaCodeReferenceElement) {
if (completion instanceof PsiMethod &&
((PsiJavaCodeReferenceElement)reference).getParent() instanceof PsiImportStaticStatement) {
return Arrays.asList(JavaLookupElementBuilder.forMethod((PsiMethod)completion, PsiSubstitutor.EMPTY));
}
if (completion instanceof PsiClass) {
return JavaClassNameCompletionContributor.createClassLookupItems((PsiClass)completion,
JavaClassNameCompletionContributor.AFTER_NEW.accepts(reference),
JavaClassNameInsertHandler.JAVA_CLASS_INSERT_HANDLER,
Condition.TRUE);
}
}
LookupElement _ret = LookupItemUtil.objectToLookupItem(completion);
if (_ret == null || !(_ret instanceof LookupItem)) return null;
if (_ret == null || !(_ret instanceof LookupItem)) return Collections.emptyList();
final PsiSubstitutor substitutor = completionElement.getSubstitutor();
if (substitutor != null) {
((LookupItem<?>)_ret).setAttribute(LookupItem.SUBSTITUTOR, substitutor);
}
return _ret;
return Arrays.asList(_ret);
}
public static boolean hasAccessibleConstructor(PsiType type) {
@@ -878,19 +882,6 @@ public class JavaCompletionUtil {
}
}
public static boolean hasAccessibleInnerClass(@NotNull PsiClass psiClass, @NotNull PsiElement position) {
final PsiClass[] inners = psiClass.getInnerClasses();
if (inners.length > 0) {
PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(position.getProject()).getResolveHelper();
for (PsiClass inner : inners) {
if (inner.hasModifierProperty(PsiModifier.STATIC) && resolveHelper.isAccessible(inner, position, null)) {
return true;
}
}
}
return false;
}
public static boolean inSomePackage(PsiElement context) {
PsiFile contextFile = context.getContainingFile();
return contextFile instanceof PsiClassOwner && StringUtil.isNotEmpty(((PsiClassOwner)contextFile).getPackageName());
@@ -914,19 +905,6 @@ public class JavaCompletionUtil {
return true;
}
public static boolean isDefinitelyExpected(PsiClass psiClass, Set<PsiType> expectedTypes, PsiElement position) {
final PsiClassType classType = JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(psiClass);
for (PsiType expectedType : expectedTypes) {
if (expectedType instanceof PsiArrayType) return false;
}
for (PsiType type : expectedTypes) {
if (type instanceof PsiClassType && ((PsiClassType)type).rawType().isAssignableFrom(classType)) {
return true;
}
}
return !hasAccessibleInnerClass(psiClass, position);
}
public static boolean promptTypeArgs(InsertionContext context, int offset) {
if (offset < 0) {
return false;
@@ -31,6 +31,9 @@ import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.Set;
/**
* @author peter
*/
@@ -38,6 +41,7 @@ public class JavaPsiClassReferenceElement extends LookupItem<Object> {
public static final ClassConditionKey<JavaPsiClassReferenceElement> CLASS_CONDITION_KEY = ClassConditionKey.create(JavaPsiClassReferenceElement.class);
private final Object myClass;
private final String myQualifiedName;
private String myForcedPresentableName;
public JavaPsiClassReferenceElement(PsiClass psiClass) {
super(psiClass.getName(), psiClass.getName());
@@ -48,6 +52,32 @@ public class JavaPsiClassReferenceElement extends LookupItem<Object> {
setTailType(TailType.NONE);
}
public String getForcedPresentableName() {
return myForcedPresentableName;
}
@NotNull
@Override
public String getLookupString() {
if (myForcedPresentableName != null) {
return myForcedPresentableName;
}
return super.getLookupString();
}
@Override
public Set<String> getAllLookupStrings() {
if (myForcedPresentableName != null) {
return Collections.singleton(myForcedPresentableName);
}
return super.getAllLookupStrings();
}
public void setForcedPresentableName(String forcedPresentableName) {
myForcedPresentableName = forcedPresentableName;
}
@NotNull
@Override
public PsiClass getObject() {
@@ -126,6 +156,13 @@ public class JavaPsiClassReferenceElement extends LookupItem<Object> {
}
private static String getName(final PsiClass psiClass, final LookupItem<?> item, boolean diamond) {
if (item instanceof JavaPsiClassReferenceElement) {
String forced = ((JavaPsiClassReferenceElement)item).getForcedPresentableName();
if (forced != null) {
return forced;
}
}
String name = PsiUtilCore.getName(psiClass);
if (item.getAttribute(LookupItem.FORCE_QUALIFY) != null) {
@@ -388,7 +388,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
final ElementFilter filter,
final boolean acceptClasses,
final boolean acceptMembers,
CompletionParameters parameters, @Nullable final PrefixMatcher matcher) {
CompletionParameters parameters, final PrefixMatcher matcher) {
if (reference instanceof PsiMultiReference) {
reference = ContainerUtil.findInstance(((PsiMultiReference) reference).getReferences(), PsiJavaReference.class);
}
@@ -138,7 +138,7 @@ public class ReferenceExpressionCompletionContributor {
final boolean secondTime = parameters.getParameters().getInvocationCount() >= 2;
final Set<LookupElement> base =
JavaSmartCompletionContributor.completeReference(element, reference, filter, false, true, parameters.getParameters(), null);
JavaSmartCompletionContributor.completeReference(element, reference, filter, false, true, parameters.getParameters(), PrefixMatcher.ALWAYS_TRUE);
for (final LookupElement item : new LinkedHashSet<LookupElement>(base)) {
ExpressionLookupItem access = getSingleArrayElementAccess(element, item);
if (access != null) {
@@ -200,7 +200,7 @@ public class ReferenceExpressionCompletionContributor {
public boolean isClassAcceptable(Class hintClass) {
return true;
}
}), false, true, parameters.getParameters(), null);
}), false, true, parameters.getParameters(), PrefixMatcher.ALWAYS_TRUE);
for (LookupElement lookupElement : elements) {
if (lookupElement.getObject() instanceof PsiMethod) {
final JavaMethodCallElement item = lookupElement.as(JavaMethodCallElement.CLASS_CONDITION_KEY);
@@ -122,18 +122,18 @@ public abstract class StaticMemberProcessor {
}
}
public List<PsiMember> processMembersOfRegisteredClasses(@Nullable final PrefixMatcher matcher, PairConsumer<PsiMember, PsiClass> consumer) {
public List<PsiMember> processMembersOfRegisteredClasses(final PrefixMatcher matcher, PairConsumer<PsiMember, PsiClass> consumer) {
final ArrayList<PsiMember> result = CollectionFactory.arrayList();
for (final PsiClass psiClass : myStaticImportedClasses) {
for (final PsiMethod method : psiClass.getAllMethods()) {
if (matcher == null || matcher.prefixMatches(method.getName())) {
if (matcher.prefixMatches(method.getName())) {
if (isStaticallyImportable(method)) {
consumer.consume(method, psiClass);
}
}
}
for (final PsiField field : psiClass.getAllFields()) {
if (matcher == null || matcher.prefixMatches(field. getName())) {
if (matcher.prefixMatches(field. getName())) {
if (isStaticallyImportable(field)) {
consumer.consume(field, psiClass);
}
@@ -143,7 +143,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
myInLibrary = fileIndex.isInLibraryClasses(virtualFile) || fileIndex.isInLibrarySource(virtualFile);
myRefCountHolder = RefCountHolder.endUsing(myFile);
if (!myRefCountHolder.retrieveUnusedReferencesInfo(new Runnable() {
if (myRefCountHolder == null || !myRefCountHolder.retrieveUnusedReferencesInfo(new Runnable() {
@Override
public void run() {
boolean errorFound = collectHighlights(elementSet, highlights, progress);
@@ -650,8 +650,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
final PsiClass containingClass = member.getContainingClass();
if (containingClass == null || !(containingClass instanceof PsiClassImpl)) return true;
final PsiMethod valuesMethod = ((PsiClassImpl)containingClass).getValuesMethod();
if (valuesMethod == null) return true;
return isMethodReferenced(valuesMethod, progress, helper);
return valuesMethod == null || isMethodReferenced(valuesMethod, progress, helper);
}
private static boolean canBeReferencedViaWeirdNames(PsiMember member) {
@@ -28,7 +28,9 @@ import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.BidirectionalMap;
import com.intellij.util.containers.ConcurrentHashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.ref.SoftReference;
import java.util.Iterator;
@@ -65,17 +67,17 @@ public class RefCountHolder {
private void makeHardReachable(boolean isHard) {
RefCountHolder holder = get();
assert holder != null;
assert !isHard || holder != null : "hard: "+isHard +"; holder="+holder;
myHardRef = isHard ? holder : null;
}
}
private static final Key<HolderReference> REF_COUNT_HOLDER_IN_FILE_KEY = Key.create("REF_COUNT_HOLDER_IN_FILE_KEY");
@NotNull
private static Pair<RefCountHolder, HolderReference> getInstance(@NotNull PsiFile file) {
private static Pair<RefCountHolder, HolderReference> getInstance(@NotNull PsiFile file, boolean create) {
HolderReference ref = file.getUserData(REF_COUNT_HOLDER_IN_FILE_KEY);
RefCountHolder holder = ref == null ? null : ref.get();
if (holder == null) {
if (holder == null && create) {
holder = new RefCountHolder(file);
HolderReference newRef = new HolderReference(holder);
while (true) {
@@ -97,21 +99,26 @@ public class RefCountHolder {
@NotNull
public static RefCountHolder startUsing(@NotNull PsiFile file) {
Pair<RefCountHolder, HolderReference> pair = getInstance(file);
Pair<RefCountHolder, HolderReference> pair = getInstance(file, true);
HolderReference reference = pair.second;
reference.makeHardReachable(true); // make sure RefCountHolder won't be gced during highlighting
log("startUsing: " + pair.first.myState+" for "+file);
return pair.first;
}
@NotNull
@Nullable("might be gced")
public static RefCountHolder endUsing(@NotNull PsiFile file) {
Pair<RefCountHolder, HolderReference> pair = getInstance(file);
Pair<RefCountHolder, HolderReference> pair = getInstance(file, false);
HolderReference reference = pair.second;
reference.makeHardReachable(false); // no longer needed, can be cleared
return pair.first;
RefCountHolder holder = pair.first;
log("endUsing: " + (holder == null ? null : holder.myState)+" for "+file);
return holder;
}
private RefCountHolder(@NotNull PsiFile file) {
myFile = file;
log("c: created: " + myState.get()+" for "+file);
}
private void clear() {
@@ -267,10 +274,13 @@ public class RefCountHolder {
}
public boolean analyze(@NotNull PsiFile file, TextRange dirtyScope, @NotNull Runnable analyze) {
State old = myState.get();
myState.compareAndSet(State.READY, State.VIRGIN);
if (!myState.compareAndSet(State.VIRGIN, State.BEING_WRITTEN_BY_GHP)) {
log("a: failed to change " + old + "->" + State.BEING_WRITTEN_BY_GHP);
return false;
}
log("a: changed " + old + "->" + State.BEING_WRITTEN_BY_GHP);
boolean finished = false;
try {
if (dirtyScope != null) {
@@ -288,20 +298,29 @@ public class RefCountHolder {
finally {
boolean set = myState.compareAndSet(State.BEING_WRITTEN_BY_GHP, finished ? State.READY : State.VIRGIN);
assert set : myState.get();
log("a: changed back " + State.BEING_WRITTEN_BY_GHP + "->" + (finished ? State.READY : State.VIRGIN));
}
return true;
}
private static void log(@NonNls String s) {
//System.err.println("RFC: "+s);
}
public boolean retrieveUnusedReferencesInfo(@NotNull Runnable analyze) {
State old = myState.get();
if (!myState.compareAndSet(State.READY, State.BEING_USED_BY_PHP)) {
log("r: failed to change " + old + "->" + State.BEING_USED_BY_PHP);
return false;
}
log("r: changed " + old + "->" + State.BEING_USED_BY_PHP);
try {
analyze.run();
}
finally {
boolean set = myState.compareAndSet(State.BEING_USED_BY_PHP, State.READY);
assert set : myState.get();
log("r: changed back " + State.BEING_USED_BY_PHP + "->" + State.READY);
}
return true;
}
@@ -15,20 +15,16 @@
*/
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.CodeInsightUtilBase;
import com.intellij.codeInsight.ExpectedTypeInfo;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.template.Template;
import com.intellij.codeInsight.template.TemplateBuilderImpl;
import com.intellij.codeInsight.template.TemplateEditingAdapter;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
@@ -60,7 +56,8 @@ public class CreateFieldFromUsageFix extends CreateVarFromUsageFix {
@Override
protected void invokeImpl(final PsiClass targetClass) {
final Project project = myReferenceExpression.getProject();
PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory();
JVMElementFactory factory = JVMElementFactories.getFactory(targetClass.getLanguage(), project);
if (factory == null) factory = JavaPsiFacade.getElementFactory(project);
PsiMember enclosingContext = null;
PsiClass parentClass;
@@ -76,28 +73,16 @@ public class CreateFieldFromUsageFix extends CreateVarFromUsageFix {
ExpectedTypeInfo[] expectedTypes = CreateFromUsageUtils.guessExpectedTypes(myReferenceExpression, false);
String fieldName = myReferenceExpression.getReferenceName();
PsiField field;
if (!createConstantField()) {
field = factory.createField(fieldName, PsiType.INT);
}
else {
PsiClass aClass = factory.createClassFromText("int i = 0;", null);
field = aClass.getFields()[0];
field.setName(fieldName);
}
if (enclosingContext != null && enclosingContext.getParent() == parentClass && targetClass == parentClass
&& enclosingContext instanceof PsiField) {
field = (PsiField)targetClass.addBefore(field, enclosingContext);
}
else if (enclosingContext != null && enclosingContext.getParent() == parentClass && targetClass == parentClass
&& enclosingContext instanceof PsiClassInitializer) {
field = (PsiField)targetClass.addBefore(field, enclosingContext);
targetClass.addBefore(CodeEditUtil.createLineFeed(field.getManager()), enclosingContext);
}
else {
field = (PsiField)targetClass.add(field);
assert fieldName != null;
PsiField field = factory.createField(fieldName, PsiType.INT);
if (createConstantField()) {
PsiUtil.setModifierProperty(field, PsiModifier.FINAL, true);
}
field = CreateFieldFromUsageHelper.insertField(targetClass, field, myReferenceExpression);
setupVisibility(parentClass, targetClass, field.getModifierList());
if (shouldCreateStaticMember(myReferenceExpression, targetClass)) {
@@ -113,24 +98,9 @@ public class CreateFieldFromUsageFix extends CreateVarFromUsageFix {
PsiUtil.setModifierProperty(field, PsiModifier.FINAL, true);
}
TemplateBuilderImpl builder = new TemplateBuilderImpl(field);
PsiElement context = PsiTreeUtil.getParentOfType(myReferenceExpression, PsiClass.class, PsiMethod.class);
new GuessTypeParameters(factory)
.setupTypeElement(field.getTypeElement(), expectedTypes, getTargetSubstitutor(myReferenceExpression),
builder, context, targetClass);
if (createConstantField()) {
builder.replaceElement(field.getInitializer(), new EmptyExpression());
}
builder.setEndVariableAfter(field.getNameIdentifier());
field = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(field);
Template template = builder.buildTemplate();
final Editor newEditor = positionCursor(project, targetFile, field);
TextRange range = field.getTextRange();
newEditor.getDocument().deleteString(range.getStartOffset(), range.getEndOffset());
if (expectedTypes.length > 1) template.setToShortenLongNames(false);
Template template =
CreateFieldFromUsageHelper.setupTemplate(field, expectedTypes, targetClass, newEditor, myReferenceExpression, createConstantField());
startTemplate(newEditor, template, project, new TemplateEditingAdapter() {
@Override
@@ -155,11 +125,11 @@ public class CreateFieldFromUsageFix extends CreateVarFromUsageFix {
return false;
}
final PsiElement element = PsiTreeUtil.getParentOfType(ref, PsiClassInitializer.class, PsiMethod.class);
if (element instanceof PsiClassInitializer){
if (element instanceof PsiClassInitializer) {
return true;
}
if (element instanceof PsiMethod && ((PsiMethod)element).isConstructor()){
if (element instanceof PsiMethod && ((PsiMethod)element).isConstructor()) {
return true;
}
@@ -0,0 +1,58 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.template.Template;
import com.intellij.lang.LanguageExtension;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiSubstitutor;
/**
* @author Max Medvedev
*/
public abstract class CreateFieldFromUsageHelper {
private static final LanguageExtension<CreateFieldFromUsageHelper> EP_NAME =
new LanguageExtension<CreateFieldFromUsageHelper>("com.intellij.codeInsight.createFieldFromUsageHelper");
public static Template setupTemplate(PsiField field,
Object expectedTypes,
PsiClass targetClass,
Editor editor,
PsiElement context, boolean createConstantField) {
CreateFieldFromUsageHelper helper = EP_NAME.forLanguage(field.getLanguage());
if (helper == null) return null;
return helper.setupTemplateImpl(field, expectedTypes, targetClass, editor, context, createConstantField,
CreateFromUsageBaseFix.getTargetSubstitutor(context));
}
public static PsiField insertField(PsiClass targetClass, PsiField field, PsiElement place) {
CreateFieldFromUsageHelper helper = EP_NAME.forLanguage(field.getLanguage());
if (helper == null) return null;
return helper.insertFieldImpl(targetClass, field, place);
}
public abstract PsiField insertFieldImpl(PsiClass targetClass, PsiField field, PsiElement place);
public abstract Template setupTemplateImpl(PsiField field,
Object expectedTypes,
PsiClass targetClass,
Editor editor,
PsiElement context,
boolean createConstantField, PsiSubstitutor substitutor);
}
@@ -37,10 +37,10 @@ import java.util.Map;
* @author ven
*/
public class GuessTypeParameters {
private final PsiElementFactory myFactory;
private final JVMElementFactory myFactory;
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.GuessTypeParameters");
public GuessTypeParameters(PsiElementFactory factory) {
public GuessTypeParameters(JVMElementFactory factory) {
myFactory = factory;
}
@@ -145,6 +145,7 @@ public class GuessTypeParameters {
return substitutor;
}
@Nullable
private static PsiClassType getComponentType (PsiType type) {
type = type.getDeepComponentType();
if (type instanceof PsiClassType) return (PsiClassType)type;
@@ -0,0 +1,95 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.CodeInsightUtilBase;
import com.intellij.codeInsight.ExpectedTypeInfo;
import com.intellij.codeInsight.template.Template;
import com.intellij.codeInsight.template.TemplateBuilderImpl;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
import com.intellij.psi.util.PsiTreeUtil;
/**
* @author Max Medvedev
*/
public class JavaCreateFieldFromUsageHelper extends CreateFieldFromUsageHelper {
@Override
public Template setupTemplateImpl(PsiField field,
Object expectedTypes,
PsiClass targetClass,
Editor editor,
PsiElement context,
boolean createConstantField,
PsiSubstitutor substitutor) {
PsiElementFactory factory = JavaPsiFacade.getElementFactory(field.getProject());
TemplateBuilderImpl builder = new TemplateBuilderImpl(field);
if (!(expectedTypes instanceof ExpectedTypeInfo[])) {
expectedTypes = ExpectedTypeInfo.EMPTY_ARRAY;
}
new GuessTypeParameters(factory).setupTypeElement(field.getTypeElement(), (ExpectedTypeInfo[])expectedTypes, substitutor, builder,
context, targetClass);
if (createConstantField) {
field.setInitializer(factory.createExpressionFromText("0", null));
builder.replaceElement(field.getInitializer(), new EmptyExpression());
}
PsiIdentifier identifier = field.getNameIdentifier();
builder.setEndVariableAfter(identifier);
field = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(field);
Template template = builder.buildTemplate();
TextRange range = field.getTextRange();
editor.getDocument().deleteString(range.getStartOffset(), range.getEndOffset());
if (((ExpectedTypeInfo[])expectedTypes).length > 1) template.setToShortenLongNames(false);
return template;
}
public PsiField insertFieldImpl(PsiClass targetClass, PsiField field, PsiElement place) {
PsiMember enclosingContext = null;
PsiClass parentClass;
do {
enclosingContext = PsiTreeUtil.getParentOfType(enclosingContext == null ? place : enclosingContext, PsiMethod.class, PsiField.class, PsiClassInitializer.class);
parentClass = enclosingContext == null ? null : enclosingContext.getContainingClass();
}
while (parentClass instanceof PsiAnonymousClass);
if (enclosingContext != null &&
enclosingContext.getParent() == parentClass &&
targetClass == parentClass &&
enclosingContext instanceof PsiField) {
field = (PsiField)targetClass.addBefore(field, enclosingContext);
}
else if (enclosingContext != null &&
enclosingContext.getParent() == parentClass &&
targetClass == parentClass &&
enclosingContext instanceof PsiClassInitializer) {
field = (PsiField)targetClass.addBefore(field, enclosingContext);
targetClass.addBefore(CodeEditUtil.createLineFeed(field.getManager()), enclosingContext);
}
else {
field = (PsiField)targetClass.add(field);
}
return field;
}
}
@@ -90,10 +90,9 @@ public class RemoveRedundantElseAction extends PsiElementBaseIntentionAction {
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
if (!CodeInsightUtilBase.prepareFileForWrite(file)) return;
PsiElement elementAt = file.findElementAt(editor.getCaretModel().getOffset());
PsiIfStatement ifStatement = (PsiIfStatement)elementAt.getParent();
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
if (!CodeInsightUtilBase.preparePsiElementForWrite(element)) return;
PsiIfStatement ifStatement = (PsiIfStatement)element.getParent();
LOG.assertTrue(ifStatement != null && ifStatement.getElseBranch() != null);
PsiStatement elseBranch = ifStatement.getElseBranch();
if (elseBranch instanceof PsiBlockStatement) {
@@ -113,12 +113,12 @@ public class SurroundWithArrayFix extends PsiElementBaseIntentionAction {
}
@Override
public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException {
if (!CodeInsightUtilBase.prepareFileForWrite(file)) return;
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
if (!CodeInsightUtilBase.preparePsiElementForWrite(element)) return;
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory();
final PsiExpression expression = getExpression(file.findElementAt(editor.getCaretModel().getOffset()));
final PsiExpression expression = getExpression(element);
assert expression != null;
final PsiExpression toReplace = elementFactory.createExpressionFromText(getArrayCreation(expression), file);
final PsiExpression toReplace = elementFactory.createExpressionFromText(getArrayCreation(expression), element);
JavaCodeStyleManager.getInstance(project).shortenClassReferences(expression.replace(toReplace));
}
@@ -160,11 +160,10 @@ public class AddOnDemandStaticImportAction extends PsiElementBaseIntentionAction
});
}
}
@Override
public void invoke(@NotNull final Project project, final Editor editor, PsiFile file) throws IncorrectOperationException {
PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
invoke(project, file, editor, element);
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
invoke(project, element.getContainingFile(), editor, element);
}
private static boolean isParameterizedReference(final PsiJavaCodeReferenceElement expression) {
@@ -202,10 +202,9 @@ public class AddSingleMemberStaticImportAction extends PsiElementBaseIntentionAc
});
}
@Override
public void invoke(@NotNull final Project project, final Editor editor, PsiFile file) throws IncorrectOperationException {
PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
invoke(file, element);
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
invoke(element.getContainingFile(), element);
}
}
@@ -67,16 +67,17 @@ public abstract class BaseMoveInitializerToMethodAction extends PsiElementBaseIn
@NotNull
protected abstract Collection<String> getUnsuitableModifiers();
@Override
public final void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
if (!CodeInsightUtilBase.prepareFileForWrite(file)) return;
final PsiField field = getFieldAtCaret(editor, file);
@Override
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
if (!CodeInsightUtilBase.preparePsiElementForWrite(element)) return;
final PsiField field = PsiTreeUtil.getParentOfType(element, PsiField.class);
assert field != null;
final PsiClass aClass = field.getContainingClass();
if (aClass == null) return;
final Collection<PsiMethod> methodsToAddInitialization = getOrCreateMethods(project, editor, file, aClass);
final Collection<PsiMethod> methodsToAddInitialization = getOrCreateMethods(project, editor, element.getContainingFile(), aClass);
final List<PsiExpressionStatement> assignments = addFieldAssignments(field, methodsToAddInitialization);
@@ -117,11 +118,6 @@ public abstract class BaseMoveInitializerToMethodAction extends PsiElementBaseIn
@NotNull
protected abstract Collection<PsiMethod> getOrCreateMethods(@NotNull Project project, @NotNull Editor editor, PsiFile file, @NotNull PsiClass aClass);
@Nullable
private static PsiField getFieldAtCaret(@NotNull Editor editor, @NotNull PsiFile file) {
final int offset = editor.getCaretModel().getOffset();
return PsiTreeUtil.getParentOfType(file.findElementAt(offset), PsiField.class);
}
@NotNull
private static PsiExpressionStatement addAssignment(@NotNull PsiCodeBlock codeBlock, @NotNull PsiField field) throws IncorrectOperationException {
@@ -1,43 +0,0 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.intention.impl;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.LowPriorityAction;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.util.Iconable;
import com.intellij.refactoring.RefactoringActionHandler;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
/**
* @author Danila Ponomarenko
*/
public abstract class BaseRunRefactoringAction implements IntentionAction, Iconable, LowPriorityAction {
public static final Icon REFACTORING_BULB = AllIcons.Actions.RefactoringBulb;
@Override
public final boolean startInWriteAction() {
return false;
}
@Override
public final Icon getIcon(int flags) {
return REFACTORING_BULB;
}
}
@@ -110,9 +110,9 @@ public class ColorChooserIntentionAction extends PsiElementBaseIntentionAction {
}
@Override
public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException {
if (!CodeInsightUtilBase.prepareFileForWrite(file)) return;
PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
if (!CodeInsightUtilBase.preparePsiElementForWrite(element)) return;
final JComponent editorComponent = editor.getComponent();
if (isInsideDecodeOrGetColorMethod(element)) {
invokeForMethodParam(editorComponent, element);
@@ -15,10 +15,8 @@
*/
package com.intellij.codeInsight.intention.impl;
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference;
@@ -32,18 +30,16 @@ import org.jetbrains.annotations.Nullable;
/**
* @author spleaner
*/
public class ConvertAbsolutePathToRelativeIntentionAction extends PsiElementBaseIntentionAction {
public class ConvertAbsolutePathToRelativeIntentionAction extends BaseIntentionAction {
protected boolean isConvertToRelative() {
return true;
}
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
final PsiFile containingFile = element.getContainingFile();
if (containingFile == null) return false;
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
final PsiReference reference = containingFile.findReferenceAt(editor.getCaretModel().getOffset());
final PsiReference reference = file.findReferenceAt(editor.getCaretModel().getOffset());
final FileReference fileReference = reference == null ? null : findFileReference(reference);
if (fileReference != null) {
@@ -15,145 +15,39 @@
*/
package com.intellij.codeInsight.intention.impl;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.CodeInsightUtilBase;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.SuggestedNameInfo;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiParameter;
import com.intellij.psi.PsiType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author Max Medvedev
*/
public class CreateFieldFromParameterAction extends CreateFieldFromParameterActionBase {
public class CreateFieldFromParameterAction extends BaseIntentionAction {
private static final Logger LOG = Logger.getInstance(CreateFieldFromParameterAction.class);
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
final PsiParameter parameter = FieldFromParameterUtils.findParameterAtCursor(file, editor);
if (parameter == null || !isAvailable(parameter)) {
return false;
}
setText(CodeInsightBundle.message("intention.create.field.from.parameter.text", parameter.getName()));
return true;
}
private static boolean isAvailable(PsiParameter psiParameter) {
final PsiType type = FieldFromParameterUtils.getSubstitutedType(psiParameter);
protected boolean isAvailable(PsiParameter psiParameter) {
final PsiType type = getSubstitutedType(psiParameter);
final PsiClass targetClass = PsiTreeUtil.getParentOfType(psiParameter, PsiClass.class);
return FieldFromParameterUtils.isAvailable(psiParameter, type, targetClass) &&
psiParameter.getLanguage().isKindOf(JavaLanguage.INSTANCE);
}
@Override
@NotNull
public String getFamilyName() {
return CodeInsightBundle.message("intention.create.field.from.parameter.family");
protected PsiType getSubstitutedType(PsiParameter parameter) {
return FieldFromParameterUtils.getSubstitutedType(parameter);
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) {
final PsiParameter myParameter = FieldFromParameterUtils.findParameterAtCursor(file, editor);
if (myParameter == null || !CodeInsightUtilBase.prepareFileForWrite(file)) return;
IdeDocumentHistory.getInstance(project).includeCurrentPlaceAsChangePlace();
try {
processParameter(project, myParameter, !ApplicationManager.getApplication().isUnitTestMode());
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
private static void processParameter(final @NotNull Project project,
final @NotNull PsiParameter myParameter,
final boolean isInteractive) {
final PsiType type = FieldFromParameterUtils.getSubstitutedType(myParameter);
final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(project);
final String parameterName = myParameter.getName();
String propertyName = styleManager.variableNameToPropertyName(parameterName, VariableKind.PARAMETER);
String fieldNameToCalc;
boolean isFinalToCalc;
final PsiClass targetClass = PsiTreeUtil.getParentOfType(myParameter, PsiClass.class);
final PsiMethod method = (PsiMethod)myParameter.getDeclarationScope();
final boolean isMethodStatic = method.hasModifierProperty(PsiModifier.STATIC);
VariableKind kind = isMethodStatic ? VariableKind.STATIC_FIELD : VariableKind.FIELD;
SuggestedNameInfo suggestedNameInfo = styleManager.suggestVariableName(kind, propertyName, null, type);
String[] names = suggestedNameInfo.names;
if (isInteractive) {
List<String> namesList = new ArrayList<String>();
ContainerUtil.addAll(namesList, names);
String defaultName = styleManager.propertyNameToVariableName(propertyName, kind);
if (namesList.contains(defaultName)) {
Collections.swap(namesList, 0, namesList.indexOf(defaultName));
}
else {
namesList.add(0, defaultName);
}
names = ArrayUtil.toStringArray(namesList);
final CreateFieldFromParameterDialog dialog = new CreateFieldFromParameterDialog(
project,
names,
targetClass,
method.isConstructor(),
type
);
dialog.show();
if (!dialog.isOK()) return;
fieldNameToCalc = dialog.getEnteredName();
isFinalToCalc = dialog.isDeclareFinal();
suggestedNameInfo.nameChosen(fieldNameToCalc);
}
else {
isFinalToCalc = !isMethodStatic && method.isConstructor();
fieldNameToCalc = names[0];
}
final boolean isFinal = isFinalToCalc;
final String fieldName = fieldNameToCalc;
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
try {
FieldFromParameterUtils.createFieldAndAddAssignment(
project,
targetClass,
method,
myParameter,
type,
fieldName,
isMethodStatic,
isFinal);
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
});
}
@Override
public boolean startInWriteAction() {
return false;
protected void performRefactoring(Project project,
PsiClass targetClass,
PsiMethod method,
PsiParameter myParameter,
PsiType type,
String fieldName,
boolean methodStatic,
boolean isFinal) {
FieldFromParameterUtils.createFieldAndAddAssignment(project, targetClass, method, myParameter, type, fieldName, methodStatic, isFinal);
}
}
@@ -0,0 +1,156 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.intention.impl;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.CodeInsightUtilBase;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.SuggestedNameInfo;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public abstract class CreateFieldFromParameterActionBase extends BaseIntentionAction {
private static final Logger LOG = Logger.getInstance(CreateFieldFromParameterActionBase.class);
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
final PsiParameter parameter = FieldFromParameterUtils.findParameterAtCursor(file, editor);
if (parameter == null || !isAvailable(parameter)) {
return false;
}
setText(CodeInsightBundle.message("intention.create.field.from.parameter.text", parameter.getName()));
return true;
}
protected abstract boolean isAvailable(PsiParameter parameter);
@Override
@NotNull
public String getFamilyName() {
return CodeInsightBundle.message("intention.create.field.from.parameter.family");
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) {
final PsiParameter myParameter = FieldFromParameterUtils.findParameterAtCursor(file, editor);
if (myParameter == null || !CodeInsightUtilBase.prepareFileForWrite(file)) return;
IdeDocumentHistory.getInstance(project).includeCurrentPlaceAsChangePlace();
try {
processParameter(project, myParameter, !ApplicationManager.getApplication().isUnitTestMode());
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
private void processParameter(final @NotNull Project project,
final @NotNull PsiParameter myParameter,
final boolean isInteractive) {
final PsiType type = getSubstitutedType(myParameter);
final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(project);
final String parameterName = myParameter.getName();
String propertyName = styleManager.variableNameToPropertyName(parameterName, VariableKind.PARAMETER);
String fieldNameToCalc;
boolean isFinalToCalc;
final PsiClass targetClass = PsiTreeUtil.getParentOfType(myParameter, PsiClass.class);
final PsiMethod method = (PsiMethod)myParameter.getDeclarationScope();
final boolean isMethodStatic = method.hasModifierProperty(PsiModifier.STATIC);
VariableKind kind = isMethodStatic ? VariableKind.STATIC_FIELD : VariableKind.FIELD;
SuggestedNameInfo suggestedNameInfo = styleManager.suggestVariableName(kind, propertyName, null, type);
String[] names = suggestedNameInfo.names;
if (isInteractive) {
List<String> namesList = new ArrayList<String>();
ContainerUtil.addAll(namesList, names);
String defaultName = styleManager.propertyNameToVariableName(propertyName, kind);
if (namesList.contains(defaultName)) {
Collections.swap(namesList, 0, namesList.indexOf(defaultName));
}
else {
namesList.add(0, defaultName);
}
names = ArrayUtil.toStringArray(namesList);
final CreateFieldFromParameterDialog dialog = new CreateFieldFromParameterDialog(
project,
names,
targetClass,
method.isConstructor(),
type
);
dialog.show();
if (!dialog.isOK()) return;
fieldNameToCalc = dialog.getEnteredName();
isFinalToCalc = dialog.isDeclareFinal();
suggestedNameInfo.nameChosen(fieldNameToCalc);
}
else {
isFinalToCalc = !isMethodStatic && method.isConstructor();
fieldNameToCalc = names[0];
}
final boolean isFinal = isFinalToCalc;
final String fieldName = fieldNameToCalc;
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
try {
performRefactoring(project, targetClass, method, myParameter, type, fieldName, isMethodStatic, isFinal);
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
});
}
protected abstract PsiType getSubstitutedType(PsiParameter parameter);
protected abstract void performRefactoring(Project project,
PsiClass targetClass,
PsiMethod method,
PsiParameter myParameter,
PsiType type,
String fieldName,
boolean methodStatic,
boolean isFinal);
@Override
public boolean startInWriteAction() {
return false;
}
}
@@ -35,7 +35,7 @@ import javax.swing.event.DocumentEvent;
import java.awt.*;
import java.awt.event.*;
class CreateFieldFromParameterDialog extends DialogWrapper {
public class CreateFieldFromParameterDialog extends DialogWrapper {
private final Project myProject;
private final String[] myNames;
private final PsiType[] myTypes;
@@ -67,7 +67,7 @@ class CreateFieldFromParameterDialog extends DialogWrapper {
@Override
protected void doOKAction() {
if (myCbFinal.isEnabled()) {
PropertiesComponent.getInstance().setValue(PROPERTY_NAME, "" + myCbFinal.isSelected());
PropertiesComponent.getInstance().setValue(PROPERTY_NAME, String.valueOf(myCbFinal.isSelected()));
}
final PsiField[] fields = myTargetClass.getFields();
@@ -16,10 +16,10 @@
package com.intellij.codeInsight.intention.impl;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.openapi.editor.CaretModel;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.refactoring.BaseRefactoringIntentionAction;
import com.intellij.refactoring.encapsulateFields.EncapsulateFieldsHandler;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
@@ -28,7 +28,7 @@ import org.jetbrains.annotations.Nullable;
/**
* @author Danila Ponomarenko
*/
public class EncapsulateFieldAction extends BaseRunRefactoringAction {
public class EncapsulateFieldAction extends BaseRefactoringIntentionAction {
@NotNull
@Override
@@ -43,15 +43,18 @@ public class EncapsulateFieldAction extends BaseRunRefactoringAction {
}
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
final PsiField field = getField(getElement(editor, file));
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
if (element instanceof SyntheticElement){
return false;
}
final PsiField field = getField(element);
return field != null && !field.hasModifierProperty(PsiModifier.FINAL) && !field.hasModifierProperty(PsiModifier.PRIVATE);
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
final PsiField field = getField(getElement(editor, file));
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
final PsiField field = getField(element);
if (field == null) {
return;
}
@@ -59,6 +62,7 @@ public class EncapsulateFieldAction extends BaseRunRefactoringAction {
new EncapsulateFieldsHandler().invoke(project, new PsiElement[]{field}, null);
}
@Nullable
protected static PsiField getField(@Nullable PsiElement element) {
if (element == null || !(element instanceof PsiIdentifier)) {
@@ -81,12 +85,4 @@ public class EncapsulateFieldAction extends BaseRunRefactoringAction {
}
return (PsiField)resolved;
}
@Nullable
protected static PsiElement getElement(Editor editor, @NotNull PsiFile file) {
if (!file.getManager().isInProject(file)) return null;
final CaretModel caretModel = editor.getCaretModel();
final int position = caretModel.getOffset();
return file.findElementAt(position);
}
}
@@ -65,16 +65,12 @@ public class ExpandStaticImportAction extends PsiElementBaseIntentionAction {
}
public void invoke(final Project project, final PsiFile file, final Editor editor, PsiElement element) {
if (!CodeInsightUtilBase.prepareFileForWrite(file)) return;
if (!CodeInsightUtilBase.preparePsiElementForWrite(element)) return;
final PsiJavaCodeReferenceElement refExpr = (PsiJavaCodeReferenceElement)element.getParent();
final PsiImportStaticStatement staticImport = (PsiImportStaticStatement)refExpr.advancedResolve(true).getCurrentFileResolveScope();
final List<PsiJavaCodeReferenceElement> expressionToExpand = collectReferencesThrough(file, refExpr, staticImport);
if (expressionToExpand.isEmpty()) {
expand(refExpr, staticImport);
staticImport.delete();
@@ -109,8 +105,7 @@ public class ExpandStaticImportAction extends PsiElementBaseIntentionAction {
}
@Override
public void invoke(@NotNull final Project project, final Editor editor, PsiFile file) throws IncorrectOperationException {
PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
invoke(project, file, editor, element);
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
invoke(project, element.getContainingFile(), editor, element);
}
}
@@ -16,21 +16,19 @@
package com.intellij.codeInsight.intention.impl;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.openapi.editor.CaretModel;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.BaseRefactoringIntentionAction;
import com.intellij.refactoring.introduceVariable.IntroduceVariableHandler;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Danila Ponomarenko
*/
public class IntroduceVariableIntentionAction extends BaseRunRefactoringAction {
public class IntroduceVariableIntentionAction extends BaseRefactoringIntentionAction {
@NotNull
@Override
public String getText() {
@@ -44,39 +42,28 @@ public class IntroduceVariableIntentionAction extends BaseRunRefactoringAction {
}
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
final PsiElement element = getElement(editor, file);
if (element == null) {
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
if (element instanceof SyntheticElement){
return false;
}
final PsiExpression expression = getExpression(element);
if (expression == null || !(expression.getParent() instanceof PsiExpressionStatement)) {
final PsiExpressionStatement statement = PsiTreeUtil.getParentOfType(element,PsiExpressionStatement.class);
if (statement == null){
return false;
}
final PsiExpression expression = statement.getExpression();
return expression.getType() != PsiType.VOID && !(expression instanceof PsiAssignmentExpression);
}
@Nullable
private static PsiExpression getExpression(@NotNull PsiElement element) {
PsiExpression expression = PsiTreeUtil.getParentOfType(element, PsiExpression.class, false);
while (expression != null && expression instanceof PsiReferenceExpression) {
expression = PsiTreeUtil.getParentOfType(expression, PsiExpression.class, true);
}
return expression;
}
@Nullable
protected static PsiElement getElement(Editor editor, @NotNull PsiFile file) {
if (!file.getManager().isInProject(file)) return null;
final CaretModel caretModel = editor.getCaretModel();
final int position = caretModel.getOffset();
return file.findElementAt(position);
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
new IntroduceVariableHandler().invoke(project, editor, file, null);
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
final PsiExpressionStatement statement = PsiTreeUtil.getParentOfType(element,PsiExpressionStatement.class);
if (statement == null){
return;
}
new IntroduceVariableHandler().invoke(project, editor, statement.getExpression());
}
}
@@ -80,11 +80,10 @@ public class InvertIfConditionAction extends PsiElementBaseIntentionAction {
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
if (!CodeInsightUtilBase.prepareFileForWrite(file)) return;
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
if (!CodeInsightUtilBase.preparePsiElementForWrite(element)) return;
PsiIfStatement ifStatement = PsiTreeUtil.getParentOfType(file.findElementAt(
editor.getCaretModel().getOffset()), PsiIfStatement.class);
PsiIfStatement ifStatement = PsiTreeUtil.getParentOfType(element, PsiIfStatement.class);
LOG.assertTrue(ifStatement != null);
PsiElement block = findCodeBlock(ifStatement);
@@ -93,10 +93,7 @@ public class MakeTypeGenericAction extends PsiElementBaseIntentionAction {
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
final CaretModel caretModel = editor.getCaretModel();
final int position = caretModel.getOffset();
final PsiElement element = file.findElementAt(position);
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
Pair<PsiVariable, PsiType> pair = findVariable(element);
if (pair == null) return;
PsiVariable variable = pair.getFirst();
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,16 +17,19 @@ package com.intellij.codeInsight.intention.impl;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiElement;
import com.intellij.refactoring.BaseRefactoringIntentionAction;
import com.intellij.refactoring.RefactoringActionHandler;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
/**
* User: anna
* Date: 9/5/11
*/
public class RunRefactoringAction extends BaseRunRefactoringAction {
public class RunRefactoringAction extends BaseRefactoringIntentionAction {
private final RefactoringActionHandler myHandler;
private final String myCommandName;
@@ -48,12 +51,22 @@ public class RunRefactoringAction extends BaseRunRefactoringAction {
}
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
return true;
}
@Override
public final void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
myHandler.invoke(project, editor, file, null);
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
myHandler.invoke(project, editor, element.getContainingFile(), null);
}
@Override
public boolean startInWriteAction() {
return false;
}
@Override
public Icon getIcon(@IconFlags int flags) {
return REFACTORING_BULB;
}
}
@@ -64,7 +64,7 @@ public class SplitDeclarationAction extends PsiElementBaseIntentionAction {
PsiElement nextField = field.getNextSibling();
while (nextField != null && !(nextField instanceof PsiField)) nextField = nextField.getNextSibling();
if (nextField != null && ((PsiField) nextField).getTypeElement() == typeElement) return true;
if (nextField != null && ((PsiField)nextField).getTypeElement() == typeElement) return true;
return false;
}
@@ -74,11 +74,12 @@ public class SplitDeclarationAction extends PsiElementBaseIntentionAction {
if (declaredElements.length == 0) return false;
if (!(declaredElements[0] instanceof PsiLocalVariable)) return false;
if (declaredElements.length == 1) {
PsiLocalVariable var = (PsiLocalVariable) declaredElements[0];
PsiLocalVariable var = (PsiLocalVariable)declaredElements[0];
if (var.getInitializer() == null) return false;
setText(CodeInsightBundle.message("intention.split.declaration.assignment.text"));
return true;
} else if (declaredElements.length > 1) {
}
else if (declaredElements.length > 1) {
if (decl.getParent() instanceof PsiForStatement) return false;
setText(CodeInsightBundle.message("intention.split.declaration.text"));
@@ -89,23 +90,17 @@ public class SplitDeclarationAction extends PsiElementBaseIntentionAction {
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
if (!CodeInsightUtilBase.prepareFileForWrite(file)) return;
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
if (!CodeInsightUtilBase.preparePsiElementForWrite(element)) return;
PsiManager psiManager = PsiManager.getInstance(project);
int offset = editor.getCaretModel().getOffset();
PsiElement token = file.findElementAt(offset);
PsiDeclarationStatement decl = PsiTreeUtil.getParentOfType(
token,
PsiDeclarationStatement.class
);
final PsiDeclarationStatement decl = PsiTreeUtil.getParentOfType(element, PsiDeclarationStatement.class);
final PsiManager psiManager = PsiManager.getInstance(project);
if (decl != null) {
invokeOnDeclarationStatement(decl, psiManager, project);
}
else {
PsiField field = PsiTreeUtil.getParentOfType(token, PsiField.class);
PsiField field = PsiTreeUtil.getParentOfType(element, PsiField.class);
if (field != null) {
field.normalizeDeclaration();
}
@@ -113,19 +108,19 @@ public class SplitDeclarationAction extends PsiElementBaseIntentionAction {
}
private static void invokeOnDeclarationStatement(PsiDeclarationStatement decl, PsiManager psiManager,
Project project) throws IncorrectOperationException {
Project project) throws IncorrectOperationException {
if (decl.getDeclaredElements().length == 1) {
PsiLocalVariable var = (PsiLocalVariable) decl.getDeclaredElements()[0];
PsiLocalVariable var = (PsiLocalVariable)decl.getDeclaredElements()[0];
var.normalizeDeclaration();
PsiExpressionStatement statement = (PsiExpressionStatement) JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory()
.createStatementFromText(var.getName() + "=xxx;", null);
statement = (PsiExpressionStatement) CodeStyleManager.getInstance(project).reformat(statement);
PsiAssignmentExpression assignment = (PsiAssignmentExpression) statement.getExpression();
PsiExpressionStatement statement = (PsiExpressionStatement)JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory()
.createStatementFromText(var.getName() + "=xxx;", null);
statement = (PsiExpressionStatement)CodeStyleManager.getInstance(project).reformat(statement);
PsiAssignmentExpression assignment = (PsiAssignmentExpression)statement.getExpression();
PsiExpression initializer = var.getInitializer();
PsiExpression rExpression;
if (initializer instanceof PsiArrayInitializerExpression) {
rExpression = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory().createExpressionFromText(
"new " + var.getTypeElement().getText() + " " + initializer.getText(), null
"new " + var.getTypeElement().getText() + " " + initializer.getText(), null
);
}
else {
@@ -157,14 +152,17 @@ public class SplitDeclarationAction extends PsiElementBaseIntentionAction {
codeBlock.add(varDeclStatement);
codeBlock.add(block);
block.replace(blockStatement);
} else {
}
else {
parent.addBefore(varDeclStatement, block);
}
} else {
}
else {
block.addAfter(statement, decl);
}
} else {
((PsiLocalVariable) decl.getDeclaredElements()[0]).normalizeDeclaration();
}
else {
((PsiLocalVariable)decl.getDeclaredElements()[0]).normalizeDeclaration();
}
}
}
@@ -72,14 +72,11 @@ public class SplitIfAction extends PsiElementBaseIntentionAction {
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) {
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
try {
if (!CodeInsightUtilBase.prepareFileForWrite(file)) { return; }
if (!CodeInsightUtilBase.preparePsiElementForWrite(element)) return;
int offset = editor.getCaretModel().getOffset();
PsiJavaToken token = (PsiJavaToken)file.findElementAt(offset);
PsiJavaToken token = (PsiJavaToken)element;
LOG.assertTrue(token.getTokenType() == JavaTokenType.ANDAND || token.getTokenType() == JavaTokenType.OROR);
PsiPolyadicExpression expression = (PsiPolyadicExpression)token.getParent();
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.ChangeContextUtil;
import com.intellij.codeInsight.CodeInsightUtilBase;
import com.intellij.codeInsight.TargetElementUtilBase;
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
import com.intellij.codeInsight.intention.impl.BaseIntentionAction;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
@@ -41,8 +42,8 @@ import org.jetbrains.annotations.NotNull;
import java.util.*;
public class ReplaceImplementsWithStaticImportAction extends PsiElementBaseIntentionAction {
private static final Logger LOG = Logger.getInstance("#" + ReplaceImplementsWithStaticImportAction.class.getName());
public class ReplaceImplementsWithStaticImportAction extends BaseIntentionAction {
private static final Logger LOG = Logger.getInstance(ReplaceImplementsWithStaticImportAction.class);
@NonNls private static final String FIND_CONSTANT_FIELD_USAGES = "Find constant field usages...";
@NotNull
@@ -55,8 +56,11 @@ public class ReplaceImplementsWithStaticImportAction extends PsiElementBaseInten
return getText();
}
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
if (!(element.getContainingFile() instanceof PsiJavaFile)) return false;
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
if (!(file instanceof PsiJavaFile)) return false;
final PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
if (element instanceof PsiIdentifier) {
final PsiElement parent = element.getParent();
if (parent instanceof PsiClass) {
@@ -99,6 +103,7 @@ public class ReplaceImplementsWithStaticImportAction extends PsiElementBaseInten
return targetClass.getAllFields().length > 0;
}
@Override
public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException {
if (!CodeInsightUtilBase.preparePsiElementForWrite(file)) return;
@@ -27,6 +27,7 @@ import com.intellij.codeInspection.util.SpecialAnnotationsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiModifierListOwner;
import org.intellij.lang.annotations.Pattern;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -138,7 +139,7 @@ public class UnusedSymbolLocalInspection extends BaseJavaLocalInspectionTool imp
return new OptionsPanel().getPanel();
}
public static IntentionAction createQuickFix(final String qualifiedName, String element, Project project) {
public static IntentionAction createQuickFix(@NonNls String qualifiedName, @Nls String element, Project project) {
final EntryPointsManagerImpl entryPointsManager = EntryPointsManagerImpl.getInstance(project);
return SpecialAnnotationsUtil.createAddToSpecialAnnotationsListIntentionAction(
QuickFixBundle.message("fix.unused.symbol.injection.text", element, qualifiedName),
@@ -24,6 +24,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.FileAttribute;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.util.indexing.FileBasedIndex;
import com.intellij.util.io.DataInputOutputUtil;
import com.intellij.util.messages.MessageBus;
import org.jetbrains.annotations.NotNull;
@@ -77,14 +78,14 @@ public class JavaLanguageLevelPusher implements FilePropertyPusher<LanguageLevel
return false;
}
private static final FileAttribute PERSISTENCE = new FileAttribute("language_level_persistence", 1, true);
private static final FileAttribute PERSISTENCE = new FileAttribute("language_level_persistence", 2, true);
@Override
public void persistAttribute(VirtualFile fileOrDir, @NotNull LanguageLevel level) throws IOException {
final DataInputStream iStream = PERSISTENCE.readAttribute(fileOrDir);
if (iStream != null) {
try {
final int oldLevelOrdinal = iStream.readInt();
final int oldLevelOrdinal = DataInputOutputUtil.readINT(iStream);
if (oldLevelOrdinal == level.ordinal()) return;
}
finally {
@@ -93,7 +94,7 @@ public class JavaLanguageLevelPusher implements FilePropertyPusher<LanguageLevel
}
final DataOutputStream oStream = PERSISTENCE.writeAttribute(fileOrDir);
oStream.writeInt(level.ordinal());
DataInputOutputUtil.writeINT(oStream, level.ordinal());
oStream.close();
for (VirtualFile child : fileOrDir.getChildren()) {
@@ -18,6 +18,7 @@ package com.intellij.psi.filters.getters;
import com.intellij.codeInsight.CodeInsightUtil;
import com.intellij.codeInsight.completion.CompletionUtil;
import com.intellij.codeInsight.completion.JavaCompletionUtil;
import com.intellij.codeInsight.completion.PrefixMatcher;
import com.intellij.codeInsight.completion.StaticMemberProcessor;
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
import com.intellij.codeInsight.lookup.LookupElement;
@@ -61,7 +62,7 @@ public abstract class MembersGetter {
}
final Set<PsiMember> importedStatically = new HashSet<PsiMember>();
processor.processMembersOfRegisteredClasses(null, new PairConsumer<PsiMember, PsiClass>() {
processor.processMembersOfRegisteredClasses(PrefixMatcher.ALWAYS_TRUE, new PairConsumer<PsiMember, PsiClass>() {
@Override
public void consume(PsiMember member, PsiClass psiClass) {
importedStatically.add(member);
@@ -662,9 +662,12 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase<Paramet
@Override
protected ValidationInfo doValidate() {
for (final ParameterTableModelItemBase<ParameterInfoImpl> item : myParametersTableModel.getItems()) {
if (item.parameter.oldParameterIndex < 0) {
if (StringUtil.isEmpty(item.defaultValueCodeFragment.getText())) return new ValidationInfo("Default value is missed. In the method call place new parameter value would be leaved blank");
if (!getTableComponent().isEditing()) {
for (final ParameterTableModelItemBase<ParameterInfoImpl> item : myParametersTableModel.getItems()) {
if (item.parameter.oldParameterIndex < 0) {
if (StringUtil.isEmpty(item.defaultValueCodeFragment.getText()))
return new ValidationInfo("Default value is missing. In the method call place new parameter value would be leaved blank");
}
}
}
return super.doValidate();
@@ -33,11 +33,15 @@ import com.intellij.refactoring.ui.ConflictsDialog;
import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
public class IntroduceVariableHandler extends IntroduceVariableBase {
public void invoke(@NotNull final Project project, final Editor editor, final PsiExpression expression) {
invokeImpl(project, expression, editor);
}
@Override
public IntroduceVariableSettings getSettings(Project project, Editor editor,
@@ -120,7 +120,7 @@ public class RenameJavaVariableProcessor extends RenameJavaMemberProcessor {
if (!(replacedOccurence instanceof PsiReferenceExpression)) return;
PsiElement elem = ((PsiReferenceExpression)replacedOccurence).resolve();
if (elem == null || elem == field) {
if (elem == null || elem == field || elem.isEquivalentTo(field)) {
// If reference is unresolved, then field is not hidden by anyone...
return;
}
@@ -16,6 +16,7 @@
package com.intellij.testIntegration.createTest;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.CodeInsightUtilBase;
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.Editor;
@@ -87,15 +88,15 @@ public class CreateTestAction extends PsiElementBaseIntentionAction {
return rm.getFileIndex().isInTestSourceContent(f);
}
public void invoke(@NotNull final Project project, final Editor editor, PsiFile file) throws IncorrectOperationException {
PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
final Module srcModule = ModuleUtil.findModuleForPsiElement(file);
@Override
public void invoke(final @NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
if (!CodeInsightUtilBase.preparePsiElementForWrite(element)) return;
final Module srcModule = ModuleUtil.findModuleForPsiElement(element);
final PsiClass srcClass = getContainingClass(element);
if (srcClass == null) return;
PsiDirectory srcDir = file.getContainingDirectory();
PsiDirectory srcDir = element.getContainingFile().getContainingDirectory();
PsiPackage srcPackage = JavaDirectoryService.getInstance().getPackage(srcDir);
final CreateTestDialog d = new CreateTestDialog(project,
@@ -356,7 +356,7 @@ public interface PsiElementFactory extends PsiJavaParserFacade, JVMElementFactor
* @throws IncorrectOperationException if <code>name</code> is not a valid identifier or
* <code>type</code> is not a valid type.
*/
@NotNull PsiDeclarationStatement createVariableDeclarationStatement(@NonNls @NotNull String name, @NotNull PsiType type, PsiExpression initializer)
@NotNull PsiDeclarationStatement createVariableDeclarationStatement(@NonNls @NotNull String name, @NotNull PsiType type, @Nullable PsiExpression initializer)
throws IncorrectOperationException;
/**
@@ -2,6 +2,6 @@ import pack.WithInnerAClass;
public class Test1 {
public void foo() {
new WithInnerAClass<caret>
new WithInnerAClass()<caret>
}
}
@@ -1,6 +1,11 @@
class Foo {
{
Zzoo l = new Zzoo()<caret>
Zzoo l = new Zzoo() {
@Override
public void run() {
<selection>//To change body of implemented methods use File | Settings | File Templates.</selection>
}
}
}
}
@@ -2,7 +2,7 @@ public class TestClass {
public TestClass create() {
final int value = 1;
return new Xxx<caret>(value);
return new Xxx(<caret>value);
}
}
@@ -64,6 +64,7 @@ public class ClassNameCompletionTest extends CompletionTestCase {
checkResultByFile(path + "/after1.java");
configureByFile(path + "/before2.java");
selectItem(myItems[0]);
checkResultByFile(path + "/after2.java");
}
@@ -24,7 +24,6 @@ import com.intellij.codeInsight.lookup.LookupElementPresentation
import com.intellij.codeInsight.lookup.LookupManager
import com.intellij.lang.java.JavaLanguage
import com.intellij.openapi.actionSystem.IdeActions
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.fileTypes.StdFileTypes
import com.intellij.psi.codeStyle.CodeStyleSettingsManager
import com.intellij.psi.codeStyle.CommonCodeStyleSettings
@@ -695,21 +694,15 @@ public class ListUtils {
public void _testClassBeforeCast() throws Throwable { doTest '\n' }
public void testNoAllClassesOnQualifiedReference() throws Throwable {
configureByFile(getTestName(false) + ".java");
assertEmpty(myItems);
checkResultByFile(getTestName(false) + ".java");
doAntiTest()
}
public void testFinishClassNameWithDot() throws Throwable {
configureByFile(getTestName(false) + ".java");
type('.');
checkResult()
doTest('.')
}
public void testFinishClassNameWithLParen() throws Throwable {
configureByFile(getTestName(false) + ".java");
type('(');
checkResult()
doTest('(')
}
public void testSelectNoParameterSignature() throws Throwable {
@@ -722,12 +715,7 @@ public class ListUtils {
public void testCompletionInsideClassLiteral() throws Throwable {
configureByFile(getTestName(false) + ".java");
new WriteCommandAction.Simple(getProject(), new PsiFile[0]) {
@Override
protected void run() throws Throwable {
getLookup().finishLookup(Lookup.NORMAL_SELECT_CHAR);
}
}.execute().throwException();
type('\n')
checkResult()
}
@@ -797,18 +785,19 @@ public class ListUtils {
}
public void testClassNameGenerics() throws Throwable {
configure()
type '\n'
checkResult();
doTest('\n')
}
public void testClassNameAnonymous() throws Throwable {
configure()
type '\n'
checkResult();
doTest('\n')
}
public void testClassNameWithInner() throws Throwable { doTest() }
public void testClassNameWithInner() throws Throwable {
configure()
assertStringItems 'Zzoo', 'Zzoo.Impl'
type '\n'
checkResult()
}
public void testClassNameWithInner2() throws Throwable { doTest() }
public void testClassNameWithInstanceInner() throws Throwable { doTest('\n') }
@@ -987,7 +976,7 @@ public class ListUtils {
public void testPrimitiveMethodParameter() throws Throwable { doTest(); }
public void testNewExpectedClassParens() throws Throwable { doTest(); }
public void testNewExpectedClassParens() throws Throwable { doTest('\n'); }
public void testQualifyInnerMembers() throws Throwable { doTest('\n') }
@@ -206,4 +206,15 @@ public class CustomFileTypeEditorTest extends LightCodeInsightTestCase {
iterator = highlighter.createIterator(27);
assertEquals(CustomHighlighterTokenType.STRING, iterator.getTokenType());
}
public void testHaskel() throws Exception {
EditorHighlighter highlighter = HighlighterFactory.createHighlighter(getProject(), "A.hs");
// 0123456789012345678 9 0123 45 6 7
highlighter.setText("{-# #-} module");
HighlighterIterator iterator = highlighter.createIterator(2);
assertEquals(CustomHighlighterTokenType.MULTI_LINE_COMMENT, iterator.getTokenType());
iterator = highlighter.createIterator(12);
assertEquals(CustomHighlighterTokenType.KEYWORD_1, iterator.getTokenType());
}
}
@@ -46,8 +46,21 @@ public abstract class HierarchyViewTestBase extends CodeInsightTestCase {
}
private static String dump(final HierarchyTreeStructure treeStructure, @Nullable HierarchyNodeDescriptor descriptor, int level) {
StringBuilder s = new StringBuilder();
dump(treeStructure, descriptor, level, s);
return s.toString();
}
private static void dump(final HierarchyTreeStructure treeStructure,
@Nullable HierarchyNodeDescriptor descriptor,
int level,
StringBuilder b) {
if (level > 10) {
for(int i = 0; i<level; i++) b.append(" ");
b.append("<Probably infinite part skipped>\n");
return;
}
if(descriptor==null) descriptor = (HierarchyNodeDescriptor)treeStructure.getRootElement();
StringBuilder b = new StringBuilder();
for(int i = 0; i<level; i++) b.append(" ");
descriptor.update();
b.append("<node text=\"").append(descriptor.getHighlightedText().getText()).append("\"")
@@ -56,16 +69,15 @@ public abstract class HierarchyViewTestBase extends CodeInsightTestCase {
final Object[] children = treeStructure.getChildElements(descriptor);
if(children.length>0) {
b.append(">\n");
for(Object o : children) {
for (Object o : children) {
HierarchyNodeDescriptor d = (HierarchyNodeDescriptor)o;
b.append(dump(treeStructure, d, level + 1));
dump(treeStructure, d, level + 1, b);
}
for(int i = 0; i<level; i++) b.append(" ");
b.append("</node>\n");
} else {
b.append("/>\n");
}
return b.toString();
}
private static void checkHierarchyTreeStructure(final HierarchyTreeStructure treeStructure, final Document document) {