Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Jemerov
2012-03-26 17:48:19 +02:00
104 changed files with 1175 additions and 342 deletions
@@ -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());
}
}
@@ -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> {
@@ -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);
@@ -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());
}
@@ -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");
@@ -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(" ");
}
@@ -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());
}
@@ -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");
}
@@ -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()]);
}
};
@@ -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);
@@ -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)) {
@@ -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);
}
-1
View File
@@ -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];
}
}
}
@@ -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);
}
@@ -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;
@@ -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) ;
}
}
}
@@ -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();
@@ -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);
}
@@ -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) {
@@ -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;
}
@@ -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
@@ -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() {
@@ -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
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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);
@@ -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);
}
}
@@ -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);
}
}
@@ -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;
}
};
}
};
}
}
@@ -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();
}
};
}
};
}
}
+1 -1
View File
@@ -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>
+3
View File
@@ -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
@@ -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
@@ -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;
}
};
}
}
@@ -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);
}
}
}
@@ -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;
@@ -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) {
@@ -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);
}
@@ -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);
@@ -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);
}
}
}
@@ -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);
@@ -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);
}
}
@@ -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
@@ -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
@@ -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";
}
@@ -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));
}
@@ -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;
}
}
@@ -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();
@@ -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);
}
}
@@ -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();
@@ -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();
}
@@ -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);
@@ -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());
@@ -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>
}
}
''')
}
}
@@ -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)
}
}
@@ -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
}
}
@@ -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,6 +1,6 @@
class Foo {
static class Bar {}
{
List<Bar> l = new AL<caret>
List<Bar> l = new ArrL<caret>
}
}
@@ -1,9 +0,0 @@
abstract class Foo {
}
class Bar extends Foo {
}
abstract class Foo2 extends Foo {
}
Foo f = new <caret>
@@ -1,9 +0,0 @@
abstract class Foo {
}
class Bar extends Foo {
}
abstract class Foo2 extends Foo {
}
Foo f = new Bar()<caret>
@@ -1,6 +0,0 @@
interface Foo {
}
class Bar implements Foo {
}
Foo f = new <caret>
@@ -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, [])
@@ -0,0 +1,5 @@
class Foo {
def b<caret>ar (int x) {}
}
new Foo().bar(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