mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.compiler;
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.util.Chunk;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public abstract class CompilerEncodingService {
|
||||
public static CompilerEncodingService getInstance(@NotNull Project project) {
|
||||
return ServiceManager.getService(project, CompilerEncodingService.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Charset getPreferredModuleEncoding(Chunk<Module> chunk) {
|
||||
CompilerEncodingService service = null;
|
||||
for (Module module : chunk.getNodes()) {
|
||||
if (service == null) {
|
||||
service = getInstance(module.getProject());
|
||||
}
|
||||
final Charset charset = service.getPreferredModuleEncoding(module);
|
||||
if (charset != null) {
|
||||
return charset;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public abstract Charset getPreferredModuleEncoding(@NotNull Module module);
|
||||
|
||||
@NotNull
|
||||
public abstract Collection<Charset> getAllModuleEncodings(@NotNull Module module);
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.compiler.impl;
|
||||
|
||||
import com.intellij.compiler.CompilerEncodingService;
|
||||
import com.intellij.openapi.compiler.CompilerManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.encoding.EncodingProjectManager;
|
||||
import com.intellij.openapi.vfs.encoding.EncodingProjectManagerImpl;
|
||||
import com.intellij.psi.util.CachedValue;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import gnu.trove.THashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class CompilerEncodingServiceImpl extends CompilerEncodingService {
|
||||
@NotNull private final Project myProject;
|
||||
private final CachedValue<Map<Module, Set<Charset>>> myModuleFileEncodings;
|
||||
|
||||
public CompilerEncodingServiceImpl(@NotNull Project project) {
|
||||
myProject = project;
|
||||
myModuleFileEncodings = CachedValuesManager.getManager(project).createCachedValue(new CachedValueProvider<Map<Module, Set<Charset>>>() {
|
||||
@Override
|
||||
public Result<Map<Module, Set<Charset>>> compute() {
|
||||
Map<Module, Set<Charset>> result = computeModuleCharsetMap();
|
||||
return Result.create(result, ProjectRootManager.getInstance(myProject),
|
||||
((EncodingProjectManagerImpl)EncodingProjectManager.getInstance(myProject)).getModificationTracker());
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
private Map<Module, Set<Charset>> computeModuleCharsetMap() {
|
||||
final Map<Module, Set<Charset>> map = new THashMap<Module, Set<Charset>>();
|
||||
final Map<VirtualFile, Charset> mappings = EncodingProjectManager.getInstance(myProject).getAllMappings();
|
||||
ProjectFileIndex index = ProjectRootManager.getInstance(myProject).getFileIndex();
|
||||
final CompilerManager compilerManager = CompilerManager.getInstance(myProject);
|
||||
for (Map.Entry<VirtualFile, Charset> entry : mappings.entrySet()) {
|
||||
final VirtualFile file = entry.getKey();
|
||||
final Charset charset = entry.getValue();
|
||||
if (file == null || charset == null || (!file.isDirectory() && !compilerManager.isCompilableFileType(file.getFileType()))
|
||||
|| !index.isInSourceContent(file)) continue;
|
||||
|
||||
final Module module = index.getModuleForFile(file);
|
||||
if (module == null) continue;
|
||||
|
||||
Set<Charset> set = map.get(module);
|
||||
if (set == null) {
|
||||
set = new LinkedHashSet<Charset>();
|
||||
map.put(module, set);
|
||||
|
||||
final VirtualFile sourceRoot = index.getSourceRootForFile(file);
|
||||
VirtualFile current = file.getParent();
|
||||
Charset parentCharset = null;
|
||||
while (current != null) {
|
||||
final Charset currentCharset = mappings.get(current);
|
||||
if (currentCharset != null) {
|
||||
parentCharset = currentCharset;
|
||||
}
|
||||
if (current.equals(sourceRoot)) {
|
||||
break;
|
||||
}
|
||||
current = current.getParent();
|
||||
}
|
||||
if (parentCharset != null) {
|
||||
set.add(parentCharset);
|
||||
}
|
||||
}
|
||||
set.add(charset);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Charset getPreferredModuleEncoding(@NotNull Module module) {
|
||||
final Set<Charset> encodings = myModuleFileEncodings.getValue().get(module);
|
||||
return ContainerUtil.getFirstItem(encodings, EncodingProjectManager.getInstance(myProject).getDefaultCharset());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<Charset> getAllModuleEncodings(@NotNull Module module) {
|
||||
final Set<Charset> encodings = myModuleFileEncodings.getValue().get(module);
|
||||
if (encodings != null) {
|
||||
return encodings;
|
||||
}
|
||||
return ContainerUtil.createMaybeSingletonList(EncodingProjectManager.getInstance(myProject).getDefaultCharset());
|
||||
}
|
||||
}
|
||||
+46
-10
@@ -48,10 +48,7 @@ import com.intellij.openapi.projectRoots.JavaSdkType;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
@@ -72,6 +69,7 @@ import org.objectweb.asm.ClassWriter;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
@@ -186,9 +184,16 @@ public class BackendCompilerWrapper {
|
||||
}
|
||||
|
||||
private void compileChunk(ModuleChunk chunk) throws IOException {
|
||||
final String chunkPresentableName = getPresentableNameFor(chunk);
|
||||
myModuleName = chunkPresentableName;
|
||||
|
||||
// validate encodings
|
||||
if (chunk.getModuleCount() > 1) {
|
||||
validateEncoding(chunk, chunkPresentableName);
|
||||
}
|
||||
|
||||
runTransformingCompilers(chunk);
|
||||
|
||||
setPresentableNameFor(chunk);
|
||||
|
||||
final List<OutputDir> outs = new ArrayList<OutputDir>();
|
||||
File fileToDelete = getOutputDirsToCompileTo(chunk, outs);
|
||||
@@ -206,10 +211,39 @@ public class BackendCompilerWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
private void validateEncoding(ModuleChunk chunk, String chunkPresentableName) {
|
||||
final CompilerEncodingService es = CompilerEncodingService.getInstance(myProject);
|
||||
Charset charset = null;
|
||||
for (Module module : chunk.getModules()) {
|
||||
final Charset moduleCharset = es.getPreferredModuleEncoding(module);
|
||||
if (charset == null) {
|
||||
charset = moduleCharset;
|
||||
}
|
||||
else {
|
||||
if (!Comparing.equal(charset, moduleCharset)) {
|
||||
// warn user
|
||||
final Charset chunkEncoding = CompilerEncodingService.getPreferredModuleEncoding(chunk);
|
||||
final StringBuilder message = new StringBuilder();
|
||||
message.append("Modules in chunk [");
|
||||
message.append(chunkPresentableName);
|
||||
message.append("] configured to use different encodings.\n");
|
||||
if (chunkEncoding != null) {
|
||||
message.append("\"").append(chunkEncoding.name()).append("\" encoding will be used to compile the chunk");
|
||||
}
|
||||
else {
|
||||
message.append("Default compiler encoding will be used to compile the chunk");
|
||||
}
|
||||
myCompileContext.addMessage(CompilerMessageCategory.INFORMATION, message.toString(), null, -1, -1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setPresentableNameFor(final ModuleChunk chunk) {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
|
||||
private static String getPresentableNameFor(final ModuleChunk chunk) {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
public String compute() {
|
||||
final Module[] modules = chunk.getModules();
|
||||
StringBuilder moduleName = new StringBuilder(Math.min(128, modules.length * 8));
|
||||
for (int idx = 0; idx < modules.length; idx++) {
|
||||
@@ -223,7 +257,7 @@ public class BackendCompilerWrapper {
|
||||
break;
|
||||
}
|
||||
}
|
||||
myModuleName = moduleName.toString();
|
||||
return moduleName.toString();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -845,7 +879,9 @@ public class BackendCompilerWrapper {
|
||||
while (true) {
|
||||
FileObject path = myPaths.take();
|
||||
|
||||
if (path == myStopThreadToken) break;
|
||||
if (path == myStopThreadToken) {
|
||||
break;
|
||||
}
|
||||
processPath(path, myProject);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,7 +305,11 @@ public class ModuleChunk extends Chunk<Module> {
|
||||
|
||||
//the check for equal language levels is done elsewhere
|
||||
public LanguageLevel getLanguageLevel() {
|
||||
return LanguageLevelUtil.getEffectiveLanguageLevel(getModules()[0]);
|
||||
return LanguageLevelUtil.getEffectiveLanguageLevel(getNodes().iterator().next());
|
||||
}
|
||||
|
||||
public Project getProject() {
|
||||
return myContext.getProject();
|
||||
}
|
||||
|
||||
private static class BeforeJdkOrderEntryCondition implements Condition<OrderEntry> {
|
||||
|
||||
+1
-1
@@ -109,7 +109,7 @@ public class CompilerAPICompiler implements BackendCompiler {
|
||||
List<String> commandLine = new ArrayList<String>();
|
||||
JavacSettings javacSettings = CompilerAPIConfiguration.getSettings(myProject, CompilerAPIConfiguration.class);
|
||||
final List<String> additionalOptions =
|
||||
JavacCompiler.addAdditionalSettings(commandLine, javacSettings, false, JavaSdkVersion.JDK_1_6, myProject, compileContext.isAnnotationProcessorsEnabled());
|
||||
JavacCompiler.addAdditionalSettings(commandLine, javacSettings, false, JavaSdkVersion.JDK_1_6, chunk, compileContext.isAnnotationProcessorsEnabled());
|
||||
|
||||
JavacCompiler.addCommandLineOptions(chunk, commandLine, outputDir, chunk.getJdk(), false,false, null, false, false, false);
|
||||
commandLine.addAll(additionalOptions);
|
||||
|
||||
+1
-1
@@ -184,7 +184,7 @@ public class EclipseCompiler extends ExternalCompiler {
|
||||
commandLine.add(outputPath.replace('/', File.separatorChar));
|
||||
|
||||
commandLine.add("-verbose");
|
||||
StringTokenizer tokenizer = new StringTokenizer(compilerSettings.getOptionsString(myProject), " ");
|
||||
StringTokenizer tokenizer = new StringTokenizer(compilerSettings.getOptionsString(chunk), " ");
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
commandLine.add(tokenizer.nextToken());
|
||||
}
|
||||
|
||||
+4
-4
@@ -214,7 +214,7 @@ public class JavacCompiler extends ExternalCompiler {
|
||||
}
|
||||
|
||||
final List<String> additionalOptions =
|
||||
addAdditionalSettings(commandLine, javacSettings, myAnnotationProcessorMode, version, myProject, annotationProcessorsEnabled);
|
||||
addAdditionalSettings(commandLine, javacSettings, myAnnotationProcessorMode, version, chunk, annotationProcessorsEnabled);
|
||||
|
||||
CompilerUtil.addLocaleOptions(commandLine, false);
|
||||
|
||||
@@ -275,15 +275,15 @@ public class JavacCompiler extends ExternalCompiler {
|
||||
}
|
||||
|
||||
public static List<String> addAdditionalSettings(List<String> commandLine, JavacSettings javacSettings, boolean isAnnotationProcessing,
|
||||
JavaSdkVersion version, Project project, boolean annotationProcessorsEnabled) {
|
||||
JavaSdkVersion version, ModuleChunk chunk, boolean annotationProcessorsEnabled) {
|
||||
final List<String> additionalOptions = new ArrayList<String>();
|
||||
StringTokenizer tokenizer = new StringTokenizer(javacSettings.getOptionsString(project), " ");
|
||||
StringTokenizer tokenizer = new StringTokenizer(javacSettings.getOptionsString(chunk), " ");
|
||||
if (!version.isAtLeast(JavaSdkVersion.JDK_1_6)) {
|
||||
isAnnotationProcessing = false; // makes no sense for these versions
|
||||
annotationProcessorsEnabled = false;
|
||||
}
|
||||
if (isAnnotationProcessing) {
|
||||
final CompilerConfiguration config = CompilerConfiguration.getInstance(project);
|
||||
final CompilerConfiguration config = CompilerConfiguration.getInstance(chunk.getProject());
|
||||
additionalOptions.add("-Xprefer:source");
|
||||
additionalOptions.add("-implicit:none");
|
||||
additionalOptions.add("-proc:only");
|
||||
|
||||
+10
-9
@@ -15,11 +15,12 @@
|
||||
*/
|
||||
package com.intellij.compiler.impl.javaCompiler.javac;
|
||||
|
||||
import com.intellij.compiler.CompilerEncodingService;
|
||||
import com.intellij.compiler.impl.javaCompiler.ModuleChunk;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.openapi.vfs.encoding.EncodingProjectManager;
|
||||
import com.intellij.util.Chunk;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
@@ -37,7 +38,7 @@ public class JavacSettings {
|
||||
|
||||
private boolean myTestsUseExternalCompiler = false;
|
||||
|
||||
public Collection<String> getOptions(Project project) {
|
||||
public Collection<String> getOptions(Chunk<Module> chunk) {
|
||||
List<String> options = new ArrayList<String>();
|
||||
if (DEBUGGING_INFO) {
|
||||
options.add("-g");
|
||||
@@ -61,10 +62,10 @@ public class JavacSettings {
|
||||
}
|
||||
}
|
||||
if (!isEncodingSet && acceptEncoding()) {
|
||||
final Charset ideCharset = EncodingProjectManager.getInstance(project).getDefaultCharset();
|
||||
if (ideCharset != null && !Comparing.equal(CharsetToolkit.getDefaultSystemCharset(), ideCharset)) {
|
||||
final Charset charset = CompilerEncodingService.getPreferredModuleEncoding(chunk);
|
||||
if (charset != null) {
|
||||
options.add("-encoding");
|
||||
options.add(ideCharset.name());
|
||||
options.add(charset.name());
|
||||
}
|
||||
}
|
||||
return options;
|
||||
@@ -78,9 +79,9 @@ public class JavacSettings {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getOptionsString(final Project project) {
|
||||
public String getOptionsString(final ModuleChunk chunk) {
|
||||
final StringBuilder options = new StringBuilder();
|
||||
for (String option : getOptions(project)) {
|
||||
for (String option : getOptions(chunk)) {
|
||||
if (options.length() > 0) {
|
||||
options.append(" ");
|
||||
}
|
||||
|
||||
+1
-1
@@ -202,7 +202,7 @@ public class JikesCompiler extends ExternalCompiler {
|
||||
commandLine.add(outputPath.replace('/', File.separatorChar));
|
||||
|
||||
JikesSettings jikesSettings = JikesConfiguration.getSettings(myProject);
|
||||
StringTokenizer tokenizer = new StringTokenizer(jikesSettings.getOptionsString(myProject), " ");
|
||||
StringTokenizer tokenizer = new StringTokenizer(jikesSettings.getOptionsString(chunk), " ");
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
commandLine.add(tokenizer.nextToken());
|
||||
}
|
||||
|
||||
+4
-3
@@ -19,7 +19,8 @@ import com.intellij.compiler.impl.javaCompiler.javac.JavacSettings;
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.openapi.components.StorageScheme;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.util.Chunk;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
@@ -34,8 +35,8 @@ public class JikesSettings extends JavacSettings {
|
||||
public String JIKES_PATH = "";
|
||||
public boolean IS_EMACS_ERRORS_MODE = true;
|
||||
|
||||
public Collection<String> getOptions(Project project) {
|
||||
final Collection<String> options = super.getOptions(project);
|
||||
public Collection<String> getOptions(Chunk<Module> chunk) {
|
||||
final Collection<String> options = super.getOptions(chunk);
|
||||
if(IS_EMACS_ERRORS_MODE) {
|
||||
options.add("+E");
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Chunk;
|
||||
import com.intellij.util.PathsList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -276,7 +277,6 @@ public class RmicCompiler implements ClassPostProcessingCompiler{
|
||||
return successfullyCompiledItems.toArray(new RmicProcessingItem[successfullyCompiledItems.size()]);
|
||||
}
|
||||
|
||||
// todo: Module -> ModuleChunk
|
||||
private static String[] createStartupCommand(final Module module, final String outputPath, final RmicProcessingItem[] items) {
|
||||
final Sdk jdk = ModuleRootManager.getInstance(module).getSdk();
|
||||
|
||||
@@ -296,7 +296,7 @@ public class RmicCompiler implements ClassPostProcessingCompiler{
|
||||
commandLine.add("-verbose");
|
||||
|
||||
final Project project = module.getProject();
|
||||
ContainerUtil.addAll(commandLine, RmicConfiguration.getSettings(project).getOptions(project));
|
||||
ContainerUtil.addAll(commandLine, RmicConfiguration.getSettings(project).getOptions(new Chunk<Module>(module)));
|
||||
|
||||
commandLine.add("-classpath");
|
||||
|
||||
|
||||
@@ -19,7 +19,8 @@ import com.intellij.compiler.impl.javaCompiler.javac.JavacSettings;
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.openapi.components.StorageScheme;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.util.Chunk;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
@@ -38,8 +39,8 @@ public class RmicSettings extends JavacSettings {
|
||||
DEPRECATION = false; // in this configuration deprecation is false by default
|
||||
}
|
||||
|
||||
public Collection<String> getOptions(Project project) {
|
||||
final Collection<String> options = super.getOptions(project);
|
||||
public Collection<String> getOptions(Chunk<Module> chunk) {
|
||||
final Collection<String> options = super.getOptions(chunk);
|
||||
if(GENERATE_IIOP_STUBS) {
|
||||
options.add("-iiop");
|
||||
}
|
||||
|
||||
+7
-1
@@ -770,10 +770,16 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
Collection<AnAction> actionsFromExtensions = new ArrayList<AnAction>();
|
||||
for (final ModuleStructureExtension extension : ModuleStructureExtension.EP_NAME.getExtensions()) {
|
||||
result.addAll(extension.createAddActions(selectedNodeRetriever, TREE_UPDATER, myProject, myRoot));
|
||||
actionsFromExtensions.addAll(extension.createAddActions(selectedNodeRetriever, TREE_UPDATER, myProject, myRoot));
|
||||
}
|
||||
|
||||
if (!actionsFromExtensions.isEmpty() && !result.isEmpty()) {
|
||||
result.add(new Separator());
|
||||
}
|
||||
result.addAll(actionsFromExtensions);
|
||||
return result.toArray(new AnAction[result.size()]);
|
||||
}
|
||||
};
|
||||
|
||||
+13
-4
@@ -27,6 +27,7 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -35,7 +36,7 @@ import java.util.List;
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
class ConstructorInsertHandler implements InsertHandler<LookupElementDecorator<LookupItem>> {
|
||||
public class ConstructorInsertHandler implements InsertHandler<LookupElementDecorator<LookupItem>> {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.ConstructorInsertHandler");
|
||||
public static final ConstructorInsertHandler SMART_INSTANCE = new ConstructorInsertHandler(true);
|
||||
public static final ConstructorInsertHandler BASIC_INSTANCE = new ConstructorInsertHandler(false);
|
||||
@@ -169,6 +170,7 @@ class ConstructorInsertHandler implements InsertHandler<LookupElementDecorator<L
|
||||
return hasParams;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Runnable generateAnonymousBody(final Editor editor, final PsiFile file) {
|
||||
final Project project = file.getProject();
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments();
|
||||
@@ -180,13 +182,20 @@ class ConstructorInsertHandler implements InsertHandler<LookupElementDecorator<L
|
||||
PsiElement parent = element.getParent();
|
||||
if (!(parent instanceof PsiAnonymousClass)) return null;
|
||||
|
||||
try{
|
||||
return genAnonymousBodyFor((PsiAnonymousClass)parent, editor, file, project);
|
||||
}
|
||||
|
||||
public static Runnable genAnonymousBodyFor(PsiAnonymousClass parent,
|
||||
final Editor editor,
|
||||
final PsiFile file,
|
||||
final Project project) {
|
||||
try {
|
||||
CodeStyleManager.getInstance(project).reformat(parent);
|
||||
}
|
||||
catch(IncorrectOperationException e){
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
offset = parent.getTextRange().getEndOffset() - 1;
|
||||
int offset = parent.getTextRange().getEndOffset() - 1;
|
||||
editor.getCaretModel().moveToOffset(offset);
|
||||
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
|
||||
editor.getSelectionModel().removeSelection();
|
||||
|
||||
@@ -17,7 +17,7 @@ package com.intellij.codeInsight.generation;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageUtils;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.StdLanguages;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
@@ -109,7 +109,7 @@ public class GenerateMembersUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <T extends GenerationInfo> List<T> insertMembersBeforeAnchor(PsiClass aClass, PsiElement anchor, @NotNull List<T> memberPrototypes) throws IncorrectOperationException {
|
||||
public static <T extends GenerationInfo> List<T> insertMembersBeforeAnchor(PsiClass aClass, @Nullable PsiElement anchor, @NotNull List<T> memberPrototypes) throws IncorrectOperationException {
|
||||
boolean before = true;
|
||||
for (T memberPrototype : memberPrototypes) {
|
||||
memberPrototype.insert(aClass, anchor, before);
|
||||
@@ -280,7 +280,7 @@ public class GenerateMembersUtil {
|
||||
if (paramName == null) paramName = "p" + i;
|
||||
|
||||
PsiParameter newParameter = factory.createParameter(paramName, substituted);
|
||||
if (parameter.getLanguage() == StdLanguages.JAVA) {
|
||||
if (parameter.getLanguage() == JavaLanguage.INSTANCE) {
|
||||
PsiModifierList modifierList = newParameter.getModifierList();
|
||||
modifierList = (PsiModifierList)modifierList.replace(parameter.getModifierList());
|
||||
processAnnotations(project, modifierList);
|
||||
|
||||
+12
-4
@@ -26,6 +26,7 @@ import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.ex.BaseLocalInspectionTool;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -60,6 +61,8 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
|
||||
@Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_SETTER_PARAMETER = true;
|
||||
@Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS = true; // remains for test
|
||||
@SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD = true;
|
||||
|
||||
private static final Logger LOG = Logger.getInstance("#" + NullableStuffInspection.class.getName());
|
||||
|
||||
@NotNull
|
||||
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
|
||||
@@ -144,10 +147,10 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
|
||||
final PsiParameter[] parameters = setter.getParameterList().getParameters();
|
||||
assert parameters.length == 1 : setter.getText();
|
||||
final PsiParameter parameter = parameters[0];
|
||||
assert parameter != null : setter.getText();
|
||||
LOG.assertTrue(parameter != null, setter.getText());
|
||||
if (REPORT_NOT_ANNOTATED_GETTER && !AnnotationUtil.isAnnotated(parameter, manager.getAllAnnotations()) && !TypeConversionUtil.isPrimitiveAndNotNull(parameter.getType())) {
|
||||
final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier();
|
||||
assert nameIdentifier1 != null : parameter;
|
||||
assertValidElement(setter, parameter, nameIdentifier1);
|
||||
holder.registerProblem(nameIdentifier1,
|
||||
InspectionsBundle.message("inspection.nullable.problems.annotated.field.setter.parameter.not.annotated",
|
||||
StringUtil.getShortName(anno)),
|
||||
@@ -157,7 +160,7 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
|
||||
if (PropertyUtils.isSimpleSetter(setter)) {
|
||||
if (annotated.isDeclaredNotNull && manager.isNullable(parameter, false)) {
|
||||
final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier();
|
||||
assert nameIdentifier1 != null : parameter;
|
||||
assertValidElement(setter, parameter, nameIdentifier1);
|
||||
holder.registerProblem(nameIdentifier1, InspectionsBundle.message(
|
||||
"inspection.nullable.problems.annotated.field.setter.parameter.conflict",
|
||||
StringUtil.getShortName(anno), nullableSimpleName),
|
||||
@@ -166,7 +169,7 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
|
||||
}
|
||||
else if (annotated.isDeclaredNullable && manager.isNotNull(parameter, false)) {
|
||||
final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier();
|
||||
assert nameIdentifier1 != null : parameter;
|
||||
assertValidElement(setter, parameter, nameIdentifier1);
|
||||
holder.registerProblem(nameIdentifier1, InspectionsBundle.message(
|
||||
"inspection.nullable.problems.annotated.field.setter.parameter.conflict", StringUtil.getShortName(anno), notNullSimpleName),
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
|
||||
@@ -241,6 +244,11 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
|
||||
}
|
||||
}
|
||||
|
||||
private void assertValidElement(PsiMethod setter, PsiParameter parameter, PsiIdentifier nameIdentifier1) {
|
||||
LOG.assertTrue(nameIdentifier1 != null, setter.getText());
|
||||
LOG.assertTrue(parameter.isPhysical(), setter.getText());
|
||||
}
|
||||
|
||||
public PsiAssignmentExpression getAssignmentExpressionIfOnAssignmentLefthand(PsiExpression expression) {
|
||||
PsiElement parent = PsiTreeUtil.skipParentsOfType(expression, PsiParenthesizedExpression.class);
|
||||
if (!(parent instanceof PsiAssignmentExpression)) {
|
||||
|
||||
+4
@@ -74,6 +74,10 @@ public class JavaMoveDirectoryWithClassesHelper extends MoveDirectoryWithClasses
|
||||
if (!(file instanceof PsiClassOwner)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!JspPsiUtil.isInJspFile(file)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (PsiClass psiClass : ((PsiClassOwner)file).getClasses()) {
|
||||
final PsiClass newClass = MoveClassesOrPackagesUtil.doMoveClass(psiClass, moveDestination);
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.psi;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Evgeny Gerashchenko
|
||||
* @since 3/20/12
|
||||
*/
|
||||
public interface ClsFileDecompiledPsiFileProvider {
|
||||
ExtensionPointName<ClsFileDecompiledPsiFileProvider> EP_NAME = ExtensionPointName.create("com.intellij.psi.clsDecompiledFileProvider");
|
||||
|
||||
/**
|
||||
* Returns decompiled PSI associated with this classfile
|
||||
*
|
||||
* @param clsFile instance of ClsFile
|
||||
* @return decompiled PSI file
|
||||
*/
|
||||
@Nullable
|
||||
PsiFile getDecompiledPsiFile(@NotNull PsiJavaFile clsFile);
|
||||
}
|
||||
@@ -12,7 +12,6 @@
|
||||
<orderEntry type="module" module-name="resources-en" />
|
||||
<orderEntry type="library" name="Guava" level="project" />
|
||||
<orderEntry type="library" name="asm" level="project" />
|
||||
<orderEntry type="module" module-name="platform-api" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -26,8 +26,6 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.fileTypes.ContentBasedClassFileProcessor;
|
||||
import com.intellij.openapi.fileTypes.ContentBasedFileSubstitutor;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.progress.NonCancelableSection;
|
||||
import com.intellij.openapi.progress.ProgressIndicatorProvider;
|
||||
@@ -327,12 +325,10 @@ public class ClsFileImpl extends ClsRepositoryPsiElement<PsiClassHolderFileStub>
|
||||
|
||||
@Override
|
||||
public PsiFile getDecompiledPsiFile() {
|
||||
for (ContentBasedFileSubstitutor processor : Extensions.getExtensions(ContentBasedFileSubstitutor.EP_NAME)) {
|
||||
if (processor instanceof ContentBasedClassFileProcessor && processor.isApplicable(getProject(), getVirtualFile())) {
|
||||
PsiFile decompiledPsiFile = ((ContentBasedClassFileProcessor)processor).getDecompiledPsiFile(this);
|
||||
if (decompiledPsiFile != null) {
|
||||
return decompiledPsiFile;
|
||||
}
|
||||
for (ClsFileDecompiledPsiFileProvider provider : Extensions.getExtensions(ClsFileDecompiledPsiFileProvider.EP_NAME)) {
|
||||
PsiFile decompiledPsiFile = provider.getDecompiledPsiFile(this);
|
||||
if (decompiledPsiFile != null) {
|
||||
return decompiledPsiFile;
|
||||
}
|
||||
}
|
||||
return (PsiFile) getMirror();
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.intellij.lang.annotations.MagicConstant;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class JavaCodeFragmentFactory {
|
||||
public static JavaCodeFragmentFactory getInstance(Project project) {
|
||||
@@ -49,7 +50,7 @@ public abstract class JavaCodeFragmentFactory {
|
||||
* @return the created code fragment.
|
||||
*/
|
||||
@NotNull
|
||||
public abstract JavaCodeFragment createCodeBlockCodeFragment(@NotNull String text, PsiElement context, boolean isPhysical);
|
||||
public abstract JavaCodeFragment createCodeBlockCodeFragment(@NotNull String text, @Nullable PsiElement context, boolean isPhysical);
|
||||
|
||||
/**
|
||||
* Flag for {@linkplain #createTypeCodeFragment(String, PsiElement, boolean, int)} - allows void type.
|
||||
|
||||
@@ -65,7 +65,7 @@ public abstract class IntervalTreeImpl<T extends MutableInterval> extends RedBla
|
||||
|
||||
private final IntervalTreeImpl<E> myIntervalTree;
|
||||
|
||||
public IntervalNode(IntervalTreeImpl<E> intervalTree, @NotNull E key, int start, int end) {
|
||||
public IntervalNode(@NotNull IntervalTreeImpl<E> intervalTree, @NotNull E key, int start, int end) {
|
||||
// maxEnd == 0 so to not disrupt existing maxes
|
||||
myIntervalTree = intervalTree;
|
||||
myStart = start;
|
||||
|
||||
@@ -28,7 +28,7 @@ public class RangeMarkerImpl extends UserDataHolderBase implements RangeMarkerEx
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.RangeMarkerImpl");
|
||||
|
||||
protected final DocumentEx myDocument;
|
||||
protected RangeMarkerTree<RangeMarkerEx>.RMNode myNode;
|
||||
protected RangeMarkerTree.RMNode<RangeMarkerEx> myNode;
|
||||
|
||||
private final long myId;
|
||||
private static final StripedIDGenerator counter = new StripedIDGenerator();
|
||||
@@ -91,7 +91,7 @@ public class RangeMarkerImpl extends UserDataHolderBase implements RangeMarkerEx
|
||||
|
||||
public void invalidate(final DocumentEvent e) {
|
||||
setValid(false);
|
||||
RangeMarkerTree<RangeMarkerEx>.RMNode node = myNode;
|
||||
RangeMarkerTree.RMNode<RangeMarkerEx> node = myNode;
|
||||
|
||||
if (node != null) {
|
||||
node.processAliveKeys(new Processor<RangeMarkerEx>() {
|
||||
|
||||
@@ -88,10 +88,10 @@ public class RangeMarkerTree<T extends RangeMarkerEx> extends IntervalTreeImpl<T
|
||||
|
||||
private static final int DUPLICATE_LIMIT = 30; // assertion: no more than DUPLICATE_LIMIT range markers are allowed to be registered at given (start, end)
|
||||
@Override
|
||||
public RangeMarkerTree<T>.RMNode addInterval(@NotNull T interval, int start, int end, boolean greedyToLeft, boolean greedyToRight, int layer) {
|
||||
public RMNode<T> addInterval(@NotNull T interval, int start, int end, boolean greedyToLeft, boolean greedyToRight, int layer) {
|
||||
RangeMarkerImpl marker = (RangeMarkerImpl)interval;
|
||||
marker.setValid(true);
|
||||
RangeMarkerTree<T>.RMNode node = (RMNode)super.addInterval(interval, start, end, greedyToLeft, greedyToRight, layer);
|
||||
RMNode<T> node = (RMNode)super.addInterval(interval, start, end, greedyToLeft, greedyToRight, layer);
|
||||
|
||||
if (DEBUG && node.intervals.size() > DUPLICATE_LIMIT) {
|
||||
l.readLock().lock();
|
||||
@@ -113,7 +113,7 @@ public class RangeMarkerTree<T extends RangeMarkerEx> extends IntervalTreeImpl<T
|
||||
}
|
||||
return node;
|
||||
}
|
||||
private String errMsg(RMNode node) {
|
||||
private String errMsg(RMNode<T> node) {
|
||||
@NonNls final StringBuilder msg = new StringBuilder();
|
||||
final AtomicInteger alive = new AtomicInteger();
|
||||
node.processAliveKeys(new Processor<Object>() {
|
||||
@@ -135,8 +135,8 @@ public class RangeMarkerTree<T extends RangeMarkerEx> extends IntervalTreeImpl<T
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected RMNode createNewNode(@NotNull T key, int start, int end, boolean greedyToLeft, boolean greedyToRight, int layer) {
|
||||
return new RMNode(key, start, end, greedyToLeft, greedyToRight);
|
||||
protected RMNode<T> createNewNode(@NotNull T key, int start, int end, boolean greedyToLeft, boolean greedyToRight, int layer) {
|
||||
return new RMNode<T>(this, key, start, end, greedyToLeft, greedyToRight);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -146,21 +146,26 @@ public class RangeMarkerTree<T extends RangeMarkerEx> extends IntervalTreeImpl<T
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RangeMarkerTree<T>.RMNode lookupNode(@NotNull T key) {
|
||||
return (RMNode)((RangeMarkerImpl)key).myNode;
|
||||
protected RMNode<T> lookupNode(@NotNull T key) {
|
||||
return (RMNode<T>)((RangeMarkerImpl)key).myNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setNode(@NotNull T key, IntervalNode<T> intervalNode) {
|
||||
((RangeMarkerImpl)key).myNode = (RangeMarkerTree.RMNode)intervalNode;
|
||||
((RangeMarkerImpl)key).myNode = (RMNode)intervalNode;
|
||||
}
|
||||
|
||||
public class RMNode extends IntervalTreeImpl.IntervalNode<T> {
|
||||
static class RMNode<T extends RangeMarkerEx> extends IntervalTreeImpl.IntervalNode<T> {
|
||||
private final boolean isExpandToLeft;
|
||||
private final boolean isExpandToRight;
|
||||
|
||||
public RMNode(@NotNull T key, int start, int end, boolean greedyToLeft, boolean greedyToRight) {
|
||||
super(RangeMarkerTree.this, key, start, end);
|
||||
public RMNode(@NotNull RangeMarkerTree<T> rangeMarkerTree,
|
||||
@NotNull T key,
|
||||
int start,
|
||||
int end,
|
||||
boolean greedyToLeft,
|
||||
boolean greedyToRight) {
|
||||
super(rangeMarkerTree, key, start, end);
|
||||
isExpandToLeft = greedyToLeft;
|
||||
isExpandToRight = greedyToRight;
|
||||
}
|
||||
@@ -227,7 +232,7 @@ public class RangeMarkerTree<T extends RangeMarkerEx> extends IntervalTreeImpl<T
|
||||
if (marker == null) continue; // node remains removed from the tree
|
||||
marker.documentChanged(e);
|
||||
if (marker.isValid()) {
|
||||
RMNode insertedNode = (RMNode)findOrInsert(node);
|
||||
RMNode<T> insertedNode = (RMNode)findOrInsert(node);
|
||||
// can change if two range become the one
|
||||
if (insertedNode != node) {
|
||||
// merge happened
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.profile;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.components.StateSplitter;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -204,8 +205,14 @@ public abstract class DefaultProjectProfileManager extends ProjectProfileManager
|
||||
return profile;
|
||||
}
|
||||
|
||||
public void addProfilesListener(ProfileChangeAdapter profilesListener) {
|
||||
public void addProfilesListener(final ProfileChangeAdapter profilesListener, Disposable parent) {
|
||||
myProfilesListener.add(profilesListener);
|
||||
Disposer.register(parent, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
myProfilesListener.remove(profilesListener);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void removeProfilesListener(ProfileChangeAdapter profilesListener) {
|
||||
|
||||
@@ -63,6 +63,7 @@ import com.intellij.openapi.vfs.VirtualFilePropertyEvent;
|
||||
import com.intellij.profile.Profile;
|
||||
import com.intellij.profile.ProfileChangeAdapter;
|
||||
import com.intellij.profile.codeInspection.InspectionProfileManager;
|
||||
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiDocumentManagerImpl;
|
||||
import com.intellij.psi.search.scope.packageSet.NamedScopesHolder;
|
||||
@@ -229,8 +230,9 @@ class DaemonListeners implements Disposable {
|
||||
CommandProcessor.getInstance().addCommandListener(new MyCommandListener(), this);
|
||||
ApplicationListener applicationListener = new MyApplicationListener();
|
||||
ApplicationManager.getApplication().addApplicationListener(applicationListener, this);
|
||||
EditorColorsManager.getInstance().addEditorColorsListener(new MyEditorColorsListener(),this);
|
||||
EditorColorsManager.getInstance().addEditorColorsListener(new MyEditorColorsListener(), this);
|
||||
InspectionProfileManager.getInstance().addProfileChangeListener(new MyProfileChangeListener(), this);
|
||||
InspectionProjectProfileManager.getInstance(project).addProfilesListener(new MyProfileChangeListener(), this);
|
||||
TodoConfiguration.getInstance().addPropertyChangeListener(new MyTodoListener(), this);
|
||||
ActionManagerEx.getInstanceEx().addAnActionListener(new MyAnActionListener(), this);
|
||||
VirtualFileManager.getInstance().addVirtualFileListener(new VirtualFileAdapter() {
|
||||
|
||||
@@ -54,7 +54,7 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
|
||||
private final Map<String, Color> ourRendererColors = new THashMap<String, Color>();
|
||||
@NonNls private static final String COLOR = "color";
|
||||
|
||||
private final TObjectIntHashMap<HighlightSeverity> myOrder = new TObjectIntHashMap<HighlightSeverity>();
|
||||
private final OrderMap myOrder = new OrderMap();
|
||||
private JDOMExternalizableStringList myReadOrder;
|
||||
|
||||
private static final Map<String, HighlightInfoType> STANDARD_SEVERITIES = new THashMap<String, HighlightInfoType>();
|
||||
@@ -301,13 +301,15 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
|
||||
|
||||
@Override
|
||||
public int compare(final HighlightSeverity s1, final HighlightSeverity s2) {
|
||||
TObjectIntHashMap<HighlightSeverity> order = getOrder();
|
||||
return order.get(s1) - order.get(s2);
|
||||
OrderMap order = getOrder();
|
||||
int o1 = order.getOrder(s1, -1);
|
||||
int o2 = order.getOrder(s2, -1);
|
||||
return o1 - o2;
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
private TObjectIntHashMap<HighlightSeverity> getOrder() {
|
||||
private OrderMap getOrder() {
|
||||
if (myOrder.isEmpty()) {
|
||||
List<HighlightSeverity> order = getDefaultOrder();
|
||||
setFromList(order);
|
||||
@@ -414,4 +416,11 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private static class OrderMap extends TObjectIntHashMap<HighlightSeverity> {
|
||||
private int getOrder(@NotNull HighlightSeverity severity, int defaultOrder) {
|
||||
int index = index(severity);
|
||||
return index < 0 ? defaultOrder : _values[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -80,11 +80,10 @@ public class WholeFileLocalInspectionsPassFactory extends AbstractProjectCompone
|
||||
myFileTools.clear();
|
||||
}
|
||||
};
|
||||
myProfileManager.addProfilesListener(myProfilesListener);
|
||||
myProfileManager.addProfilesListener(myProfilesListener, myProject);
|
||||
Disposer.register(myProject, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
myProfileManager.removeProfilesListener(myProfilesListener);
|
||||
myFileTools.clear();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -87,7 +87,11 @@ public class ProblemDescriptorImpl extends CommonProblemDescriptorImpl implement
|
||||
assertPhysical(startElement);
|
||||
if (startElement != endElement) assertPhysical(endElement);
|
||||
|
||||
if (startElement.getTextRange().getStartOffset() >= endElement.getTextRange().getEndOffset()) {
|
||||
final TextRange startElementRange = startElement.getTextRange();
|
||||
LOG.assertTrue(startElementRange != null, startElement);
|
||||
final TextRange endElementRange = endElement.getTextRange();
|
||||
LOG.assertTrue(endElementRange != null, endElement);
|
||||
if (startElementRange.getStartOffset() >= endElementRange.getEndOffset()) {
|
||||
if (!(startElement instanceof PsiFile && endElement instanceof PsiFile)) {
|
||||
LOG.error("Empty PSI elements should not be passed to createDescriptor. Start: " + startElement + ", end: " + endElement);
|
||||
}
|
||||
|
||||
+5
-1
@@ -141,7 +141,11 @@ public class InspectionResultsViewComparator implements Comparator {
|
||||
|
||||
private static int compareEntity(final RefEntity entity, final PsiElement element) {
|
||||
if (entity instanceof RefElement) {
|
||||
return PsiUtilCore.compareElementsByPosition(((RefElement)entity).getElement(), element);
|
||||
final PsiElement psiElement = ((RefElement)entity).getElement();
|
||||
if (psiElement != null && element != null) {
|
||||
return PsiUtilCore.compareElementsByPosition(psiElement, element);
|
||||
}
|
||||
if (element == null) return psiElement == null ? 0 : 1;
|
||||
}
|
||||
if (element instanceof PsiQualifiedNamedElement) {
|
||||
return StringUtil.compare(entity.getQualifiedName(), ((PsiQualifiedNamedElement)element).getQualifiedName(), true);
|
||||
|
||||
@@ -49,7 +49,7 @@ public class OrderRootsCache {
|
||||
@Nullable
|
||||
public VirtualFile[] getCachedRoots(OrderRootType rootType, int flags) {
|
||||
final VirtualFilePointerContainer cached = myRoots.get(new CacheKey(rootType, flags));
|
||||
return cached != null ? cached.getFiles() : null;
|
||||
return cached == null ? null : cached.getFiles();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -67,7 +67,7 @@ public class OrderRootsCache {
|
||||
|
||||
private static final class CacheKey {
|
||||
private final OrderRootType myRootType;
|
||||
private int myFlags;
|
||||
private final int myFlags;
|
||||
|
||||
private CacheKey(OrderRootType rootType, int flags) {
|
||||
myRootType = rootType;
|
||||
|
||||
+6
-1
@@ -16,6 +16,7 @@
|
||||
package com.intellij.openapi.vcs.checkin;
|
||||
|
||||
import com.intellij.openapi.components.StorageScheme;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ex.ProjectEx;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
@@ -70,6 +71,10 @@ public class BeforeCheckinHandlerUtil {
|
||||
|
||||
private static boolean isFileUnderSourceRoot(@NotNull Project project, @NotNull VirtualFile file) {
|
||||
ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex();
|
||||
return index.isInSource(file) && !index.isInLibrarySource(file);
|
||||
if (StdFileTypes.JAVA == file.getFileType()) {
|
||||
return index.isInSource(file) && !index.isInLibrarySource(file);
|
||||
} else {
|
||||
return index.isInContent(file) && !index.isInLibrarySource(file) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -356,7 +356,7 @@ public class InspectionProfileManager extends ApplicationProfileManager implemen
|
||||
return mySchemesManager;
|
||||
}
|
||||
|
||||
public void onProfilesChanged() {
|
||||
public static void onProfilesChanged() {
|
||||
//cleanup caches blindly for all projects in case ide profile was modified
|
||||
for (Project project : ProjectManager.getInstance().getOpenProjects()) {
|
||||
HighlightingSettingsPerFile.getInstance(project).cleanProfileSettings();
|
||||
|
||||
+1
@@ -53,6 +53,7 @@ public class ProjectInspectionToolsConfigurable extends InspectionToolsConfigura
|
||||
myProfileManager.setRootProfile(profileName);
|
||||
myProjectProfileManager.setProjectProfile(null);
|
||||
}
|
||||
InspectionProfileManager.onProfilesChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.intellij.openapi.progress.util.ProgressIndicatorBase;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.startup.StartupManager;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.wm.ex.ProgressIndicatorEx;
|
||||
import com.intellij.pom.PomManager;
|
||||
@@ -407,6 +408,12 @@ public class DocumentCommitThread implements Runnable, Disposable {
|
||||
catch (Exception e) {
|
||||
s += e;
|
||||
}
|
||||
try {
|
||||
Disposer.dispose(project);
|
||||
}
|
||||
catch (Throwable ignored) {
|
||||
// do not fill log with endless exceptions
|
||||
}
|
||||
throw new RuntimeException(s);
|
||||
}
|
||||
|
||||
|
||||
-9
@@ -34,13 +34,4 @@ public interface ContentBasedClassFileProcessor extends ContentBasedFileSubstitu
|
||||
*/
|
||||
@NotNull
|
||||
SyntaxHighlighter createHighlighter(Project project, VirtualFile vFile);
|
||||
|
||||
/**
|
||||
* Returns decompiled PSI associated with this classfile
|
||||
*
|
||||
* @param clsFile instance of ClsFile
|
||||
* @return decompiled PSI file
|
||||
*/
|
||||
@Nullable
|
||||
PsiFile getDecompiledPsiFile(PsiFile clsFile);
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
|
||||
DocumentBulkUpdateListener bulkUpdateListener = new DocumentBulkUpdateListener() {
|
||||
@Override
|
||||
public void updateStarted(@NotNull Document doc) {
|
||||
if (doc != myEditor.getDocument() && myOffset >= doc.getTextLength()) return;
|
||||
if (doc != myEditor.getDocument() && myOffset >= doc.getTextLength() || savedBeforeBulkCaretMarker != null) return;
|
||||
savedBeforeBulkCaretMarker = doc.createRangeMarker(myOffset, myOffset);
|
||||
}
|
||||
@Override
|
||||
@@ -237,7 +237,7 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
|
||||
}
|
||||
|
||||
public void setIgnoreWrongMoves(boolean ignoreWrongMoves) {
|
||||
this.myIgnoreWrongMoves = ignoreWrongMoves;
|
||||
myIgnoreWrongMoves = ignoreWrongMoves;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -695,9 +695,8 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
|
||||
moveToOffset(newLength, performSoftWrapAdjustment);
|
||||
}
|
||||
else {
|
||||
final int line;
|
||||
try {
|
||||
line = event.translateLineViaDiff(myLogicalCaret.line);
|
||||
final int line = event.translateLineViaDiff(myLogicalCaret.line);
|
||||
moveToLogicalPosition(new LogicalPosition(line, myLogicalCaret.column), performSoftWrapAdjustment, null, false);
|
||||
}
|
||||
catch (FilesTooBigForDiffException e1) {
|
||||
|
||||
+5
-4
@@ -44,19 +44,20 @@ public class RangeHighlighterTree extends RangeMarkerTree<RangeHighlighterEx> {
|
||||
@NotNull
|
||||
@Override
|
||||
protected RHNode createNewNode(@NotNull RangeHighlighterEx key, int start, int end, boolean greedyToLeft, boolean greedyToRight, int layer) {
|
||||
return new RHNode(key, start, end, greedyToLeft, greedyToRight,layer);
|
||||
return new RHNode(this, key, start, end, greedyToLeft, greedyToRight,layer);
|
||||
}
|
||||
|
||||
class RHNode extends RangeMarkerTree<RangeHighlighterEx>.RMNode {
|
||||
static class RHNode extends RMNode<RangeHighlighterEx> {
|
||||
final int myLayer;
|
||||
|
||||
public RHNode(@NotNull final RangeHighlighterEx key,
|
||||
public RHNode(@NotNull RangeHighlighterTree rangeMarkerTree,
|
||||
@NotNull final RangeHighlighterEx key,
|
||||
int start,
|
||||
int end,
|
||||
boolean greedyToLeft,
|
||||
boolean greedyToRight,
|
||||
int layer) {
|
||||
super(key, start, end, greedyToLeft, greedyToRight);
|
||||
super(rangeMarkerTree, key, start, end, greedyToLeft, greedyToRight);
|
||||
myLayer = layer;
|
||||
}
|
||||
|
||||
|
||||
+15
@@ -36,6 +36,7 @@ import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.ModificationTracker;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
@@ -65,6 +66,13 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager {
|
||||
private boolean myUseUTFGuessing = true;
|
||||
private boolean myNative2AsciiForPropertiesFiles;
|
||||
private Charset myDefaultCharsetForPropertiesFiles;
|
||||
private long myModificationCount;
|
||||
private final ModificationTracker myModificationTracker = new ModificationTracker() {
|
||||
@Override
|
||||
public long getModificationCount() {
|
||||
return myModificationCount;
|
||||
}
|
||||
};
|
||||
|
||||
public EncodingProjectManagerImpl(Project project, GeneralSettings generalSettings, EditorSettingsExternalizable editorSettings, PsiDocumentManager documentManager) {
|
||||
myProject = project;
|
||||
@@ -138,6 +146,7 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager {
|
||||
myEditorSettings.migrateCharsetSettingsTo(defaultManager);
|
||||
}
|
||||
}
|
||||
myModificationCount++;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -180,6 +189,10 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ModificationTracker getModificationTracker() {
|
||||
return myModificationTracker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEncoding(@Nullable VirtualFile virtualFileOrDir, @Nullable Charset charset) {
|
||||
if (charset == null) {
|
||||
@@ -188,6 +201,7 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager {
|
||||
else {
|
||||
myMapping.put(virtualFileOrDir, charset);
|
||||
}
|
||||
myModificationCount++;
|
||||
setAndSaveOrReload(virtualFileOrDir, charset);
|
||||
}
|
||||
|
||||
@@ -252,6 +266,7 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
myModificationCount++;
|
||||
}
|
||||
|
||||
//retrieves encoding for the Project node
|
||||
|
||||
+9
-5
@@ -25,6 +25,7 @@ import com.intellij.openapi.vfs.pointers.VirtualFilePointerContainer;
|
||||
import com.intellij.openapi.vfs.pointers.VirtualFilePointerListener;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.ContainerUtilRt;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -39,10 +40,10 @@ import java.util.List;
|
||||
*/
|
||||
public class VirtualFilePointerContainerImpl implements VirtualFilePointerContainer, Disposable {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.pointers.VirtualFilePointerContainer");
|
||||
@NotNull private final List<VirtualFilePointer> myList = new ArrayList<VirtualFilePointer>();
|
||||
@NotNull private final List<VirtualFilePointer> myList = ContainerUtilRt.createEmptyCOWList();
|
||||
private final List<VirtualFilePointer> myReadOnlyList = Collections.unmodifiableList(myList);
|
||||
private final VirtualFilePointerManagerImpl myVirtualFilePointerManager;
|
||||
private final Disposable myParent;
|
||||
@NotNull private final VirtualFilePointerManagerImpl myVirtualFilePointerManager;
|
||||
@NotNull private final Disposable myParent;
|
||||
private final VirtualFilePointerListener myListener;
|
||||
private VirtualFile[] myCachedDirectories;
|
||||
@NonNls private static final String URL_ATTR = "url";
|
||||
@@ -91,7 +92,7 @@ public class VirtualFilePointerContainerImpl implements VirtualFilePointerContai
|
||||
ContainerUtil.swapElements(myList, index, index + 1);
|
||||
}
|
||||
|
||||
private int indexOf(final String url) {
|
||||
private int indexOf(@NotNull final String url) {
|
||||
for (int i = 0; i < myList.size(); i++) {
|
||||
final VirtualFilePointer pointer = myList.get(i);
|
||||
if (url.equals(pointer.getUrl())) {
|
||||
@@ -134,7 +135,7 @@ public class VirtualFilePointerContainerImpl implements VirtualFilePointerContai
|
||||
@Override
|
||||
@NotNull
|
||||
public List<VirtualFilePointer> getList() {
|
||||
assert !myDisposed;
|
||||
assert !myDisposed;
|
||||
return myReadOnlyList;
|
||||
}
|
||||
|
||||
@@ -166,6 +167,7 @@ public class VirtualFilePointerContainerImpl implements VirtualFilePointerContai
|
||||
return myCachedUrls;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String[] calcUrls() {
|
||||
if (myList.isEmpty()) return ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
final ArrayList<String> result = new ArrayList<String>(myList.size());
|
||||
@@ -186,6 +188,7 @@ public class VirtualFilePointerContainerImpl implements VirtualFilePointerContai
|
||||
return myCachedFiles;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private VirtualFile[] calcFiles() {
|
||||
if (myList.isEmpty()) return VirtualFile.EMPTY_ARRAY;
|
||||
final ArrayList<VirtualFile> result = new ArrayList<VirtualFile>(myList.size());
|
||||
@@ -272,6 +275,7 @@ public class VirtualFilePointerContainerImpl implements VirtualFilePointerContai
|
||||
return myVirtualFilePointerManager.duplicate(virtualFilePointer, myParent, myListener);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@NonNls
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
+1
-1
@@ -318,7 +318,7 @@ class TabContentLayout extends ContentLayout {
|
||||
|
||||
@Nullable
|
||||
private static BufferedImage drawToBuffer(Rectangle r, boolean selected, boolean last, boolean prevSelected, boolean active) {
|
||||
if (r.width == 0 || r.height == 0) return null;
|
||||
if (r.width <= 0 || r.height <= 0) return null;
|
||||
BufferedImage image = new BufferedImage(r.width, r.height, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g2d = image.createGraphics();
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
@@ -532,6 +532,8 @@
|
||||
|
||||
<extensionPoint name="psi.clsCustomNavigationPolicy"
|
||||
interface="com.intellij.psi.impl.compiled.ClsCustomNavigationPolicy" />
|
||||
<extensionPoint name="psi.clsDecompiledFileProvider"
|
||||
interface="com.intellij.psi.ClsFileDecompiledPsiFileProvider"/>
|
||||
|
||||
<extensionPoint name="codeBlockProvider"
|
||||
beanClass="com.intellij.lang.LanguageExtensionPoint"/>
|
||||
|
||||
@@ -540,6 +540,7 @@
|
||||
<action id="DirDiffMenu.SetCopyToRight" class="com.intellij.openapi.diff.impl.dir.actions.popup.SetCopyToRight" text="Set Copy to Right" icon="/vcs/arrow_right.png"/>
|
||||
<action id="DirDiffMenu.SetCopyToLeft" class="com.intellij.openapi.diff.impl.dir.actions.popup.SetCopyToLeft" text="Set Copy to Left" icon="/vcs/arrow_left.png"/>
|
||||
<action id="DirDiffMenu.SetDelete" class="com.intellij.openapi.diff.impl.dir.actions.popup.SetDelete" text="Set Delete" icon="/vcs/remove.png"/>
|
||||
<action id="DirDiffMenu.SetDefault" class="com.intellij.openapi.diff.impl.dir.actions.popup.SetDefault" text="Set Default"/>
|
||||
</group>
|
||||
|
||||
<action id="Rerun" class="com.intellij.execution.runners.FakeRerunAction" text="Rerun"/>
|
||||
|
||||
@@ -41,6 +41,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
import javax.swing.plaf.TreeUI;
|
||||
import javax.swing.tree.*;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class TestTreeView extends Tree implements DataProvider, CopyProvider {
|
||||
private TestFrameworkRunningModel myModel;
|
||||
@@ -88,13 +90,14 @@ public abstract class TestTreeView extends Tree implements DataProvider, CopyPro
|
||||
if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) {
|
||||
TreePath[] paths = getSelectionPaths();
|
||||
if (paths != null && paths.length > 1) {
|
||||
final PsiElement[] els = new PsiElement[paths.length];
|
||||
int i = 0;
|
||||
final List<PsiElement> els = new ArrayList<PsiElement>(paths.length);
|
||||
for (TreePath path : paths) {
|
||||
AbstractTestProxy test = getSelectedTest(path);
|
||||
els[i++] = test != null ? (PsiElement)TestsUIUtil.getData(test, LangDataKeys.PSI_ELEMENT.getName(), myModel) : null;
|
||||
if (test != null) {
|
||||
els.add((PsiElement)TestsUIUtil.getData(test, LangDataKeys.PSI_ELEMENT.getName(), myModel));
|
||||
}
|
||||
}
|
||||
return els;
|
||||
return els.isEmpty() ? null : els.toArray(new PsiElement[els.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -429,6 +429,32 @@ public abstract class VcsVFSListener implements Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
// If a file is scheduled for deletion, and at the same time for copying or addition, don't delete it.
|
||||
// It happens during Overwrite command or undo of overwrite.
|
||||
private void dontDeleteAddedCopiedOrMovedFiles() {
|
||||
Collection<String> copiedAddedMoved = new ArrayList<String>();
|
||||
for (VirtualFile file : myCopyFromMap.keySet()) {
|
||||
copiedAddedMoved.add(file.getPath());
|
||||
}
|
||||
for (VirtualFile file : myAddedFiles) {
|
||||
copiedAddedMoved.add(file.getPath());
|
||||
}
|
||||
for (MovedFileInfo movedFileInfo : myMovedFiles) {
|
||||
copiedAddedMoved.add(movedFileInfo.myNewPath);
|
||||
}
|
||||
|
||||
for (Iterator<FilePath> iter = myDeletedFiles.iterator(); iter.hasNext(); ) {
|
||||
if (copiedAddedMoved.contains(iter.next().getPath())) {
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
for (Iterator<FilePath> iter = myDeletedWithoutConfirmFiles.iterator(); iter.hasNext(); ) {
|
||||
if (copiedAddedMoved.contains(iter.next().getPath())) {
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void commandFinished(final CommandEvent event) {
|
||||
if (myProject != event.getProject()) return;
|
||||
myCommandLevel--;
|
||||
@@ -444,6 +470,7 @@ public abstract class VcsVFSListener implements Disposable {
|
||||
finally {
|
||||
myCommandLevel--;
|
||||
}
|
||||
dontDeleteAddedCopiedOrMovedFiles();
|
||||
checkMovedAddedSourceBack();
|
||||
if (!myAddedFiles.isEmpty()) {
|
||||
executeAdd();
|
||||
@@ -479,5 +506,6 @@ public abstract class VcsVFSListener implements Disposable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -138,6 +138,15 @@ public class DirDiffElement {
|
||||
return mySourceLength < 0 ? null : String.valueOf(mySourceLength);
|
||||
}
|
||||
|
||||
public DirDiffOperation getDefaultOperation() {
|
||||
return myDefaultOperation;
|
||||
//if (myType == DType.SOURCE) return COPY_TO;
|
||||
//if (myType == DType.TARGET) return COPY_FROM;
|
||||
//if (myType == DType.CHANGED) return MERGE;
|
||||
//if (myType == DType.EQUAL) return EQUAL;
|
||||
//return NONE;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getTargetName() {
|
||||
return myType == DType.CHANGED || myType == DType.TARGET || myType == DType.EQUAL
|
||||
|
||||
+6
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.openapi.diff.impl.dir.actions.popup;
|
||||
|
||||
import com.intellij.openapi.diff.impl.dir.DirDiffElement;
|
||||
import com.intellij.openapi.diff.impl.dir.DirDiffOperation;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -27,4 +28,9 @@ public class SetCopyToLeft extends SetOperationToBase {
|
||||
protected DirDiffOperation getOperation() {
|
||||
return DirDiffOperation.COPY_FROM;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isEnabledFor(DirDiffElement element) {
|
||||
return element.getTarget() != null;
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.openapi.diff.impl.dir.actions.popup;
|
||||
|
||||
import com.intellij.openapi.diff.impl.dir.DirDiffElement;
|
||||
import com.intellij.openapi.diff.impl.dir.DirDiffOperation;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -27,4 +28,9 @@ public class SetCopyToRight extends SetOperationToBase {
|
||||
protected DirDiffOperation getOperation() {
|
||||
return DirDiffOperation.COPY_TO;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isEnabledFor(DirDiffElement element) {
|
||||
return element.getSource() != null;
|
||||
}
|
||||
}
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.openapi.diff.impl.dir.actions.popup;
|
||||
|
||||
import com.intellij.openapi.diff.impl.dir.DirDiffElement;
|
||||
import com.intellij.openapi.diff.impl.dir.DirDiffOperation;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Konstantin Bulenkov
|
||||
*/
|
||||
public class SetDefault extends SetOperationToBase {
|
||||
@NotNull
|
||||
@Override
|
||||
protected DirDiffOperation getOperation() {
|
||||
return DirDiffOperation.NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isEnabledFor(DirDiffElement element) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.openapi.diff.impl.dir.actions.popup;
|
||||
|
||||
import com.intellij.openapi.diff.impl.dir.DirDiffElement;
|
||||
import com.intellij.openapi.diff.impl.dir.DirDiffOperation;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -27,4 +28,9 @@ public class SetDelete extends SetOperationToBase {
|
||||
protected DirDiffOperation getOperation() {
|
||||
return DirDiffOperation.DELETE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isEnabledFor(DirDiffElement element) {
|
||||
return element.getSource() == null || element.getTarget() == null;
|
||||
}
|
||||
}
|
||||
|
||||
+18
-5
@@ -33,11 +33,16 @@ public abstract class SetOperationToBase extends AnAction {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
DirDiffOperation operation = getOperation();
|
||||
boolean setToDefault = operation == DirDiffOperation.NONE;
|
||||
final DirDiffTableModel model = getModel(e);
|
||||
final JTable table = getTable(e);
|
||||
assert model != null && table != null;
|
||||
for (DirDiffElement element : model.getSelectedElements()) {
|
||||
element.setOperation(operation);
|
||||
if (isEnabledFor(element)) {
|
||||
element.setOperation(setToDefault ? element.getDefaultOperation() : operation);
|
||||
} else {
|
||||
element.setOperation(DirDiffOperation.NONE);
|
||||
}
|
||||
}
|
||||
table.repaint();
|
||||
}
|
||||
@@ -46,14 +51,22 @@ public abstract class SetOperationToBase extends AnAction {
|
||||
protected abstract DirDiffOperation getOperation();
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
public final void update(AnActionEvent e) {
|
||||
final DirDiffTableModel model = getModel(e);
|
||||
final JTable table = getTable(e);
|
||||
e.getPresentation().setEnabled(table != null
|
||||
&& model != null
|
||||
&& !model.getSelectedElements().isEmpty());
|
||||
if (table != null && model != null) {
|
||||
for (DirDiffElement element : model.getSelectedElements()) {
|
||||
if (isEnabledFor(element)) {
|
||||
e.getPresentation().setEnabled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
e.getPresentation().setEnabled(false);
|
||||
}
|
||||
|
||||
protected abstract boolean isEnabledFor(DirDiffElement element);
|
||||
|
||||
@Nullable
|
||||
private static JTable getTable(AnActionEvent e) {
|
||||
return e.getData(DirDiffPanel.DIR_DIFF_TABLE);
|
||||
|
||||
@@ -299,6 +299,7 @@ public abstract class ChangesTreeList<T> extends JPanel {
|
||||
}
|
||||
});
|
||||
|
||||
final Set<Object> wasSelected = new HashSet<Object>(Arrays.asList(myList.getSelectedValues()));
|
||||
myList.setModel(new AbstractListModel() {
|
||||
@Override
|
||||
public int getSize() {
|
||||
@@ -310,6 +311,12 @@ public abstract class ChangesTreeList<T> extends JPanel {
|
||||
return sortedChanges.get(index);
|
||||
}
|
||||
});
|
||||
for (int i = 0; i < sortedChanges.size(); i++) {
|
||||
T t = sortedChanges.get(i);
|
||||
if (wasSelected.contains(t)) {
|
||||
myList.setSelectedIndex(i);
|
||||
}
|
||||
}
|
||||
|
||||
final DefaultTreeModel model = buildTreeModel(changes, myChangeDecorator);
|
||||
TreeState state = null;
|
||||
|
||||
@@ -92,7 +92,6 @@ public class XFramesView extends XDebugViewBase {
|
||||
CustomLineBorder border = new CustomLineBorder(CaptionPanel.CNT_ACTIVE_COLOR, 0, 0, 1, 0);
|
||||
myThreadsPanel.setBorder(border);
|
||||
myThreadsPanel.add(myToolbar.getComponent(), BorderLayout.EAST);
|
||||
myThreadsPanel.add(myThreadComboBox, BorderLayout.CENTER);
|
||||
myMainPanel.add(myThreadsPanel, BorderLayout.NORTH);
|
||||
|
||||
rebuildView(SessionEvent.RESUMED);
|
||||
@@ -155,12 +154,10 @@ public class XFramesView extends XDebugViewBase {
|
||||
}
|
||||
XExecutionStack activeExecutionStack = suspendContext.getActiveExecutionStack();
|
||||
myThreadComboBox.setSelectedItem(activeExecutionStack);
|
||||
final boolean invisible = executionStacks.length == 1 && StringUtil.isEmpty(executionStacks[0].getDisplayName());
|
||||
myThreadsPanel.removeAll();
|
||||
if (invisible) {
|
||||
myThreadsPanel.add(myToolbar.getComponent(), BorderLayout.WEST);
|
||||
} else {
|
||||
myThreadsPanel.add(myToolbar.getComponent(), BorderLayout.EAST);
|
||||
myThreadsPanel.add(myToolbar.getComponent(), BorderLayout.EAST);
|
||||
final boolean invisible = executionStacks.length == 1 && StringUtil.isEmpty(executionStacks[0].getDisplayName());
|
||||
if (!invisible) {
|
||||
myThreadsPanel.add(myThreadComboBox, BorderLayout.CENTER);
|
||||
}
|
||||
myToolbar.setAddSeparatorFirst(!invisible);
|
||||
|
||||
+5
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2011 Bas Leijdekkers
|
||||
* Copyright 2006-201@ Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -73,6 +73,10 @@ public class UnqualifiedFieldAccessInspection extends BaseInspection {
|
||||
if (field.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
return;
|
||||
}
|
||||
final PsiClass containingClass = field.getContainingClass();
|
||||
if (containingClass instanceof PsiAnonymousClass) {
|
||||
return;
|
||||
}
|
||||
registerError(expression);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2011 Bas Leijdekkers
|
||||
* Copyright 2006-2012 Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -68,6 +68,10 @@ public class UnqualifiedMethodAccessInspection extends BaseInspection {
|
||||
if (method.isConstructor() || method.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
return;
|
||||
}
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
if (containingClass instanceof PsiAnonymousClass) {
|
||||
return;
|
||||
}
|
||||
registerError(expression);
|
||||
}
|
||||
}
|
||||
|
||||
+13
@@ -9,4 +9,17 @@ public class UnqualifiedFieldAccess {
|
||||
final String s = String.valueOf(field.hashCode());
|
||||
System.out.println(s);
|
||||
}
|
||||
|
||||
void foo() {
|
||||
new Object() {
|
||||
int i;
|
||||
void foo() {
|
||||
new Object() {
|
||||
void foo() {
|
||||
i = 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+12
@@ -15,4 +15,16 @@ public class UnqualifiedMethodAccess extends JPanel {
|
||||
void foo(String s) {
|
||||
this.foo();
|
||||
}
|
||||
|
||||
void anonymous() {
|
||||
new Object() {
|
||||
void bar() {
|
||||
new Object() {
|
||||
void foo() {
|
||||
bar();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ public class GitBranch extends GitReference {
|
||||
super(name);
|
||||
myRemote = remote;
|
||||
myActive = active;
|
||||
myHash = new String(hash);
|
||||
myHash = new String(hash.trim());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.util.Processor;
|
||||
import com.intellij.vcsUtil.VcsUtil;
|
||||
import git4idea.GitBranch;
|
||||
import git4idea.branch.GitBranchesCollection;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -54,11 +55,9 @@ class GitRepositoryReader {
|
||||
// this format shouldn't appear, but we don't want to fail because of a space
|
||||
private static Pattern BRANCH_WEAK_PATTERN = Pattern.compile(" *(ref:)? */?refs/heads/(\\S+)");
|
||||
private static Pattern COMMIT_PATTERN = Pattern.compile("[0-9a-fA-F]+"); // commit hash
|
||||
private static Pattern PACKED_REFS_BRANCH_LINE = Pattern.compile("([0-9a-fA-F]+) (\\S+)"); // branch reference in .git/packed-refs
|
||||
private static Pattern PACKED_REFS_TAGREF_LINE = Pattern.compile("\\^[0-9a-fA-F]+"); // tag reference in .git/packed-refs
|
||||
|
||||
private static final String REFS_HEADS_PREFIX = "refs/heads/";
|
||||
private static final String REFS_REMOTES_PREFIX = "refs/remotes/";
|
||||
@NonNls private static final String REFS_HEADS_PREFIX = "refs/heads/";
|
||||
@NonNls private static final String REFS_REMOTES_PREFIX = "refs/remotes/";
|
||||
private static final int IO_RETRIES = 3; // number of retries before fail if an IOException happens during file read.
|
||||
|
||||
private final File myGitDir; // .git/
|
||||
@@ -146,7 +145,7 @@ class GitRepositoryReader {
|
||||
* and returns the {@link GitBranch} for the branch name written there, or null if these files don't exist.
|
||||
*/
|
||||
@Nullable
|
||||
private GitBranch readRebaseBranch(String rebaseDirName) {
|
||||
private GitBranch readRebaseBranch(@NonNls String rebaseDirName) {
|
||||
File rebaseDir = new File(myGitDir, rebaseDirName);
|
||||
if (!rebaseDir.exists()) {
|
||||
return null;
|
||||
@@ -197,7 +196,8 @@ class GitRepositoryReader {
|
||||
while ((line = reader.readLine()) != null) {
|
||||
final AtomicReference<String> hashRef = new AtomicReference<String>();
|
||||
parsePackedRefsLine(line, new PackedRefsLineResultHandler() {
|
||||
@Override public void handleResult(String hash, String branchName) {
|
||||
@Override
|
||||
public void handleResult(String hash, String branchName) {
|
||||
if (hash == null || branchName == null) {
|
||||
return;
|
||||
}
|
||||
@@ -436,26 +436,47 @@ class GitRepositoryReader {
|
||||
* Using a special handler may seem to be an overhead, but it is to avoid code duplication in two methods that parse packed-refs.
|
||||
*/
|
||||
private static void parsePackedRefsLine(String line, PackedRefsLineResultHandler resultHandler) {
|
||||
line = line.trim();
|
||||
if (line.startsWith("#")) { // ignoring comments
|
||||
resultHandler.handleResult(null, null);
|
||||
return;
|
||||
try {
|
||||
line = line.trim();
|
||||
char firstChar = line.isEmpty() ? 0 : line.charAt(0);
|
||||
if (firstChar == '#') { // ignoring comments
|
||||
return;
|
||||
}
|
||||
if (firstChar == '^') {
|
||||
// ignoring the hash which an annotated tag above points to
|
||||
return;
|
||||
}
|
||||
String hash = null;
|
||||
int i;
|
||||
for (i = 0; i < line.length(); i++) {
|
||||
char c = line.charAt(i);
|
||||
if (!Character.isLetterOrDigit(c)) {
|
||||
hash = line.substring(0, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
String branch = null;
|
||||
int start = i;
|
||||
if (hash != null && start < line.length() && line.charAt(start++) == ' ') {
|
||||
for (i = start; i < line.length(); i++) {
|
||||
char c = line.charAt(i);
|
||||
if (Character.isWhitespace(c)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
branch = line.substring(start, i);
|
||||
}
|
||||
|
||||
if (hash != null && branch != null) {
|
||||
resultHandler.handleResult(hash, branch);
|
||||
}
|
||||
else {
|
||||
LOG.info("Ignoring invalid packed-refs line: [" + line + "]");
|
||||
}
|
||||
}
|
||||
if (PACKED_REFS_TAGREF_LINE.matcher(line).matches()) { // ignoring the hash which an annotated tag above points to
|
||||
finally {
|
||||
resultHandler.handleResult(null, null);
|
||||
return;
|
||||
}
|
||||
Matcher matcher = PACKED_REFS_BRANCH_LINE.matcher(line);
|
||||
if (matcher.matches()) {
|
||||
String hash = matcher.group(1);
|
||||
String branch = matcher.group(2);
|
||||
resultHandler.handleResult(hash, branch);
|
||||
} else {
|
||||
LOG.info("Ignoring invalid packed-refs line: [" + line + "]");
|
||||
resultHandler.handleResult(null, null);
|
||||
return;
|
||||
}
|
||||
resultHandler.handleResult(null, null);
|
||||
}
|
||||
|
||||
private interface PackedRefsLineResultHandler {
|
||||
|
||||
@@ -151,8 +151,8 @@ public class GitRepositoryReaderTest extends LightIdeaTestCase {
|
||||
private final String myHash;
|
||||
|
||||
private GitTestBranch(String name, String hash) {
|
||||
myName = name;
|
||||
myHash = hash;
|
||||
myName = name.trim();
|
||||
myHash = hash.trim();
|
||||
}
|
||||
|
||||
String getName() {
|
||||
|
||||
@@ -75,7 +75,9 @@ public class GradleTaskManager extends AbstractProjectComponent implements Gradl
|
||||
}
|
||||
finally {
|
||||
myAlarm.cancelAllRequests();
|
||||
myAlarm.addRequest(this, DETECT_HANGED_TASKS_FREQUENCY_MILLIS);
|
||||
if (!myProject.isDisposed()) {
|
||||
myAlarm.addRequest(this, DETECT_HANGED_TASKS_FREQUENCY_MILLIS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, DETECT_HANGED_TASKS_FREQUENCY_MILLIS);
|
||||
@@ -84,6 +86,7 @@ public class GradleTaskManager extends AbstractProjectComponent implements Gradl
|
||||
@Override
|
||||
public void disposeComponent() {
|
||||
myProgressNotificationManager.removeNotificationListener(this);
|
||||
myAlarm.cancelAllRequests();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
This inspection reports usages of deprecated code in Groovy
|
||||
</body>
|
||||
</html>
|
||||
@@ -599,6 +599,9 @@
|
||||
<localInspection language="Groovy" groupPath="Groovy" shortName="ClashingGetters" bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
|
||||
key="clashing.getters" groupName="Potentially confusing code constructs" enabledByDefault="false" level="WARNING"
|
||||
implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.ClashingGettersInspection"/>
|
||||
<localInspection language="Groovy" groupPath="Groovy" shortName="GrDeprecatedAPIUsage" bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
|
||||
key="gr.deprecated.api.usage" groupName="Potentially confusing code constructs" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GrDeprecatedAPIUsageInspection"/>
|
||||
<localInspection language="Groovy" groupPath="Groovy" shortName="GroovyNestedConditional" displayName="Nested conditional expression"
|
||||
groupName="Potentially confusing code constructs" enabledByDefault="false" level="WARNING"
|
||||
implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyNestedConditionalInspection"/>
|
||||
|
||||
@@ -304,3 +304,4 @@ primitive.bound.types.are.not.allowed=Primitive bound types are not allowed
|
||||
ellipsis.type.is.not.allowed.here=Ellipsis type is not allowed here
|
||||
method.0.is.too.complex.too.analyze=Method ''{0}'' is too complex to analyze.\nTypes of local variables are not inferred.
|
||||
closure.is.too.complex.to.analyze=Closure is complex to analyze.\nTypes of local variables are not inferred.
|
||||
0.is.deprecated=''{0}'' is deprecated
|
||||
|
||||
+1
@@ -83,3 +83,4 @@ unused.0=Unused {0}
|
||||
remove.0=Remove {0}
|
||||
replace.postfix.0.with.prefix.0=Replace postfix {0} with prefix {0}
|
||||
replace.0.with.1=Replace {0} with binary {1}
|
||||
gr.deprecated.api.usage=Deprecated API inspection
|
||||
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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 org.jetbrains.plugins.groovy.codeInspection.confusing;
|
||||
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.psi.PsiDocCommentOwner;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiModifierListOwner;
|
||||
import com.intellij.psi.impl.PsiImplUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.GroovyBundle;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.BaseInspection;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public class GrDeprecatedAPIUsageInspection extends BaseInspection {
|
||||
@Override
|
||||
public boolean isEnabledByDefault() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
public String getGroupDisplayName() {
|
||||
return CONFUSING_CODE_CONSTRUCTS;
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
public String getDisplayName() {
|
||||
return GroovyInspectionBundle.message("gr.deprecated.api.usage");
|
||||
}
|
||||
|
||||
@NonNls
|
||||
@NotNull
|
||||
public String getShortName() {
|
||||
return "GrDeprecatedAPIUsage";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BaseInspectionVisitor buildVisitor() {
|
||||
return new BaseInspectionVisitor() {
|
||||
@Override
|
||||
public void visitReferenceExpression(GrReferenceExpression ref) {
|
||||
super.visitReferenceExpression(ref);
|
||||
checkRef(ref);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCodeReferenceElement(GrCodeReferenceElement ref) {
|
||||
super.visitCodeReferenceElement(ref);
|
||||
checkRef(ref);
|
||||
}
|
||||
|
||||
private void checkRef(GrReferenceElement ref) {
|
||||
PsiElement resolved = ref.resolve();
|
||||
if (isDeprecated(resolved)) {
|
||||
PsiElement toHighlight = getElementToHighlight(ref);
|
||||
registerError(toHighlight, GroovyBundle.message("0.is.deprecated", ref.getReferenceName()), LocalQuickFix.EMPTY_ARRAY,
|
||||
ProblemHighlightType.LIKE_DEPRECATED);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiElement getElementToHighlight(@NotNull GrReferenceElement refElement) {
|
||||
final PsiElement refNameElement = refElement.getReferenceNameElement();
|
||||
return refNameElement != null ? refNameElement : refElement;
|
||||
}
|
||||
|
||||
|
||||
private boolean isDeprecated(PsiElement resolved) {
|
||||
if (resolved instanceof PsiDocCommentOwner && PsiImplUtil.isDeprecatedByDocTag((PsiDocCommentOwner)resolved)) {
|
||||
return true;
|
||||
}
|
||||
if (resolved instanceof PsiModifierListOwner && PsiImplUtil.isDeprecatedByAnnotation((PsiModifierListOwner)resolved)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+14
-8
@@ -21,6 +21,8 @@ import com.intellij.codeInsight.CodeInsightSettings;
|
||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
|
||||
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
|
||||
import com.intellij.codeInsight.daemon.impl.*;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.SafeDeleteFix;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInspection.InspectionProfile;
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
@@ -122,20 +124,24 @@ public class GroovyPostHighlightingPass extends TextEditorHighlightingPass {
|
||||
if (nameId.getNode().getElementType() == GroovyTokenTypes.mIDENT) {
|
||||
String name = ((GrNamedElement)element).getName();
|
||||
if (element instanceof GrTypeDefinition && !PostHighlightingPass.isClassUsed((GrTypeDefinition)element, progress, usageHelper)) {
|
||||
unusedDeclarations.add(
|
||||
PostHighlightingPass.createUnusedSymbolInfo(nameId, "Class " + name + " is unused", HighlightInfoType.UNUSED_SYMBOL));
|
||||
HighlightInfo highlightInfo = PostHighlightingPass.createUnusedSymbolInfo(nameId, "Class " + name + " is unused", HighlightInfoType.UNUSED_SYMBOL);
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, new SafeDeleteFix(element));
|
||||
unusedDeclarations.add(highlightInfo);
|
||||
}
|
||||
else if (element instanceof GrMethod) {
|
||||
GrMethod method = (GrMethod)element;
|
||||
if (!GroovyCompletionUtil.OPERATOR_METHOD_NAMES.contains(method.getName()) &&
|
||||
!PostHighlightingPass.isMethodReferenced(method, progress, usageHelper)) {
|
||||
unusedDeclarations.add(
|
||||
PostHighlightingPass.createUnusedSymbolInfo(nameId, (method.isConstructor() ? "Constructor" : "Method") +" " + name + " is unused", HighlightInfoType.UNUSED_SYMBOL));
|
||||
if (!GroovyCompletionUtil.OPERATOR_METHOD_NAMES.contains(method.getName()) && !PostHighlightingPass.isMethodReferenced(method, progress, usageHelper)) {
|
||||
String message = (method.isConstructor() ? "Constructor" : "Method") + " " + name + " is unused";
|
||||
HighlightInfo highlightInfo = PostHighlightingPass.createUnusedSymbolInfo(nameId, message, HighlightInfoType.UNUSED_SYMBOL);
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, new SafeDeleteFix(method));
|
||||
unusedDeclarations.add(highlightInfo);
|
||||
}
|
||||
}
|
||||
else if (element instanceof GrField && PostHighlightingPass.isFieldUnused((GrField)element, progress, usageHelper)) {
|
||||
unusedDeclarations.add(
|
||||
PostHighlightingPass.createUnusedSymbolInfo(nameId, "Property " + name + " is unused", HighlightInfoType.UNUSED_SYMBOL));
|
||||
HighlightInfo highlightInfo =
|
||||
PostHighlightingPass.createUnusedSymbolInfo(nameId, "Property " + name + " is unused", HighlightInfoType.UNUSED_SYMBOL);
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, new SafeDeleteFix(element));
|
||||
unusedDeclarations.add(highlightInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-2
@@ -294,8 +294,10 @@ public class GroovyCodeFragmentFactory extends CodeFragmentFactory {
|
||||
PsiElement parent = context;
|
||||
while (parent != null) {
|
||||
if (parent instanceof PsiModifierListOwner && ((PsiModifierListOwner)parent).hasModifierProperty(PsiModifier.STATIC)) return true;
|
||||
if (parent instanceof GrTypeDefinition || parent instanceof GroovyFile) return false;
|
||||
parent = parent.getParent();
|
||||
if (parent instanceof GroovyFile && parent.isPhysical()) return false;
|
||||
if (parent instanceof GrTypeDefinition) return false;
|
||||
|
||||
parent = parent.getContext();
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
+5
-2
@@ -18,7 +18,10 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -65,7 +68,7 @@ public class GppExpectedTypesContributor extends GroovyExpectedTypesContributor
|
||||
final PsiElement method = resolveResult.getElement();
|
||||
if (method instanceof PsiMethod && ((PsiMethod)method).isConstructor()) {
|
||||
final Map<GrExpression,Pair<PsiParameter,PsiType>> map = GrClosureSignatureUtil
|
||||
.mapArgumentsToParameters(resolveResult, list, false, GrNamedArgument.EMPTY_ARRAY, args, GrClosableBlock.EMPTY_ARRAY);
|
||||
.mapArgumentsToParameters(resolveResult, list, false, true, GrNamedArgument.EMPTY_ARRAY, args, GrClosableBlock.EMPTY_ARRAY);
|
||||
if (map != null) {
|
||||
final Pair<PsiParameter, PsiType> pair = map.get(arg);
|
||||
if (pair != null) {
|
||||
|
||||
+6
-12
@@ -47,22 +47,16 @@ import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeConstraint;
|
||||
*/
|
||||
public class IntentionUtils {
|
||||
|
||||
public static void replaceExpression(@NotNull String newExpression,
|
||||
@NotNull GrExpression expression)
|
||||
throws IncorrectOperationException {
|
||||
public static void replaceExpression(@NotNull String newExpression, @NotNull GrExpression expression) throws IncorrectOperationException {
|
||||
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(expression.getProject());
|
||||
final GrExpression newCall =
|
||||
factory.createExpressionFromText(newExpression);
|
||||
final PsiElement insertedElement = expression.replaceWithExpression(newCall, true);
|
||||
final GrExpression newCall = factory.createExpressionFromText(newExpression);
|
||||
expression.replaceWithExpression(newCall, true);
|
||||
}
|
||||
|
||||
public static GrStatement replaceStatement(
|
||||
@NonNls @NotNull String newStatement,
|
||||
@NonNls @NotNull GrStatement statement)
|
||||
throws IncorrectOperationException {
|
||||
public static GrStatement replaceStatement(@NonNls @NotNull String newStatement, @NonNls @NotNull GrStatement statement)
|
||||
throws IncorrectOperationException {
|
||||
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(statement.getProject());
|
||||
final GrStatement newCall =
|
||||
(GrStatement) factory.createTopElementFromText(newStatement);
|
||||
final GrStatement newCall = (GrStatement)factory.createTopElementFromText(newStatement);
|
||||
return statement.replaceWithStatement(newCall);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -196,7 +196,7 @@ public class ConvertMapToClassIntention extends Intention {
|
||||
|
||||
GrClosableBlock[] closures = methodCall.getClosureArguments();
|
||||
final Map<GrExpression, Pair<PsiParameter, PsiType>> mapToParams = GrClosureSignatureUtil
|
||||
.mapArgumentsToParameters(resolveResult, arg, false, argList.getNamedArguments(), argList.getExpressionArguments(), closures);
|
||||
.mapArgumentsToParameters(resolveResult, arg, false, false, argList.getNamedArguments(), argList.getExpressionArguments(), closures);
|
||||
if (mapToParams == null) return null;
|
||||
|
||||
final Pair<PsiParameter, PsiType> parameterPair = mapToParams.get(arg);
|
||||
|
||||
+84
-55
@@ -16,25 +16,26 @@
|
||||
|
||||
package org.jetbrains.plugins.groovy.intentions.style;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.intentions.base.Intention;
|
||||
import org.jetbrains.plugins.groovy.intentions.base.IntentionUtils;
|
||||
import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
import org.jetbrains.plugins.groovy.refactoring.GroovyNamesUtil;
|
||||
|
||||
import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils.*;
|
||||
|
||||
@@ -42,6 +43,8 @@ import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils.*;
|
||||
* @author ilyas
|
||||
*/
|
||||
public class JavaStylePropertiesInvocationIntention extends Intention {
|
||||
private static final Logger LOG = Logger.getInstance(JavaStylePropertiesInvocationIntention.class);
|
||||
|
||||
@Override
|
||||
protected boolean isStopElement(PsiElement element) {
|
||||
return super.isStopElement(element) || element instanceof GrClosableBlock;
|
||||
@@ -51,35 +54,35 @@ public class JavaStylePropertiesInvocationIntention extends Intention {
|
||||
assert element instanceof GrMethodCall;
|
||||
GrMethodCall call = ((GrMethodCall)element);
|
||||
GrExpression invoked = call.getInvokedExpression();
|
||||
String accessorName = ((GrReferenceExpression)invoked).getName();
|
||||
if (isGetterInvocation(call) && invoked instanceof GrReferenceExpression) {
|
||||
String name = ((GrReferenceExpression)invoked).getName();
|
||||
assert name != null;
|
||||
name = StringUtil.trimStart(name, GET_PREFIX);
|
||||
name = StringUtil.decapitalize(name);
|
||||
replaceWithGetter(call, name);
|
||||
final GrExpression newCall = genRefForGetter(call, accessorName);
|
||||
call.replaceWithExpression(newCall, true);
|
||||
}
|
||||
else if (isSetterInvocation(call) && invoked instanceof GrReferenceExpression) {
|
||||
String name = ((GrReferenceExpression)invoked).getName();
|
||||
assert name != null;
|
||||
name = StringUtil.trimStart(name, SET_PREFIX);
|
||||
name = StringUtil.decapitalize(name);
|
||||
GrExpression value = call.getExpressionArguments()[0];
|
||||
replaceWithSetter(call, name, value);
|
||||
final GrStatement newCall = genRefForSetter(call, accessorName);
|
||||
call.replaceWithStatement(newCall);
|
||||
}
|
||||
}
|
||||
|
||||
private static void replaceWithSetter(GrMethodCall call, String name, GrExpression value) throws IncorrectOperationException {
|
||||
GrReferenceExpression refExpr = (GrReferenceExpression) call.getInvokedExpression();
|
||||
private static GrAssignmentExpression genRefForSetter(GrMethodCall call, String accessorName) {
|
||||
String name = getPropertyNameBySetterName(accessorName);
|
||||
GrExpression value = call.getExpressionArguments()[0];
|
||||
GrReferenceExpression refExpr = (GrReferenceExpression)call.getInvokedExpression();
|
||||
String oldNameStr = refExpr.getReferenceNameElement().getText();
|
||||
String newRefExpr = StringUtil.trimEnd(refExpr.getText(), oldNameStr) + name;
|
||||
IntentionUtils.replaceStatement(newRefExpr + " = " + value.getText(), call);
|
||||
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(call.getProject());
|
||||
return (GrAssignmentExpression)factory.createStatementFromText(newRefExpr + " = " + value.getText(), call);
|
||||
}
|
||||
|
||||
private static void replaceWithGetter(GrMethodCall call, String name) throws IncorrectOperationException {
|
||||
GrReferenceExpression refExpr = (GrReferenceExpression) call.getInvokedExpression();
|
||||
private static GrExpression genRefForGetter(GrMethodCall call, String accessorName) {
|
||||
String name = getPropertyNameByGetterName(accessorName, true);
|
||||
GrReferenceExpression refExpr = (GrReferenceExpression)call.getInvokedExpression();
|
||||
String oldNameStr = refExpr.getReferenceNameElement().getText();
|
||||
String newRefExpr = StringUtil.trimEnd(refExpr.getText(), oldNameStr) + name;
|
||||
IntentionUtils.replaceExpression(newRefExpr, call);
|
||||
|
||||
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(call.getProject());
|
||||
return factory.createExpressionFromText(newRefExpr, call);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -100,60 +103,86 @@ public class JavaStylePropertiesInvocationIntention extends Intention {
|
||||
GrExpression expr = call.getInvokedExpression();
|
||||
|
||||
if (!(expr instanceof GrReferenceExpression)) return false;
|
||||
GrReferenceExpression refExpr = (GrReferenceExpression)expr;
|
||||
|
||||
GrReferenceExpression refExpr = (GrReferenceExpression) expr;
|
||||
String name = refExpr.getName();
|
||||
if (name == null || !name.startsWith(SET_PREFIX)) return false;
|
||||
|
||||
name = name.substring(SET_PREFIX.length());
|
||||
String propName = StringUtil.decapitalize(name);
|
||||
if (propName.length() == 0 || name.equals(propName)) return false;
|
||||
|
||||
PsiMethod method;
|
||||
if (call instanceof GrApplicationStatement) {
|
||||
PsiElement element = refExpr.resolve();
|
||||
if (!(element instanceof PsiMethod) || !GroovyPropertyUtils.isSimplePropertySetter(((PsiMethod)element))) return false;
|
||||
} else {
|
||||
PsiMethod method = call.resolveMethod();
|
||||
if (!GroovyPropertyUtils.isSimplePropertySetter(method)) return false;
|
||||
if (!(element instanceof PsiMethod) || !isSimplePropertySetter(((PsiMethod)element))) return false;
|
||||
method = (PsiMethod)element;
|
||||
}
|
||||
else {
|
||||
method = call.resolveMethod();
|
||||
if (!isSimplePropertySetter(method)) return false;
|
||||
}
|
||||
|
||||
if (call instanceof GrMethodCallExpression) {
|
||||
GrArgumentList args = call.getArgumentList();
|
||||
return args != null &&
|
||||
args.getExpressionArguments().length == 1 &&
|
||||
args.getNamedArguments().length == 0;
|
||||
if (!GroovyNamesUtil.isValidReference(getPropertyNameByGetterName(method.getName(), true),
|
||||
((GrReferenceExpression)expr).getQualifier() != null,
|
||||
call.getProject())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GrArgumentList args = call.getArgumentList();
|
||||
return args != null &&
|
||||
args.getExpressionArguments().length == 1 &&
|
||||
args.getNamedArguments().length == 0;
|
||||
if (args == null || args.getExpressionArguments().length != 1 || args.getNamedArguments().length > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GrAssignmentExpression assignment = genRefForSetter(call, refExpr.getName());
|
||||
GrExpression value = assignment.getLValue();
|
||||
if (value instanceof GrReferenceExpression &&
|
||||
call.getManager().areElementsEquivalent(((GrReferenceExpression)value).resolve(), method)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isGetterInvocation(GrMethodCall call) {
|
||||
GrExpression expr = call.getInvokedExpression();
|
||||
if (!(expr instanceof GrReferenceExpression)) return false;
|
||||
|
||||
GrReferenceExpression refExpr = (GrReferenceExpression) expr;
|
||||
String name = refExpr.getName();
|
||||
if (name == null || !name.startsWith(GET_PREFIX)) return false;
|
||||
|
||||
name = name.substring(GET_PREFIX.length());
|
||||
String propName = StringUtil.decapitalize(name);
|
||||
if (propName.length() == 0 || name.equals(propName)) return false;
|
||||
|
||||
PsiMethod method = call.resolveMethod();
|
||||
if (!GroovyPropertyUtils.isSimplePropertyGetter(method)) return false;
|
||||
if (!isSimplePropertyGetter(method)) return false;
|
||||
|
||||
if (!GroovyNamesUtil.isValidReference(getPropertyNameByGetterName(method.getName(), true),
|
||||
((GrReferenceExpression)expr).getQualifier() != null,
|
||||
call.getProject())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GrArgumentList args = call.getArgumentList();
|
||||
return args != null && args.getExpressionArguments().length == 0;
|
||||
if (args == null || args.getAllArguments().length != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GrExpression ref = genRefForGetter(call, ((GrReferenceExpression)expr).getName());
|
||||
if (ref instanceof GrReferenceExpression) {
|
||||
PsiElement resolved = ((GrReferenceExpression)ref).resolve();
|
||||
PsiManager manager = call.getManager();
|
||||
if (manager.areElementsEquivalent(resolved, method) || areEquivalentAccessors(method, resolved, manager)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean areEquivalentAccessors(PsiMethod method, PsiElement resolved, PsiManager manager) {
|
||||
if (!(resolved instanceof GrAccessorMethod) || !(method instanceof GrAccessorMethod)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (((GrAccessorMethod)resolved).isSetter() != ((GrAccessorMethod)method).isSetter()) return false;
|
||||
|
||||
GrField p1 = ((GrAccessorMethod)resolved).getProperty();
|
||||
GrField p2 = ((GrAccessorMethod)method).getProperty();
|
||||
return manager.areElementsEquivalent(p1, p2);
|
||||
}
|
||||
|
||||
private static class JavaPropertyInvocationPredicate implements PsiElementPredicate {
|
||||
public boolean satisfiedBy(PsiElement element) {
|
||||
if (!(element instanceof GrMethodCall)) return false;
|
||||
return isPropertyAccessor((GrMethodCall) element);
|
||||
return isPropertyAccessor((GrMethodCall)element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -280,7 +280,7 @@ public class GroovySmartCompletionContributor extends CompletionContributor {
|
||||
final PsiClass psiClass = com.intellij.psi.util.PsiUtil.resolveClassInType(type);
|
||||
if (psiClass == null) return null;
|
||||
|
||||
if (psiClass.isInterface() || psiClass.hasModifierProperty(PsiModifier.ABSTRACT)) return null;
|
||||
//if (psiClass.isInterface() || psiClass.hasModifierProperty(PsiModifier.ABSTRACT)) return null;
|
||||
if (!checkForInnerClass(psiClass, place)) return null;
|
||||
|
||||
final LookupItem item = PsiTypeLookupItem.createLookupItem(JavaCompletionUtil.eliminateWildcards(type), place);
|
||||
|
||||
+38
-4
@@ -17,15 +17,19 @@
|
||||
package org.jetbrains.plugins.groovy.lang.completion.handlers;
|
||||
|
||||
import com.intellij.codeInsight.AutoPopupController;
|
||||
import com.intellij.codeInsight.completion.ConstructorInsertHandler;
|
||||
import com.intellij.codeInsight.completion.InsertHandler;
|
||||
import com.intellij.codeInsight.completion.InsertionContext;
|
||||
import com.intellij.codeInsight.completion.JavaCompletionFeatures;
|
||||
import com.intellij.codeInsight.completion.util.ParenthesesInsertHandler;
|
||||
import com.intellij.codeInsight.lookup.LookupItem;
|
||||
import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiClassType;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.completion.GroovyCompletionUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
|
||||
@@ -33,6 +37,8 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
* @author Maxim.Medvedev
|
||||
*/
|
||||
public class AfterNewClassInsertHandler implements InsertHandler<LookupItem<PsiClassType>> {
|
||||
private static final Logger LOG = Logger.getInstance(AfterNewClassInsertHandler.class);
|
||||
|
||||
private final PsiClassType myClassType;
|
||||
private final boolean myTriggerFeature;
|
||||
|
||||
@@ -41,14 +47,15 @@ public class AfterNewClassInsertHandler implements InsertHandler<LookupItem<PsiC
|
||||
myTriggerFeature = triggerFeature;
|
||||
}
|
||||
|
||||
public void handleInsert(InsertionContext context, LookupItem<PsiClassType> item) {
|
||||
public void handleInsert(final InsertionContext context, LookupItem<PsiClassType> item) {
|
||||
final PsiClassType.ClassResolveResult resolveResult = myClassType.resolveGenerics();
|
||||
final PsiClass psiClass = resolveResult.getElement();
|
||||
if (psiClass == null || !psiClass.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
GroovyPsiElement place = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), GroovyPsiElement.class, false);
|
||||
GroovyPsiElement place =
|
||||
PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), GroovyPsiElement.class, false);
|
||||
boolean hasParams = place != null && GroovyCompletionUtil.hasConstructorParameters(psiClass, place);
|
||||
if (myTriggerFeature) {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed(JavaCompletionFeatures.AFTER_NEW);
|
||||
@@ -60,9 +67,36 @@ public class AfterNewClassInsertHandler implements InsertHandler<LookupItem<PsiC
|
||||
else {
|
||||
ParenthesesInsertHandler.NO_PARAMETERS.handleInsert(context, item);
|
||||
}
|
||||
|
||||
GroovyCompletionUtil.addImportForItem(context.getFile(), context.getStartOffset(), item);
|
||||
if (hasParams) {
|
||||
AutoPopupController.getInstance(context.getProject()).autoPopupParameterInfo(context.getEditor(), null);
|
||||
}
|
||||
|
||||
if (psiClass.hasModifierProperty(PsiModifier.ABSTRACT)) {
|
||||
final Editor editor = context.getEditor();
|
||||
final int offset = context.getTailOffset();
|
||||
editor.getDocument().insertString(offset, " {}");
|
||||
editor.getCaretModel().moveToOffset(offset + 2);
|
||||
|
||||
context.setLaterRunnable(generateAnonymousBody(editor, context.getFile()));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Runnable generateAnonymousBody(final Editor editor, final PsiFile file) {
|
||||
final Project project = file.getProject();
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments();
|
||||
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
PsiElement element = file.findElementAt(offset);
|
||||
if (element == null) return null;
|
||||
|
||||
PsiElement parent = element.getParent().getParent();
|
||||
if (!(parent instanceof PsiAnonymousClass)) return null;
|
||||
|
||||
return ConstructorInsertHandler.genAnonymousBodyFor((PsiAnonymousClass)parent, editor, file, project);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -173,7 +173,7 @@ public class GroovyExpectedTypesProvider {
|
||||
final GrNamedArgument[] namedArgs = argumentList == null ? GrNamedArgument.EMPTY_ARRAY : argumentList.getNamedArguments();
|
||||
final GrExpression[] expressionArgs = argumentList == null ? GrExpression.EMPTY_ARRAY : argumentList.getExpressionArguments();
|
||||
addConstraintsFromMap(constraints,
|
||||
GrClosureSignatureUtil.mapArgumentsToParameters(variant, methodCall, true, namedArgs, expressionArgs,
|
||||
GrClosureSignatureUtil.mapArgumentsToParameters(variant, methodCall, true, true, namedArgs, expressionArgs,
|
||||
closureArgs),
|
||||
closureIndex == closureArgs.length - 1);
|
||||
}
|
||||
@@ -238,7 +238,7 @@ public class GroovyExpectedTypesProvider {
|
||||
for (GroovyResolveResult variant : ResolveUtil.getCallVariants(list)) {
|
||||
final GrExpression[] arguments = list.getExpressionArguments();
|
||||
addConstraintsFromMap(constraints,
|
||||
GrClosureSignatureUtil.mapArgumentsToParameters(variant, list, true,
|
||||
GrClosureSignatureUtil.mapArgumentsToParameters(variant, list, true, true,
|
||||
list.getNamedArguments(),
|
||||
list.getExpressionArguments(),
|
||||
GrClosableBlock.EMPTY_ARRAY
|
||||
|
||||
+4
-4
@@ -123,7 +123,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
|
||||
public GrReferenceExpression createReferenceExpressionFromText(String idText) {
|
||||
PsiFile file = createGroovyFile(idText);
|
||||
final GrTopStatement[] statements = ((GroovyFileBase)file).getTopStatements();
|
||||
LOG.assertTrue(statements.length == 1 && statements[0] instanceof GrReferenceExpression, idText);
|
||||
if (!(statements.length == 1 && statements[0] instanceof GrReferenceExpression)) throw new IncorrectOperationException(idText);
|
||||
return (GrReferenceExpression) statements[0];
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
|
||||
}
|
||||
|
||||
public GrClosableBlock createClosureFromText(String closureText, PsiElement context) throws IncorrectOperationException {
|
||||
GroovyFile psiFile = createGroovyFile("def foo = " + closureText, false, context);
|
||||
GroovyFile psiFile = createGroovyFile("def __hdsjfghk_sdhjfshglk_foo = " + closureText, false, context);
|
||||
final GrStatement st = psiFile.getStatements()[0];
|
||||
LOG.assertTrue(st instanceof GrVariableDeclaration, closureText);
|
||||
final GrExpression initializer = ((GrVariableDeclaration)st).getVariables()[0].getInitializerGroovy();
|
||||
@@ -282,7 +282,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
|
||||
public GrParameter createParameter(String name, @Nullable String typeText, @Nullable String initializer, @Nullable GroovyPsiElement context)
|
||||
throws IncorrectOperationException {
|
||||
StringBuilder fileText = new StringBuilder();
|
||||
fileText.append("def foo(");
|
||||
fileText.append("def dsfsadfnbhfjks_weyripouh_huihnrecuio(");
|
||||
if (typeText != null) {
|
||||
fileText.append(typeText).append(" ");
|
||||
} else {
|
||||
@@ -433,7 +433,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
|
||||
@NotNull
|
||||
@Override
|
||||
public GrAnnotation createAnnotationFromText(@NotNull @NonNls String annotationText, @Nullable PsiElement context) throws IncorrectOperationException {
|
||||
return createMethodFromText(annotationText + " void foo() {}", context).getModifierList().getAnnotations()[0];
|
||||
return createMethodFromText(annotationText + " void ___shdjklf_pqweirupncp_foo() {}", context).getModifierList().getAnnotations()[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+53
-27
@@ -47,13 +47,14 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUt
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.params.GrParameterListImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.ClosureSyntheticParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightVariable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.MethodTypeInferencer;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.PropertyResolverProcessor;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor;
|
||||
import org.jetbrains.plugins.groovy.refactoring.GroovyNamesUtil;
|
||||
|
||||
import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames.GROOVY_LANG_CLOSURE;
|
||||
|
||||
/**
|
||||
* @author ilyas
|
||||
*/
|
||||
@@ -82,24 +83,50 @@ public class GrClosableBlockImpl extends GrBlockImpl implements GrClosableBlock
|
||||
if (lastParent == null) return true;
|
||||
|
||||
ResolveState state = _state.put(ResolverProcessor.RESOLVE_CONTEXT, this);
|
||||
if (!super.processDeclarations(processor, state, lastParent, place)) return false;
|
||||
if (!super.processDeclarations(processor, _state, lastParent, place)) return false;
|
||||
if (!processParameters(processor, _state, state, place)) return false;
|
||||
if (!processOwner(processor, state)) return false;
|
||||
if (!processClosureClassMembers(processor, state, lastParent, place)) return false;
|
||||
|
||||
PsiElement current = place;
|
||||
boolean it_already_processed = false;
|
||||
while (current != this && current != null) {
|
||||
if (current instanceof GrClosableBlock && !((GrClosableBlock)current).hasParametersSection() && !(current.getParent() instanceof GrStringInjection)) {
|
||||
it_already_processed = true;
|
||||
break;
|
||||
}
|
||||
current = current.getParent();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!it_already_processed || hasParametersSection()) {
|
||||
for (final PsiParameter parameter : getAllParameters()) {
|
||||
if (!ResolveUtil.processElement(processor, parameter, state)) return false;
|
||||
private boolean processClosureClassMembers(PsiScopeProcessor processor,
|
||||
ResolveState state, PsiElement lastParent,
|
||||
PsiElement place) {
|
||||
final PsiClass closureClass = GroovyPsiManager.getInstance(getProject()).findClassWithCache(GROOVY_LANG_CLOSURE, getResolveScope());
|
||||
if (closureClass != null) {
|
||||
if (!closureClass.processDeclarations(processor, state, lastParent, place)) return false;
|
||||
|
||||
if (place instanceof GroovyPsiElement) {
|
||||
GrClosureType closureType = GrClosureType.create(this, false /*if it is 'true' need-to-prevent-recursion triggers*/);
|
||||
if (!ResolveUtil.processNonCodeMembers(closureType, processor, (GroovyPsiElement)place, state)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean processParameters(PsiScopeProcessor processor,
|
||||
ResolveState _state,
|
||||
ResolveState state,
|
||||
PsiElement place) {
|
||||
if (hasParametersSection()) {
|
||||
for (GrParameter parameter : getParameters()) {
|
||||
if (!ResolveUtil.processElement(processor, parameter, _state)) return false;
|
||||
}
|
||||
}
|
||||
else if (!isItAlreadyDeclared(place)) {
|
||||
GrParameter[] synth = getSyntheticItParameter();
|
||||
if (synth.length > 0) {
|
||||
if (!ResolveUtil.processElement(processor, synth[0], state)) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean processOwner(PsiScopeProcessor processor, ResolveState state) {
|
||||
if (processor instanceof PropertyResolverProcessor && OWNER_NAME.equals(((PropertyResolverProcessor)processor).getName())) {
|
||||
processor.handleEvent(ResolveUtil.DECLARATION_SCOPE_PASSED, this);
|
||||
}
|
||||
@@ -108,22 +135,21 @@ public class GrClosableBlockImpl extends GrBlockImpl implements GrClosableBlock
|
||||
if (nameHint == null || nameHint.equals(OWNER_NAME)) {
|
||||
if (!processor.execute(getOwner(), state)) return false;
|
||||
}
|
||||
|
||||
final PsiClass closureClass = GroovyPsiManager.getInstance(getProject()).findClassWithCache(GroovyCommonClassNames.GROOVY_LANG_CLOSURE, getResolveScope());
|
||||
if (closureClass != null) {
|
||||
if (!closureClass.processDeclarations(processor, state, lastParent, place)) return false;
|
||||
|
||||
if (place instanceof GroovyPsiElement &&
|
||||
!ResolveUtil
|
||||
.processNonCodeMembers(GrClosureType.create(this, false /*if it is 'true' need-to-prevent-recursion triggers*/), processor,
|
||||
(GroovyPsiElement)place, state)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isItAlreadyDeclared(PsiElement place) {
|
||||
while (place != this && place != null) {
|
||||
if (place instanceof GrClosableBlock &&
|
||||
!((GrClosableBlock)place).hasParametersSection() &&
|
||||
!(place.getParent() instanceof GrStringInjection)) {
|
||||
return true;
|
||||
}
|
||||
place = place.getParent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Closable block";
|
||||
}
|
||||
|
||||
+36
-8
@@ -140,6 +140,29 @@ public class GrClosureSignatureUtil {
|
||||
};
|
||||
}
|
||||
|
||||
public static GrClosureSignature createSignatureWithErasedParameterTypes(final GrClosableBlock closure) {
|
||||
final PsiParameter[] params = closure.getParameterList().getParameters();
|
||||
final GrClosureParameter[] closureParams = new GrClosureParameter[params.length];
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
PsiParameter param = params[i];
|
||||
PsiType type = TypeConversionUtil.erasure(param.getType());
|
||||
closureParams[i] = new GrClosureParameterImpl(type, GrClosureParameterImpl.isParameterOptional(param),
|
||||
GrClosureParameterImpl.getDefaultInitializer(param));
|
||||
}
|
||||
return new GrClosureSignatureImpl(closureParams, null, GrClosureParameterImpl.isVararg(closureParams)) {
|
||||
@Override
|
||||
public PsiType getReturnType() {
|
||||
return closure.getReturnType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return closure.isValid();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static GrClosureSignature createSignature(PsiParameter[] parameters, @Nullable PsiType returnType) {
|
||||
return new GrClosureSignatureImpl(parameters, returnType);
|
||||
}
|
||||
@@ -449,6 +472,7 @@ public class GrClosureSignatureUtil {
|
||||
public static Map<GrExpression, Pair<PsiParameter, PsiType>> mapArgumentsToParameters(@NotNull GroovyResolveResult resolveResult,
|
||||
@NotNull GroovyPsiElement context,
|
||||
final boolean partial,
|
||||
final boolean eraseArgs,
|
||||
@NotNull final GrNamedArgument[] namedArgs,
|
||||
@NotNull final GrExpression[] expressionArgs,
|
||||
@NotNull GrClosableBlock[] closureArguments) {
|
||||
@@ -457,18 +481,20 @@ public class GrClosureSignatureUtil {
|
||||
final PsiElement element = resolveResult.getElement();
|
||||
final PsiSubstitutor substitutor = resolveResult.getSubstitutor();
|
||||
if (element instanceof PsiMethod) {
|
||||
signature = createSignature((PsiMethod)element, substitutor);
|
||||
signature =
|
||||
eraseArgs ? createSignatureWithErasedParameterTypes((PsiMethod)element) : createSignature((PsiMethod)element, substitutor);
|
||||
parameters = ((PsiMethod)element).getParameterList().getParameters();
|
||||
}
|
||||
else if (element instanceof GrClosableBlock) {
|
||||
signature = createSignature((GrClosableBlock)element);
|
||||
signature =
|
||||
eraseArgs ? createSignatureWithErasedParameterTypes((GrClosableBlock)element) : createSignature(((GrClosableBlock)element));
|
||||
parameters = ((GrClosableBlock)element).getAllParameters();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
|
||||
final ArgInfo<PsiElement>[] argInfos = mapParametersToArguments(signature, namedArgs, expressionArgs, context, closureArguments, partial);
|
||||
final ArgInfo<PsiElement>[] argInfos = mapParametersToArguments(signature, namedArgs, expressionArgs, context, closureArguments, partial, eraseArgs);
|
||||
if (argInfos == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -498,17 +524,17 @@ public class GrClosureSignatureUtil {
|
||||
@Nullable GrArgumentList list,
|
||||
@NotNull GroovyPsiElement context,
|
||||
@NotNull GrClosableBlock[] closureArguments) {
|
||||
return mapParametersToArguments(signature, list, context, closureArguments, false);
|
||||
return mapParametersToArguments(signature, list, context, closureArguments, false, false);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ArgInfo<PsiElement>[] mapParametersToArguments(@NotNull GrClosureSignature signature,
|
||||
@Nullable GrArgumentList list,
|
||||
@NotNull GroovyPsiElement context,
|
||||
@NotNull GrClosableBlock[] closureArguments, final boolean partial) {
|
||||
@NotNull GrClosableBlock[] closureArguments, final boolean partial, final boolean eraseArgs) {
|
||||
final GrNamedArgument[] namedArgs = list == null ? GrNamedArgument.EMPTY_ARRAY : list.getNamedArguments();
|
||||
final GrExpression[] expressionArgs = list == null ? GrExpression.EMPTY_ARRAY : list.getExpressionArguments();
|
||||
return mapParametersToArguments(signature, namedArgs, expressionArgs, context, closureArguments, partial);
|
||||
return mapParametersToArguments(signature, namedArgs, expressionArgs, context, closureArguments, partial, eraseArgs);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -517,7 +543,7 @@ public class GrClosureSignatureUtil {
|
||||
@NotNull GrExpression[] expressionArgs,
|
||||
@NotNull GroovyPsiElement context,
|
||||
@NotNull GrClosableBlock[] closureArguments,
|
||||
final boolean partial) {
|
||||
final boolean partial, boolean eraseArgs) {
|
||||
List<InnerArg> innerArgs = new ArrayList<InnerArg>();
|
||||
|
||||
boolean hasNamedArgs = namedArgs.length > 0;
|
||||
@@ -539,7 +565,9 @@ public class GrClosureSignatureUtil {
|
||||
if (expression instanceof GrNewExpression && com.intellij.psi.util.PsiUtil.resolveClassInType(type) == null) {
|
||||
type = null;
|
||||
}
|
||||
type = TypeConversionUtil.erasure(type);
|
||||
if (eraseArgs) {
|
||||
type = TypeConversionUtil.erasure(type);
|
||||
}
|
||||
innerArgs.add(new InnerArg(type, expression));
|
||||
}
|
||||
|
||||
|
||||
+16
-4
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.plugins.groovy.lang.resolve.processors;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiField;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.ResolveState;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -36,10 +37,10 @@ public class PropertyResolverProcessor extends ResolverProcessor {
|
||||
|
||||
@Override
|
||||
public boolean execute(PsiElement element, ResolveState state) {
|
||||
if (element instanceof GrReferenceExpression && ((GrReferenceExpression)element).getQualifier()!=null) {
|
||||
if (element instanceof GrReferenceExpression && ((GrReferenceExpression)element).getQualifier() != null) {
|
||||
return true;
|
||||
}
|
||||
return super.execute(element, state);
|
||||
return super.execute(element, state) || state.get(RESOLVE_CONTEXT) != null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -50,10 +51,21 @@ public class PropertyResolverProcessor extends ResolverProcessor {
|
||||
final int size = candidates.size();
|
||||
if (size == 0) return GroovyResolveResult.EMPTY_ARRAY;
|
||||
final GroovyResolveResult last = candidates.get(size - 1);
|
||||
if (last.isAccessible() && last.isStaticsOK()) return candidates.toArray(new GroovyResolveResult[candidates.size()]);
|
||||
if (isCorrectLocalVarOrParam(last)) {
|
||||
return new GroovyResolveResult[]{last};
|
||||
}
|
||||
for (GroovyResolveResult candidate : candidates) {
|
||||
if (candidate.isStaticsOK()) return new GroovyResolveResult[]{candidate};
|
||||
if (candidate.isStaticsOK()) {
|
||||
return new GroovyResolveResult[]{candidate};
|
||||
}
|
||||
}
|
||||
return candidates.toArray(new GroovyResolveResult[candidates.size()]);
|
||||
}
|
||||
|
||||
private static boolean isCorrectLocalVarOrParam(GroovyResolveResult last) {
|
||||
return !(last.getElement() instanceof PsiField) &&
|
||||
last.isAccessible() &&
|
||||
last.isStaticsOK() &&
|
||||
last.getCurrentFileResolveContext() == null;
|
||||
}
|
||||
}
|
||||
|
||||
+6
-3
@@ -30,6 +30,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.GrReferenceAdjuster;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
|
||||
@@ -133,9 +134,11 @@ public class GroovyOverrideImplementUtil {
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
if (i > 0) buffer.append(", ");
|
||||
PsiParameter parameter = parameters[i];
|
||||
final PsiType parameterType = substitutor.substitute(parameter.getType());
|
||||
buffer.append(parameterType.getCanonicalText());
|
||||
buffer.append(" ");
|
||||
if (!(parameter instanceof GrParameter && parameter.getTypeElement() == null)) {
|
||||
final PsiType parameterType = substitutor.substitute(parameter.getType());
|
||||
buffer.append(parameterType.getCanonicalText());
|
||||
buffer.append(" ");
|
||||
}
|
||||
final String paramName = parameter.getName();
|
||||
if (paramName != null) {
|
||||
buffer.append(paramName);
|
||||
|
||||
@@ -17,12 +17,13 @@
|
||||
package org.jetbrains.plugins.groovy.refactoring;
|
||||
|
||||
import com.intellij.lexer.Lexer;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyLexer;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.regex.Matcher;
|
||||
@@ -48,6 +49,18 @@ public class GroovyNamesUtil {
|
||||
return lexer.getTokenType() == null;
|
||||
}
|
||||
|
||||
public static boolean isValidReference(@Nullable String text, boolean afterDot, Project project) {
|
||||
if (text == null) return false;
|
||||
|
||||
try {
|
||||
GroovyPsiElementFactory.getInstance(project).createReferenceExpressionFromText(afterDot ? "foo." + text : text);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static ArrayList<String> camelizeString(String str) {
|
||||
ArrayList<String> res = new ArrayList<String>();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
+1
-1
@@ -83,7 +83,7 @@ public class GrMethodCallUsageInfo extends UsageInfo implements PossiblyIncorrec
|
||||
else {
|
||||
myMapToArguments = GrClosureSignatureUtil
|
||||
.mapParametersToArguments(signature, call.getNamedArguments(), call.getExpressionArguments(), call, call.getClosureArguments(),
|
||||
false);
|
||||
false, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -56,10 +56,10 @@ class ArgumentListGenerator {
|
||||
GrClosableBlock[] clArgs,
|
||||
GroovyPsiElement context) {
|
||||
GrClosureSignatureUtil.ArgInfo<PsiElement>[] argInfos =
|
||||
signature == null ? null : GrClosureSignatureUtil.mapParametersToArguments(signature, namedArgs, exprs, context, clArgs, false);
|
||||
signature == null ? null : GrClosureSignatureUtil.mapParametersToArguments(signature, namedArgs, exprs, context, clArgs, false, false);
|
||||
|
||||
if (argInfos == null && signature != null) {
|
||||
argInfos = GrClosureSignatureUtil.mapParametersToArguments(signature, namedArgs, exprs, context, clArgs, true);
|
||||
argInfos = GrClosureSignatureUtil.mapParametersToArguments(signature, namedArgs, exprs, context, clArgs, true, true);
|
||||
}
|
||||
|
||||
final PsiSubstitutor substitutor = signature == null ? PsiSubstitutor.EMPTY : signature.getSubstitutor();
|
||||
|
||||
+6
@@ -376,6 +376,12 @@ public class StubGenerator implements ClassItemGenerator {
|
||||
private static String getVariableInitializer(GrVariable variable, PsiType declaredType) {
|
||||
if (declaredType instanceof PsiPrimitiveType) {
|
||||
Object eval = GroovyConstantExpressionEvaluator.evaluate(variable.getInitializerGroovy());
|
||||
if (eval instanceof Float) {
|
||||
return eval.toString() + "f";
|
||||
}
|
||||
else if (eval instanceof Character) {
|
||||
return "'" + ((Character)eval).charValue() + "'";
|
||||
}
|
||||
if (eval instanceof Number || eval instanceof Boolean) {
|
||||
return eval.toString();
|
||||
}
|
||||
|
||||
+1
-1
@@ -397,7 +397,7 @@ public class GrIntroduceClosureParameterProcessor extends BaseRefactoringProcess
|
||||
if (signature == null) signature = GrClosureSignatureUtil.createSignature(toReplaceIn);
|
||||
|
||||
final GrClosureSignatureUtil.ArgInfo<PsiElement>[] actualArgs =
|
||||
GrClosureSignatureUtil.mapParametersToArguments(signature, argList, callExpression, callExpression.getClosureArguments(), true);
|
||||
GrClosureSignatureUtil.mapParametersToArguments(signature, argList, callExpression, callExpression.getClosureArguments(), true, true);
|
||||
|
||||
if (PsiTreeUtil.isAncestor(toReplaceIn, callExpression, false)) {
|
||||
argList.addAfter(factory.createExpressionFromText(settings.getName()), anchor);
|
||||
|
||||
+1
-1
@@ -102,7 +102,7 @@ public class GroovyIntroduceParameterMethodUsagesProcessor implements IntroduceP
|
||||
if (signature == null) signature = GrClosureSignatureUtil.createSignature(data.getMethodToSearchFor(), PsiSubstitutor.EMPTY);
|
||||
|
||||
final GrClosureSignatureUtil.ArgInfo<PsiElement>[] actualArgs =
|
||||
GrClosureSignatureUtil.mapParametersToArguments(signature, argList, callExpression, callExpression.getClosureArguments(), true);
|
||||
GrClosureSignatureUtil.mapParametersToArguments(signature, argList, callExpression, callExpression.getClosureArguments(), true, true);
|
||||
|
||||
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(data.getProject());
|
||||
|
||||
|
||||
+15
-4
@@ -36,12 +36,8 @@ public class GroovySmartCompletionTest extends GroovyCompletionTestBase {
|
||||
assertOrderedEquals(myFixture.lookupElementStrings, "Bar", "Foo");
|
||||
}
|
||||
|
||||
public void testSmartCompletionAfterNewInDeclarationWithInterface() throws Throwable { doSmartTest(); }
|
||||
|
||||
public void testCaretAfterSmartCompletionAfterNewInDeclaration() throws Throwable { doSmartTest(); }
|
||||
|
||||
public void testSmartCompletionAfterNewInDeclarationWithAbstractClass() throws Throwable { doSmartTest(); }
|
||||
|
||||
public void testSmartCompletionAfterNewInDeclarationWithArray() throws Throwable { doSmartTest(); }
|
||||
|
||||
public void testSmartCompletionAfterNewInDeclarationWithIntArray() throws Throwable { doSmartTest(); }
|
||||
@@ -128,4 +124,19 @@ throw new RuntimeException()
|
||||
void testInnerClassReferenceWithoutQualifier() {
|
||||
doSmartTest()
|
||||
}
|
||||
|
||||
void testAnonymousClassCompletion() {
|
||||
myFixture.configureByText('_a.groovy', '''\
|
||||
Runnable r = new Run<caret>
|
||||
''')
|
||||
myFixture.complete(CompletionType.SMART)
|
||||
myFixture.checkResult('''\
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
void run() {
|
||||
<caret><selection>//To change body of implemented methods use File | Settings | File Templates.</selection>
|
||||
}
|
||||
}
|
||||
''')
|
||||
}
|
||||
}
|
||||
|
||||
+19
-4
@@ -36,10 +36,6 @@ import org.jetbrains.plugins.groovy.codeInspection.GroovyUnusedDeclarationInspec
|
||||
import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection
|
||||
import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyResultOfAssignmentUsedInspection
|
||||
import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyUncheckedAssignmentOfMemberOfRawTypeInspection
|
||||
import org.jetbrains.plugins.groovy.codeInspection.confusing.ClashingGettersInspection
|
||||
import org.jetbrains.plugins.groovy.codeInspection.confusing.GrUnusedIncDecInspection
|
||||
import org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyOctalIntegerInspection
|
||||
import org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyResultOfIncrementOrDecrementUsedInspection
|
||||
import org.jetbrains.plugins.groovy.codeInspection.control.GroovyTrivialConditionalInspection
|
||||
import org.jetbrains.plugins.groovy.codeInspection.control.GroovyTrivialIfInspection
|
||||
import org.jetbrains.plugins.groovy.codeInspection.control.GroovyUnnecessaryReturnInspection
|
||||
@@ -50,6 +46,7 @@ import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.Groov
|
||||
import org.jetbrains.plugins.groovy.codeInspection.unusedDef.UnusedDefInspection
|
||||
import org.jetbrains.plugins.groovy.util.TestUtils
|
||||
import org.jetbrains.plugins.groovy.codeInspection.bugs.*
|
||||
import org.jetbrains.plugins.groovy.codeInspection.confusing.*
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -710,4 +707,22 @@ public class CorrectImplementor implements ActionListener {
|
||||
public void testReassignedHighlighting() {
|
||||
myFixture.testHighlighting(true, true, true, getTestName(false) + ".groovy");
|
||||
}
|
||||
|
||||
public void testDeprecated() {
|
||||
myFixture.configureByText('_a.groovy', '''\
|
||||
/**
|
||||
@deprecated
|
||||
*/
|
||||
class X {
|
||||
@Deprecated
|
||||
def foo(){}
|
||||
|
||||
public static void main() {
|
||||
new <warning descr="'X' is deprecated">X</warning>().<warning descr="'foo' is deprecated">foo</warning>()
|
||||
}
|
||||
}''')
|
||||
|
||||
myFixture.enableInspections(GrDeprecatedAPIUsageInspection)
|
||||
myFixture.testHighlighting(true, false, false)
|
||||
}
|
||||
}
|
||||
+16
-1
@@ -722,7 +722,7 @@ print map.cla<caret>ss''')
|
||||
public void testResolveInsideWith0() {
|
||||
def resolved = resolve('a.groovy')
|
||||
|
||||
assertInstanceOf( resolved , GrAccessorMethod)
|
||||
assertInstanceOf(resolved, GrAccessorMethod)
|
||||
assertEquals(resolved.containingClass.name, 'A')
|
||||
}
|
||||
|
||||
@@ -733,4 +733,19 @@ print map.cla<caret>ss''')
|
||||
assertEquals(resolved.containingClass.name, 'B')
|
||||
}
|
||||
|
||||
|
||||
void testLocalVarVsFieldInWithClosure() {
|
||||
def ref = configureByText('''\
|
||||
class Test {
|
||||
def var
|
||||
}
|
||||
|
||||
int var = 4
|
||||
new Test().with() {
|
||||
print v<caret>ar
|
||||
}
|
||||
''')
|
||||
assertFalse ref.resolve() instanceof GrField
|
||||
assertTrue ref.resolve() instanceof GrVariable
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -233,6 +233,10 @@ public class ChangeSignatureTest extends ChangeSignatureTestCase {
|
||||
doTest(new SimpleInfo("lucky", -1, "defValue", "defInit", String.class.getName(), true));
|
||||
}
|
||||
|
||||
public void testParamsWithGenerics() {
|
||||
doTest(new SimpleInfo(0));
|
||||
}
|
||||
|
||||
private PsiType createType(String typeText) {
|
||||
return JavaPsiFacade.getElementFactory(getProject()).createTypeByFQClassName(typeText, GlobalSearchScope.allScope(getProject()));
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
class Foo {
|
||||
static class Bar {}
|
||||
{
|
||||
List<Bar> l = new AL<caret>
|
||||
List<Bar> l = new ArrL<caret>
|
||||
}
|
||||
}
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
abstract class Foo {
|
||||
}
|
||||
class Bar extends Foo {
|
||||
}
|
||||
|
||||
abstract class Foo2 extends Foo {
|
||||
}
|
||||
|
||||
Foo f = new <caret>
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
abstract class Foo {
|
||||
}
|
||||
class Bar extends Foo {
|
||||
}
|
||||
|
||||
abstract class Foo2 extends Foo {
|
||||
}
|
||||
|
||||
Foo f = new Bar()<caret>
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
interface Foo {
|
||||
}
|
||||
class Bar implements Foo {
|
||||
}
|
||||
|
||||
Foo f = new <caret>
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
interface Foo {
|
||||
}
|
||||
class Bar implements Foo {
|
||||
}
|
||||
|
||||
Foo f = new Bar()<caret>
|
||||
@@ -0,0 +1,5 @@
|
||||
class Foo {
|
||||
def b<caret>ar (int x, List<Integer> list) {}
|
||||
}
|
||||
|
||||
new Foo().bar(1, [])
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class Foo {
|
||||
def b<caret>ar (int x) {}
|
||||
}
|
||||
|
||||
new Foo().bar(1)
|
||||
+1
-1
@@ -35,7 +35,7 @@ public class MavenAddArchetypeDialog extends DialogWrapper {
|
||||
|
||||
public MavenAddArchetypeDialog(Component parent) {
|
||||
super(parent, false);
|
||||
setTitle("Add archetype");
|
||||
setTitle("Add Archetype");
|
||||
|
||||
init();
|
||||
|
||||
|
||||
@@ -556,17 +556,22 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
|
||||
}
|
||||
|
||||
private void createPool() {
|
||||
if (myPool != null) return;
|
||||
final String property = System.getProperty(KEEP_CONNECTIONS_KEY);
|
||||
final boolean keep;
|
||||
if (StringUtil.isEmptyOrSpaces(property)) {
|
||||
keep = ! ApplicationManager.getApplication().isUnitTestMode(); // default
|
||||
keep = !ApplicationManager.getApplication().isUnitTestMode(); // default
|
||||
} else {
|
||||
keep = Boolean.getBoolean(KEEP_CONNECTIONS_KEY);
|
||||
}
|
||||
myPool = new DefaultSVNRepositoryPool(myConfiguration.getAuthenticationManager(this), myConfiguration.getOptions(myProject), 60*1000, keep);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ISVNRepositoryPool getPool() {
|
||||
if (myPool == null) {
|
||||
createPool();
|
||||
}
|
||||
return myPool;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,18 +86,22 @@ public class CopiesPanel {
|
||||
myCurrentInfoList = null;
|
||||
|
||||
final Runnable focus = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
IdeFocusManager.getInstance(myProject).requestFocus(myRefreshLabel, true);
|
||||
}
|
||||
};
|
||||
final Runnable refreshView = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final List<WCInfo> infoList = myVcs.getAllWcInfos();
|
||||
Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (myCurrentInfoList != null) {
|
||||
final List<OverrideEqualsWrapper<WCInfo>> newList =
|
||||
ObjectsConvertor.convert(infoList, new Convertor<WCInfo, OverrideEqualsWrapper<WCInfo>>() {
|
||||
@Override
|
||||
public OverrideEqualsWrapper<WCInfo> convert(WCInfo o) {
|
||||
return new OverrideEqualsWrapper<WCInfo>(InfoEqualityPolicy.getInstance(), o);
|
||||
}
|
||||
@@ -119,8 +123,14 @@ public class CopiesPanel {
|
||||
}
|
||||
};
|
||||
final Runnable refreshOnPooled = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().executeOnPooledThread(refreshView);
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
refreshView.run();
|
||||
}
|
||||
else {
|
||||
ApplicationManager.getApplication().executeOnPooledThread(refreshView);
|
||||
}
|
||||
}
|
||||
};
|
||||
myConnection.subscribe(SvnVcs.ROOTS_RELOADED, refreshOnPooled);
|
||||
@@ -133,6 +143,7 @@ public class CopiesPanel {
|
||||
panel.add(myPanel, BorderLayout.NORTH);
|
||||
holderPanel.add(panel, BorderLayout.WEST);
|
||||
myRefreshLabel = new MyLinkLabel(myTextHeight, "Refresh", new LinkListener() {
|
||||
@Override
|
||||
public void linkSelected(LinkLabel aSource, Object aLinkData) {
|
||||
if (myRefreshLabel.isEnabled()) {
|
||||
myVcs.invokeRefreshSvnRoots(true);
|
||||
@@ -280,6 +291,7 @@ public class CopiesPanel {
|
||||
|
||||
private void mergeFrom(final WCInfo wcInfo, final VirtualFile root, final Component mergeLabel) {
|
||||
SelectBranchPopup.showForBranchRoot(myProject, root, new SelectBranchPopup.BranchSelectedCallback() {
|
||||
@Override
|
||||
public void branchSelected(Project project, SvnBranchConfigurationNew configuration, String url, long revision) {
|
||||
new QuickMerge(project, url, wcInfo, SVNPathUtil.tail(url), root).execute();
|
||||
}
|
||||
@@ -393,6 +405,7 @@ public class CopiesPanel {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHashCode(WCInfo value) {
|
||||
final HashCodeBuilder builder = new HashCodeBuilder();
|
||||
builder.append(value.getPath());
|
||||
@@ -404,6 +417,7 @@ public class CopiesPanel {
|
||||
return builder.getCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEqual(WCInfo val1, WCInfo val2) {
|
||||
if (val1 == val2) return true;
|
||||
if (val1 == null || val2 == null || val1.getClass() != val2.getClass()) return false;
|
||||
@@ -425,6 +439,7 @@ public class CopiesPanel {
|
||||
return ourComparator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(WCInfo o1, WCInfo o2) {
|
||||
return o1.getPath().compareTo(o2.getPath());
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user